fix parameter passing bug introduced recently (byte not converted to word)

This commit is contained in:
Irmen de Jong 2023-11-02 00:31:27 +01:00
parent 16b24fadea
commit d54ab856e7
4 changed files with 146 additions and 107 deletions

View File

@ -563,7 +563,7 @@ class AsmGen6502Internal (
when(reg) { when(reg) {
RegisterOrPair.A, RegisterOrPair.A,
RegisterOrPair.X, RegisterOrPair.X,
RegisterOrPair.Y -> assignmentAsmGen.assignRegisterByte(target, reg.asCpuRegister(), target.datatype in SignedDatatypes) RegisterOrPair.Y -> assignmentAsmGen.assignRegisterByte(target, reg.asCpuRegister(), target.datatype in SignedDatatypes, true)
RegisterOrPair.AX, RegisterOrPair.AX,
RegisterOrPair.AY, RegisterOrPair.AY,
RegisterOrPair.XY, RegisterOrPair.XY,

View File

@ -110,8 +110,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
val var3name = asmgen.asmVariableName(fcall.args[3] as PtIdentifier) val var3name = asmgen.asmVariableName(fcall.args[3] as PtIdentifier)
val divisionTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[2].position, var2name) val divisionTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[2].position, var2name)
val remainderTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[3].position, var3name) val remainderTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[3].position, var3name)
assignAsmGen.assignRegisterByte(remainderTarget, CpuRegister.A, false) assignAsmGen.assignRegisterByte(remainderTarget, CpuRegister.A, false, false)
assignAsmGen.assignRegisterByte(divisionTarget, CpuRegister.Y, false) assignAsmGen.assignRegisterByte(divisionTarget, CpuRegister.Y, false, false)
} }
private fun funcDivmodW(fcall: PtBuiltinFunctionCall) { private fun funcDivmodW(fcall: PtBuiltinFunctionCall) {
@ -273,11 +273,11 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
when(fcall.args[0].type) { when(fcall.args[0].type) {
DataType.UBYTE -> { DataType.UBYTE -> {
asmgen.out(" ldy #0 | jsr prog8_lib.func_sqrt16_into_A") asmgen.out(" ldy #0 | jsr prog8_lib.func_sqrt16_into_A")
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, false) assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, false, false)
} }
DataType.UWORD -> { DataType.UWORD -> {
asmgen.out(" jsr prog8_lib.func_sqrt16_into_A") asmgen.out(" jsr prog8_lib.func_sqrt16_into_A")
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, false) assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, false, false)
} }
DataType.FLOAT -> { DataType.FLOAT -> {
asmgen.out(" jsr floats.func_sqrt_into_FAC1") asmgen.out(" jsr floats.func_sqrt_into_FAC1")
@ -686,7 +686,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
assignAsmGen.assignConstantByte(target, 0) assignAsmGen.assignConstantByte(target, 0)
} else { } else {
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.A, false) asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.A, false)
assignAsmGen.assignRegisterByte(target, CpuRegister.A, false) assignAsmGen.assignRegisterByte(target, CpuRegister.A, false, false)
} }
} }
@ -701,7 +701,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
DataType.FLOAT -> asmgen.out(" jsr floats.func_sign_f_into_A") DataType.FLOAT -> asmgen.out(" jsr floats.func_sign_f_into_A")
else -> throw AssemblyError("weird type $dt") else -> throw AssemblyError("weird type $dt")
} }
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, true) assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, true, true)
} }
private fun funcAnyAll(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?, scope: IPtSubroutine?) { private fun funcAnyAll(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?, scope: IPtSubroutine?) {
@ -714,7 +714,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
in SplitWordArrayTypes -> TODO("split word any/all") in SplitWordArrayTypes -> TODO("split word any/all")
else -> throw AssemblyError("weird type $dt") else -> throw AssemblyError("weird type $dt")
} }
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, dt in SignedDatatypes) assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, dt in SignedDatatypes, true)
} }
private fun funcAbs(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?, scope: IPtSubroutine?) { private fun funcAbs(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?, scope: IPtSubroutine?) {
@ -723,7 +723,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
when (dt) { when (dt) {
DataType.BYTE -> { DataType.BYTE -> {
asmgen.out(" jsr prog8_lib.abs_b_into_A") asmgen.out(" jsr prog8_lib.abs_b_into_A")
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A,false) assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A,false, true)
} }
DataType.WORD -> { DataType.WORD -> {
asmgen.out(" jsr prog8_lib.abs_w_into_AY") asmgen.out(" jsr prog8_lib.abs_w_into_AY")
@ -871,7 +871,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
assignAsmGen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A, signed) // value assignAsmGen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A, signed) // value
asmgen.out(" jsr prog8_lib.func_clamp_${fcall.type.toString().lowercase()}") asmgen.out(" jsr prog8_lib.func_clamp_${fcall.type.toString().lowercase()}")
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, signed, fcall.position, fcall.definingISub(), asmgen) val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, signed, fcall.position, fcall.definingISub(), asmgen)
assignAsmGen.assignRegisterByte(targetReg, CpuRegister.A, signed) assignAsmGen.assignRegisterByte(targetReg, CpuRegister.A, signed, true)
} }
in WordDatatypes -> { in WordDatatypes -> {
assignAsmGen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W1", fcall.args[1].type) // minimum assignAsmGen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W1", fcall.args[1].type) // minimum
@ -887,55 +887,59 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
private fun funcMin(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) { private fun funcMin(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
val signed = fcall.type in SignedDatatypes val signed = fcall.type in SignedDatatypes
if(fcall.type in ByteDatatypes) { when (fcall.type) {
asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_B1", fcall.type) // right in ByteDatatypes -> {
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A) // left asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_B1", fcall.type) // right
asmgen.out(" cmp P8ZP_SCRATCH_B1") asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A) // left
if(signed) asmgen.out(" bmi +") else asmgen.out(" bcc +") asmgen.out(" cmp P8ZP_SCRATCH_B1")
asmgen.out(""" if(signed) asmgen.out(" bmi +") else asmgen.out(" bcc +")
lda P8ZP_SCRATCH_B1
+""")
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, signed, fcall.position, fcall.definingISub(), asmgen)
asmgen.assignRegister(RegisterOrPair.A, targetReg)
} else if(fcall.type in WordDatatypes) {
asmgen.assignExpressionToVariable(fcall.args[0], "P8ZP_SCRATCH_W1", fcall.type) // left
asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", fcall.type) // right
if(signed) {
asmgen.out(""" asmgen.out("""
lda P8ZP_SCRATCH_W1 lda P8ZP_SCRATCH_B1
ldy P8ZP_SCRATCH_W1+1 +""")
cmp P8ZP_SCRATCH_W2 val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, signed, fcall.position, fcall.definingISub(), asmgen)
tya asmgen.assignRegister(RegisterOrPair.A, targetReg)
sbc P8ZP_SCRATCH_W2+1 }
bvc + in WordDatatypes -> {
eor #$80 asmgen.assignExpressionToVariable(fcall.args[0], "P8ZP_SCRATCH_W1", fcall.type) // left
+ bpl + asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", fcall.type) // right
lda P8ZP_SCRATCH_W1 if(signed) {
ldy P8ZP_SCRATCH_W1+1 asmgen.out("""
jmp ++ lda P8ZP_SCRATCH_W1
+ lda P8ZP_SCRATCH_W2 ldy P8ZP_SCRATCH_W1+1
ldy P8ZP_SCRATCH_W2+1 cmp P8ZP_SCRATCH_W2
+""") tya
} else { sbc P8ZP_SCRATCH_W2+1
asmgen.out(""" bvc +
lda P8ZP_SCRATCH_W1+1 eor #$80
cmp P8ZP_SCRATCH_W2+1 + bpl +
bcc ++ lda P8ZP_SCRATCH_W1
bne + ldy P8ZP_SCRATCH_W1+1
lda P8ZP_SCRATCH_W1 jmp ++
cmp P8ZP_SCRATCH_W2 + lda P8ZP_SCRATCH_W2
bcc ++ ldy P8ZP_SCRATCH_W2+1
+ lda P8ZP_SCRATCH_W2 +""")
ldy P8ZP_SCRATCH_W2+1 } else {
jmp ++ asmgen.out("""
+ lda P8ZP_SCRATCH_W1 lda P8ZP_SCRATCH_W1+1
ldy P8ZP_SCRATCH_W1+1 cmp P8ZP_SCRATCH_W2+1
+""") bcc ++
bne +
lda P8ZP_SCRATCH_W1
cmp P8ZP_SCRATCH_W2
bcc ++
+ lda P8ZP_SCRATCH_W2
ldy P8ZP_SCRATCH_W2+1
jmp ++
+ lda P8ZP_SCRATCH_W1
ldy P8ZP_SCRATCH_W1+1
+""")
}
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, signed, fcall.position, fcall.definingISub(), asmgen)
asmgen.assignRegister(RegisterOrPair.AY, targetReg)
}
else -> {
throw AssemblyError("min float not supported")
} }
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, signed, fcall.position, fcall.definingISub(), asmgen)
asmgen.assignRegister(RegisterOrPair.AY, targetReg)
} else {
throw AssemblyError("min float not supported")
} }
} }

View File

@ -84,7 +84,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" lda (P8ZP_SCRATCH_W1),y") asmgen.out(" lda (P8ZP_SCRATCH_W1),y")
} }
} }
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes) assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, false)
return return
} }
@ -109,7 +109,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
when (elementDt) { when (elementDt) {
in ByteDatatypes -> { in ByteDatatypes -> {
asmgen.out(" lda $arrayVarName+$indexValue") asmgen.out(" lda $arrayVarName+$indexValue")
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes) assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, false)
} }
in WordDatatypes -> { in WordDatatypes -> {
asmgen.out(" lda $arrayVarName+$indexValue | ldy $arrayVarName+$indexValue+1") asmgen.out(" lda $arrayVarName+$indexValue | ldy $arrayVarName+$indexValue+1")
@ -127,7 +127,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
in ByteDatatypes -> { in ByteDatatypes -> {
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y) asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
asmgen.out(" lda $arrayVarName,y") asmgen.out(" lda $arrayVarName,y")
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes) assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, true)
} }
in WordDatatypes -> { in WordDatatypes -> {
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y) asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
@ -154,7 +154,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
fun assignViaExprEval(expression: PtExpression) { fun assignViaExprEval(expression: PtExpression) {
assignExpressionToVariable(expression, "P8ZP_SCRATCH_W2", DataType.UWORD) assignExpressionToVariable(expression, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2") asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2")
assignRegisterByte(assign.target, CpuRegister.A, false) assignRegisterByte(assign.target, CpuRegister.A, false, true)
} }
val value = assign.source.memory!! val value = assign.source.memory!!
@ -169,7 +169,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
is PtBinaryExpression -> { is PtBinaryExpression -> {
val addrExpr = value.address as PtBinaryExpression val addrExpr = value.address as PtBinaryExpression
if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) { if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
assignRegisterByte(assign.target, CpuRegister.A, false) assignRegisterByte(assign.target, CpuRegister.A, false, true)
} else { } else {
assignViaExprEval(value.address) assignViaExprEval(value.address)
} }
@ -223,9 +223,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
else -> { else -> {
// do NOT restore X register before assigning the result values first // do NOT restore X register before assigning the result values first
when (returnValue.first.registerOrPair) { when (returnValue.first.registerOrPair) {
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A, returnValue.second in SignedDatatypes) RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A, returnValue.second in SignedDatatypes, true)
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X, returnValue.second in SignedDatatypes) RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X, returnValue.second in SignedDatatypes, true)
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y, returnValue.second in SignedDatatypes) RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y, returnValue.second in SignedDatatypes, true)
RegisterOrPair.AX -> assignVirtualRegister(assign.target, RegisterOrPair.AX) RegisterOrPair.AX -> assignVirtualRegister(assign.target, RegisterOrPair.AX)
RegisterOrPair.AY -> assignVirtualRegister(assign.target, RegisterOrPair.AY) RegisterOrPair.AY -> assignVirtualRegister(assign.target, RegisterOrPair.AY)
RegisterOrPair.XY -> assignVirtualRegister(assign.target, RegisterOrPair.XY) RegisterOrPair.XY -> assignVirtualRegister(assign.target, RegisterOrPair.XY)
@ -261,7 +261,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
if(assign.target.register==null) { if(assign.target.register==null) {
// still need to assign the result to the target variable/etc. // still need to assign the result to the target variable/etc.
when(returnDt) { when(returnDt) {
in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A, returnDt in SignedDatatypes) // function's byte result is in A in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A, returnDt in SignedDatatypes, false) // function's byte result is in A
in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY) // function's word result is in AY in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY) // function's word result is in AY
DataType.STR -> { DataType.STR -> {
when (assign.target.datatype) { when (assign.target.datatype) {
@ -306,7 +306,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
"not" -> throw AssemblyError("not should have been replaced in the Ast by ==0") "not" -> throw AssemblyError("not should have been replaced in the Ast by ==0")
else -> throw AssemblyError("invalid prefix operator") else -> throw AssemblyError("invalid prefix operator")
} }
assignRegisterByte(assign.target, CpuRegister.A, signed) assignRegisterByte(assign.target, CpuRegister.A, signed, false)
} else { } else {
assignExpressionToRegister(value.value, RegisterOrPair.AY, signed) assignExpressionToRegister(value.value, RegisterOrPair.AY, signed)
when(value.operator) { when(value.operator) {
@ -376,7 +376,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
is PtContainmentCheck -> { is PtContainmentCheck -> {
containmentCheckIntoA(value) containmentCheckIntoA(value)
assignRegisterByte(assign.target, CpuRegister.A, false) assignRegisterByte(assign.target, CpuRegister.A, false, true)
} }
is PtBinaryExpression -> { is PtBinaryExpression -> {
if(!attemptAssignOptimizedBinexpr(value, assign)) { if(!attemptAssignOptimizedBinexpr(value, assign)) {
@ -415,7 +415,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
when(target.datatype) { when(target.datatype) {
in ByteDatatypes -> { in ByteDatatypes -> {
asmgen.out(" lda cx16.${register.toString().lowercase()}L") asmgen.out(" lda cx16.${register.toString().lowercase()}L")
assignRegisterByte(target, CpuRegister.A, false) assignRegisterByte(target, CpuRegister.A, false, false)
} }
in WordDatatypes -> assignRegisterpairWord(target, register) in WordDatatypes -> assignRegisterpairWord(target, register)
else -> throw AssemblyError("expected byte or word") else -> throw AssemblyError("expected byte or word")
@ -493,7 +493,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
if(target.register==RegisterOrPair.A) if(target.register==RegisterOrPair.A)
asmgen.out(" cmp #0") // fix the status register asmgen.out(" cmp #0") // fix the status register
else else
assignRegisterByte(target, CpuRegister.A, false) assignRegisterByte(target, CpuRegister.A, false, true)
return true return true
} }
DataType.UWORD -> { DataType.UWORD -> {
@ -513,7 +513,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" pha") asmgen.out(" pha")
assignExpressionToRegister(expr.right, RegisterOrPair.Y, false) assignExpressionToRegister(expr.right, RegisterOrPair.Y, false)
asmgen.out(" pla | jsr math.divmod_ub_asm") asmgen.out(" pla | jsr math.divmod_ub_asm")
assignRegisterByte(target, CpuRegister.Y, false) assignRegisterByte(target, CpuRegister.Y, false, true)
return true return true
} }
DataType.BYTE -> { DataType.BYTE -> {
@ -521,7 +521,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" pha") asmgen.out(" pha")
assignExpressionToRegister(expr.right, RegisterOrPair.Y, true) assignExpressionToRegister(expr.right, RegisterOrPair.Y, true)
asmgen.out(" pla | jsr math.divmod_b_asm") asmgen.out(" pla | jsr math.divmod_b_asm")
assignRegisterByte(target, CpuRegister.Y, true) assignRegisterByte(target, CpuRegister.Y, true, true)
return true return true
} }
DataType.UWORD -> { DataType.UWORD -> {
@ -549,7 +549,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" pha") asmgen.out(" pha")
assignExpressionToRegister(expr.right, RegisterOrPair.Y, expr.type in SignedDatatypes) assignExpressionToRegister(expr.right, RegisterOrPair.Y, expr.type in SignedDatatypes)
asmgen.out(" pla | jsr math.multiply_bytes") asmgen.out(" pla | jsr math.multiply_bytes")
assignRegisterByte(target, CpuRegister.A, false) assignRegisterByte(target, CpuRegister.A, false, true)
return true return true
} }
in WordDatatypes -> { in WordDatatypes -> {
@ -587,7 +587,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" jsr math.mul_byte_${value}") asmgen.out(" jsr math.mul_byte_${value}")
else else
asmgen.out(" ldy #$value | jsr math.multiply_bytes") asmgen.out(" ldy #$value | jsr math.multiply_bytes")
assignRegisterByte(target, CpuRegister.A, false) assignRegisterByte(target, CpuRegister.A, false, true)
return true return true
} }
in WordDatatypes -> { in WordDatatypes -> {
@ -647,7 +647,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" jsr math.lsr_ubyte_A") asmgen.out(" jsr math.lsr_ubyte_A")
else else
asmgen.out(" jsr math.asl_byte_A") asmgen.out(" jsr math.asl_byte_A")
assignRegisterByte(target, CpuRegister.A, signed) assignRegisterByte(target, CpuRegister.A, signed, true)
return true return true
} else { } else {
assignExpressionToRegister(expr.left, RegisterOrPair.AY, signed) assignExpressionToRegister(expr.left, RegisterOrPair.AY, signed)
@ -682,7 +682,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
} }
} }
assignRegisterByte(target, CpuRegister.A, signed) assignRegisterByte(target, CpuRegister.A, signed, true)
return true return true
} }
else -> { else -> {
@ -691,7 +691,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} else { } else {
asmgen.out(" lda #0") asmgen.out(" lda #0")
} }
assignRegisterByte(target, CpuRegister.A, signed) assignRegisterByte(target, CpuRegister.A, signed, true)
return true return true
} }
} }
@ -764,7 +764,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" clc | adc $symname") asmgen.out(" clc | adc $symname")
else else
asmgen.out(" sec | sbc $symname") asmgen.out(" sec | sbc $symname")
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes) assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
return true return true
} }
is PtNumber -> { is PtNumber -> {
@ -773,7 +773,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" clc | adc #${right.number.toHex()}") asmgen.out(" clc | adc #${right.number.toHex()}")
else else
asmgen.out(" sec | sbc #${right.number.toHex()}") asmgen.out(" sec | sbc #${right.number.toHex()}")
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes) assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
return true return true
} }
else -> { else -> {
@ -804,7 +804,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
else else
asmgen.out(" sec | sbc $arrayvarname,y") asmgen.out(" sec | sbc $arrayvarname,y")
} }
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes) assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
} else { } else {
assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", right.type) assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", right.type)
assignExpressionToRegister(left, RegisterOrPair.A, left.type==DataType.BYTE) assignExpressionToRegister(left, RegisterOrPair.A, left.type==DataType.BYTE)
@ -812,7 +812,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" clc | adc P8ZP_SCRATCH_B1") asmgen.out(" clc | adc P8ZP_SCRATCH_B1")
else else
asmgen.out(" sec | sbc P8ZP_SCRATCH_B1") asmgen.out(" sec | sbc P8ZP_SCRATCH_B1")
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes) assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
} }
return true return true
} }
@ -1005,7 +1005,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1") "^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
else -> throw AssemblyError("invalid operator") else -> throw AssemblyError("invalid operator")
} }
assignRegisterByte(target, CpuRegister.A, false) assignRegisterByte(target, CpuRegister.A, false, true)
return true return true
} }
else if (expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) { else if (expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
@ -1044,7 +1044,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
else -> return false else -> return false
} }
assignRegisterByte(assign.target, CpuRegister.A, false) assignRegisterByte(assign.target, CpuRegister.A, false, true)
return true return true
} }
@ -1558,7 +1558,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
else -> return false else -> return false
} }
assignRegisterByte(assign.target, CpuRegister.A, signed) assignRegisterByte(assign.target, CpuRegister.A, signed, true)
return true return true
} }
@ -1575,7 +1575,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
"^", "xor" -> asmgen.out(" eor $operand") "^", "xor" -> asmgen.out(" eor $operand")
else -> throw AssemblyError("invalid operator") else -> throw AssemblyError("invalid operator")
} }
assignRegisterByte(target, CpuRegister.A, false) assignRegisterByte(target, CpuRegister.A, false, true)
} }
private fun assignLogicalWithSimpleRightOperandWord(target: AsmAssignTarget, left: PtExpression, operator: String, right: PtExpression) { private fun assignLogicalWithSimpleRightOperandWord(target: AsmAssignTarget, left: PtExpression, operator: String, right: PtExpression) {
@ -1614,7 +1614,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
beq + beq +
lda #1 lda #1
+ eor #1""") + eor #1""")
assignRegisterByte(assign.target, CpuRegister.A, false) assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true return true
} }
in WordDatatypes -> { in WordDatatypes -> {
@ -1625,13 +1625,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
beq + beq +
lda #1 lda #1
+ eor #1""") + eor #1""")
assignRegisterByte(assign.target, CpuRegister.A, false) assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true return true
} }
DataType.FLOAT -> { DataType.FLOAT -> {
assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true) assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
asmgen.out(" jsr floats.SIGN | and #1 | eor #1") asmgen.out(" jsr floats.SIGN | and #1 | eor #1")
assignRegisterByte(assign.target, CpuRegister.A, false) assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true return true
} }
else->{ else->{
@ -1645,7 +1645,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
assignExpressionToRegister(expr.left, RegisterOrPair.A, dt==DataType.BYTE) assignExpressionToRegister(expr.left, RegisterOrPair.A, dt==DataType.BYTE)
asmgen.out(" beq + | lda #1") asmgen.out(" beq + | lda #1")
asmgen.out("+") asmgen.out("+")
assignRegisterByte(assign.target, CpuRegister.A, false) assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true return true
} }
in WordDatatypes -> { in WordDatatypes -> {
@ -1653,13 +1653,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" sty P8ZP_SCRATCH_B1 | ora P8ZP_SCRATCH_B1") asmgen.out(" sty P8ZP_SCRATCH_B1 | ora P8ZP_SCRATCH_B1")
asmgen.out(" beq + | lda #1") asmgen.out(" beq + | lda #1")
asmgen.out("+") asmgen.out("+")
assignRegisterByte(assign.target, CpuRegister.A, false) assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true return true
} }
DataType.FLOAT -> { DataType.FLOAT -> {
assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true) assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
asmgen.out(" jsr floats.SIGN") asmgen.out(" jsr floats.SIGN")
assignRegisterByte(assign.target, CpuRegister.A, true) assignRegisterByte(assign.target, CpuRegister.A, true, false)
return true return true
} }
else->{ else->{
@ -1731,7 +1731,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
else -> throw AssemblyError("can't use Z or N flags as return 'values'") else -> throw AssemblyError("can't use Z or N flags as return 'values'")
} }
assignRegisterByte(target, CpuRegister.A, false) assignRegisterByte(target, CpuRegister.A, false, true)
} }
private fun assignTypeCastedValue(target: AsmAssignTarget, targetDt: DataType, value: PtExpression, origTypeCastExpression: PtTypeCast) { private fun assignTypeCastedValue(target: AsmAssignTarget, targetDt: DataType, value: PtExpression, origTypeCastExpression: PtTypeCast) {
@ -1840,7 +1840,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.XY, RegisterOrPair.XY,
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
assignExpressionToRegister(value, RegisterOrPair.A, false) assignExpressionToRegister(value, RegisterOrPair.A, false)
assignRegisterByte(target, CpuRegister.A, false) assignRegisterByte(target, CpuRegister.A, false, true)
return return
} }
else -> {} else -> {}
@ -2770,13 +2770,33 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
} }
internal fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister, signed: Boolean) { private fun extendToMSBofVirtualReg(cpuRegister: CpuRegister, vreg: String, signed: Boolean) {
if(signed) {
when(cpuRegister) {
CpuRegister.A -> { }
CpuRegister.X -> asmgen.out(" txa")
CpuRegister.Y -> asmgen.out(" tya")
}
asmgen.out("""
ora #$7f
bmi +
lda #0
+ sta $vreg+1""")
} else {
if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz $vreg+1")
else
asmgen.out(" lda #0 | sta $vreg+1")
}
}
internal fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister, signed: Boolean, extendWord: Boolean) {
val assignAsWord = target.datatype in WordDatatypes val assignAsWord = target.datatype in WordDatatypes
when(target.kind) { when(target.kind) {
TargetStorageKind.VARIABLE -> { TargetStorageKind.VARIABLE -> {
asmgen.out(" st${register.name.lowercase()} ${target.asmVarname}") asmgen.out(" st${register.name.lowercase()} ${target.asmVarname}")
if(assignAsWord) { if(assignAsWord && extendWord) {
if(target.datatype in SignedDatatypes) { if(target.datatype in SignedDatatypes) {
if(register!=CpuRegister.A) if(register!=CpuRegister.A)
asmgen.out(" t${register.name.lowercase()}a") asmgen.out(" t${register.name.lowercase()}a")
@ -2801,7 +2821,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
TargetStorageKind.ARRAY -> { TargetStorageKind.ARRAY -> {
if(assignAsWord) if(assignAsWord)
TODO("assign register byte as word into Array not yet supported") TODO("assign register byte as word into Array not yet supported")
assignRegisterByteToArray(target, register) assignRegisterByteToByteArray(target, register)
} }
TargetStorageKind.REGISTER -> { TargetStorageKind.REGISTER -> {
when(register) { when(register) {
@ -2810,6 +2830,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.X -> { asmgen.out(" tax") } RegisterOrPair.X -> { asmgen.out(" tax") }
RegisterOrPair.Y -> { asmgen.out(" tay") } RegisterOrPair.Y -> { asmgen.out(" tay") }
RegisterOrPair.AY -> { RegisterOrPair.AY -> {
require(extendWord) {
"no extend"
}
if(signed) if(signed)
asmgen.out(""" asmgen.out("""
ldy #0 ldy #0
@ -2821,6 +2844,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" ldy #0") asmgen.out(" ldy #0")
} }
RegisterOrPair.AX -> { RegisterOrPair.AX -> {
require(extendWord)
if(signed) if(signed)
asmgen.out(""" asmgen.out("""
ldx #0 ldx #0
@ -2832,6 +2856,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" ldx #0") asmgen.out(" ldx #0")
} }
RegisterOrPair.XY -> { RegisterOrPair.XY -> {
require(extendWord)
if(signed) if(signed)
asmgen.out(""" asmgen.out("""
tax tax
@ -2845,8 +2870,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
// only assign a single byte to the virtual register's Lsb val reg = "cx16.${target.register.toString().lowercase()}"
asmgen.out(" sta cx16.${target.register.toString().lowercase()}") asmgen.out(" sta $reg")
if(extendWord)
extendToMSBofVirtualReg(CpuRegister.A, reg, signed)
} }
else -> throw AssemblyError("weird register") else -> throw AssemblyError("weird register")
} }
@ -2855,6 +2882,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.X -> { } RegisterOrPair.X -> { }
RegisterOrPair.Y -> { asmgen.out(" txy") } RegisterOrPair.Y -> { asmgen.out(" txy") }
RegisterOrPair.AY -> { RegisterOrPair.AY -> {
require(extendWord)
if(signed) if(signed)
asmgen.out(""" asmgen.out("""
txa txa
@ -2867,6 +2895,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" txa | ldy #0") asmgen.out(" txa | ldy #0")
} }
RegisterOrPair.AX -> { RegisterOrPair.AX -> {
require(extendWord)
if(signed) if(signed)
asmgen.out(""" asmgen.out("""
txa txa
@ -2879,6 +2908,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" txa | ldx #0") asmgen.out(" txa | ldx #0")
} }
RegisterOrPair.XY -> { RegisterOrPair.XY -> {
require(extendWord)
if(signed) if(signed)
asmgen.out(""" asmgen.out("""
ldy #0 ldy #0
@ -2891,8 +2921,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
// only assign a single byte to the virtual register's Lsb val reg = "cx16.${target.register.toString().lowercase()}"
asmgen.out(" stx cx16.${target.register.toString().lowercase()}") asmgen.out(" stx $reg")
if(extendWord)
extendToMSBofVirtualReg(CpuRegister.X, reg, signed)
} }
else -> throw AssemblyError("weird register") else -> throw AssemblyError("weird register")
} }
@ -2901,6 +2933,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.X -> { asmgen.out(" tyx") } RegisterOrPair.X -> { asmgen.out(" tyx") }
RegisterOrPair.Y -> { } RegisterOrPair.Y -> { }
RegisterOrPair.AY -> { RegisterOrPair.AY -> {
require(extendWord)
if(signed) if(signed)
asmgen.out(""" asmgen.out("""
tya tya
@ -2913,6 +2946,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" tya | ldy #0") asmgen.out(" tya | ldy #0")
} }
RegisterOrPair.AX -> { RegisterOrPair.AX -> {
require(extendWord)
if(signed) if(signed)
asmgen.out(""" asmgen.out("""
tya tya
@ -2925,6 +2959,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" tya | ldx #0") asmgen.out(" tya | ldx #0")
} }
RegisterOrPair.XY -> { RegisterOrPair.XY -> {
require(extendWord)
if(signed) if(signed)
asmgen.out(""" asmgen.out("""
tya tya
@ -2939,8 +2974,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
// only assign a single byte to the virtual register's Lsb val reg = "cx16.${target.register.toString().lowercase()}"
asmgen.out(" sty cx16.${target.register.toString().lowercase()}") asmgen.out(" sty $reg")
if(extendWord)
extendToMSBofVirtualReg(CpuRegister.Y, reg, signed)
} }
else -> throw AssemblyError("weird register") else -> throw AssemblyError("weird register")
} }
@ -2949,7 +2986,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
} }
private fun assignRegisterByteToArray(target: AsmAssignTarget, register: CpuRegister) { private fun assignRegisterByteToByteArray(target: AsmAssignTarget, register: CpuRegister) {
if(target.array!!.splitWords) if(target.array!!.splitWords)
throw AssemblyError("cannot assign byte to split word array here ${target.position}") throw AssemblyError("cannot assign byte to split word array here ${target.position}")
@ -3553,7 +3590,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
TargetStorageKind.ARRAY -> { TargetStorageKind.ARRAY -> {
asmgen.out(" lda ${address.toHex()}") asmgen.out(" lda ${address.toHex()}")
assignRegisterByte(target, CpuRegister.A, false) assignRegisterByte(target, CpuRegister.A, false, true)
} }
TargetStorageKind.REGISTER -> when(target.register!!) { TargetStorageKind.REGISTER -> when(target.register!!) {
RegisterOrPair.A -> asmgen.out(" lda ${address.toHex()}") RegisterOrPair.A -> asmgen.out(" lda ${address.toHex()}")
@ -3587,7 +3624,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
TargetStorageKind.ARRAY -> { TargetStorageKind.ARRAY -> {
asmgen.loadByteFromPointerIntoA(identifier) asmgen.loadByteFromPointerIntoA(identifier)
assignRegisterByte(target, CpuRegister.A, false) assignRegisterByte(target, CpuRegister.A, false, true)
} }
TargetStorageKind.REGISTER -> { TargetStorageKind.REGISTER -> {
asmgen.loadByteFromPointerIntoA(identifier) asmgen.loadByteFromPointerIntoA(identifier)

View File

@ -1,8 +1,6 @@
TODO TODO
==== ====
- fix the parameter passing bug intruduced recently. Example: cx16.FB_cursor_position(math.rnd(), math.rnd())
- add a %zpallowed option to specify the range of zeropage register that can be used (intersect with the actual available zp registers ofcourse) - add a %zpallowed option to specify the range of zeropage register that can be used (intersect with the actual available zp registers ofcourse)
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... - [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....