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) {
RegisterOrPair.A,
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.AY,
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 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)
assignAsmGen.assignRegisterByte(remainderTarget, CpuRegister.A, false)
assignAsmGen.assignRegisterByte(divisionTarget, CpuRegister.Y, false)
assignAsmGen.assignRegisterByte(remainderTarget, CpuRegister.A, false, false)
assignAsmGen.assignRegisterByte(divisionTarget, CpuRegister.Y, false, false)
}
private fun funcDivmodW(fcall: PtBuiltinFunctionCall) {
@ -273,11 +273,11 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
when(fcall.args[0].type) {
DataType.UBYTE -> {
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 -> {
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 -> {
asmgen.out(" jsr floats.func_sqrt_into_FAC1")
@ -686,7 +686,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
assignAsmGen.assignConstantByte(target, 0)
} else {
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")
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?) {
@ -714,7 +714,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
in SplitWordArrayTypes -> TODO("split word any/all")
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?) {
@ -723,7 +723,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
when (dt) {
DataType.BYTE -> {
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 -> {
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
asmgen.out(" jsr prog8_lib.func_clamp_${fcall.type.toString().lowercase()}")
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 -> {
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?) {
val signed = fcall.type in SignedDatatypes
if(fcall.type in ByteDatatypes) {
asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_B1", fcall.type) // right
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A) // left
asmgen.out(" cmp P8ZP_SCRATCH_B1")
if(signed) asmgen.out(" bmi +") else asmgen.out(" bcc +")
asmgen.out("""
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) {
when (fcall.type) {
in ByteDatatypes -> {
asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_B1", fcall.type) // right
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A) // left
asmgen.out(" cmp P8ZP_SCRATCH_B1")
if(signed) asmgen.out(" bmi +") else asmgen.out(" bcc +")
asmgen.out("""
lda P8ZP_SCRATCH_W1
ldy P8ZP_SCRATCH_W1+1
cmp P8ZP_SCRATCH_W2
tya
sbc P8ZP_SCRATCH_W2+1
bvc +
eor #$80
+ bpl +
lda P8ZP_SCRATCH_W1
ldy P8ZP_SCRATCH_W1+1
jmp ++
+ lda P8ZP_SCRATCH_W2
ldy P8ZP_SCRATCH_W2+1
+""")
} else {
asmgen.out("""
lda 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
+""")
lda P8ZP_SCRATCH_B1
+""")
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, signed, fcall.position, fcall.definingISub(), asmgen)
asmgen.assignRegister(RegisterOrPair.A, targetReg)
}
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("""
lda P8ZP_SCRATCH_W1
ldy P8ZP_SCRATCH_W1+1
cmp P8ZP_SCRATCH_W2
tya
sbc P8ZP_SCRATCH_W2+1
bvc +
eor #$80
+ bpl +
lda P8ZP_SCRATCH_W1
ldy P8ZP_SCRATCH_W1+1
jmp ++
+ lda P8ZP_SCRATCH_W2
ldy P8ZP_SCRATCH_W2+1
+""")
} else {
asmgen.out("""
lda 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")
}
}
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes)
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, false)
return
}
@ -109,7 +109,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
when (elementDt) {
in ByteDatatypes -> {
asmgen.out(" lda $arrayVarName+$indexValue")
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes)
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, false)
}
in WordDatatypes -> {
asmgen.out(" lda $arrayVarName+$indexValue | ldy $arrayVarName+$indexValue+1")
@ -127,7 +127,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
in ByteDatatypes -> {
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.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 -> {
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
@ -154,7 +154,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
fun assignViaExprEval(expression: PtExpression) {
assignExpressionToVariable(expression, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2")
assignRegisterByte(assign.target, CpuRegister.A, false)
assignRegisterByte(assign.target, CpuRegister.A, false, true)
}
val value = assign.source.memory!!
@ -169,7 +169,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
is PtBinaryExpression -> {
val addrExpr = value.address as PtBinaryExpression
if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
assignRegisterByte(assign.target, CpuRegister.A, false)
assignRegisterByte(assign.target, CpuRegister.A, false, true)
} else {
assignViaExprEval(value.address)
}
@ -223,9 +223,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
else -> {
// do NOT restore X register before assigning the result values first
when (returnValue.first.registerOrPair) {
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A, returnValue.second in SignedDatatypes)
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X, returnValue.second in SignedDatatypes)
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y, 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, true)
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y, returnValue.second in SignedDatatypes, true)
RegisterOrPair.AX -> assignVirtualRegister(assign.target, RegisterOrPair.AX)
RegisterOrPair.AY -> assignVirtualRegister(assign.target, RegisterOrPair.AY)
RegisterOrPair.XY -> assignVirtualRegister(assign.target, RegisterOrPair.XY)
@ -261,7 +261,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
if(assign.target.register==null) {
// still need to assign the result to the target variable/etc.
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
DataType.STR -> {
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")
else -> throw AssemblyError("invalid prefix operator")
}
assignRegisterByte(assign.target, CpuRegister.A, signed)
assignRegisterByte(assign.target, CpuRegister.A, signed, false)
} else {
assignExpressionToRegister(value.value, RegisterOrPair.AY, signed)
when(value.operator) {
@ -376,7 +376,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
is PtContainmentCheck -> {
containmentCheckIntoA(value)
assignRegisterByte(assign.target, CpuRegister.A, false)
assignRegisterByte(assign.target, CpuRegister.A, false, true)
}
is PtBinaryExpression -> {
if(!attemptAssignOptimizedBinexpr(value, assign)) {
@ -415,7 +415,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
when(target.datatype) {
in ByteDatatypes -> {
asmgen.out(" lda cx16.${register.toString().lowercase()}L")
assignRegisterByte(target, CpuRegister.A, false)
assignRegisterByte(target, CpuRegister.A, false, false)
}
in WordDatatypes -> assignRegisterpairWord(target, register)
else -> throw AssemblyError("expected byte or word")
@ -493,7 +493,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
if(target.register==RegisterOrPair.A)
asmgen.out(" cmp #0") // fix the status register
else
assignRegisterByte(target, CpuRegister.A, false)
assignRegisterByte(target, CpuRegister.A, false, true)
return true
}
DataType.UWORD -> {
@ -513,7 +513,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" pha")
assignExpressionToRegister(expr.right, RegisterOrPair.Y, false)
asmgen.out(" pla | jsr math.divmod_ub_asm")
assignRegisterByte(target, CpuRegister.Y, false)
assignRegisterByte(target, CpuRegister.Y, false, true)
return true
}
DataType.BYTE -> {
@ -521,7 +521,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" pha")
assignExpressionToRegister(expr.right, RegisterOrPair.Y, true)
asmgen.out(" pla | jsr math.divmod_b_asm")
assignRegisterByte(target, CpuRegister.Y, true)
assignRegisterByte(target, CpuRegister.Y, true, true)
return true
}
DataType.UWORD -> {
@ -549,7 +549,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" pha")
assignExpressionToRegister(expr.right, RegisterOrPair.Y, expr.type in SignedDatatypes)
asmgen.out(" pla | jsr math.multiply_bytes")
assignRegisterByte(target, CpuRegister.A, false)
assignRegisterByte(target, CpuRegister.A, false, true)
return true
}
in WordDatatypes -> {
@ -587,7 +587,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" jsr math.mul_byte_${value}")
else
asmgen.out(" ldy #$value | jsr math.multiply_bytes")
assignRegisterByte(target, CpuRegister.A, false)
assignRegisterByte(target, CpuRegister.A, false, true)
return true
}
in WordDatatypes -> {
@ -647,7 +647,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" jsr math.lsr_ubyte_A")
else
asmgen.out(" jsr math.asl_byte_A")
assignRegisterByte(target, CpuRegister.A, signed)
assignRegisterByte(target, CpuRegister.A, signed, true)
return true
} else {
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
}
else -> {
@ -691,7 +691,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} else {
asmgen.out(" lda #0")
}
assignRegisterByte(target, CpuRegister.A, signed)
assignRegisterByte(target, CpuRegister.A, signed, true)
return true
}
}
@ -764,7 +764,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" clc | adc $symname")
else
asmgen.out(" sec | sbc $symname")
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes)
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
return true
}
is PtNumber -> {
@ -773,7 +773,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" clc | adc #${right.number.toHex()}")
else
asmgen.out(" sec | sbc #${right.number.toHex()}")
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes)
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
return true
}
else -> {
@ -804,7 +804,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
else
asmgen.out(" sec | sbc $arrayvarname,y")
}
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes)
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
} else {
assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", right.type)
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")
else
asmgen.out(" sec | sbc P8ZP_SCRATCH_B1")
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes)
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
}
return true
}
@ -1005,7 +1005,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
else -> throw AssemblyError("invalid operator")
}
assignRegisterByte(target, CpuRegister.A, false)
assignRegisterByte(target, CpuRegister.A, false, true)
return true
}
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
}
assignRegisterByte(assign.target, CpuRegister.A, false)
assignRegisterByte(assign.target, CpuRegister.A, false, true)
return true
}
@ -1558,7 +1558,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
else -> return false
}
assignRegisterByte(assign.target, CpuRegister.A, signed)
assignRegisterByte(assign.target, CpuRegister.A, signed, true)
return true
}
@ -1575,7 +1575,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
"^", "xor" -> asmgen.out(" eor $operand")
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) {
@ -1614,7 +1614,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
beq +
lda #1
+ eor #1""")
assignRegisterByte(assign.target, CpuRegister.A, false)
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
in WordDatatypes -> {
@ -1625,13 +1625,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
beq +
lda #1
+ eor #1""")
assignRegisterByte(assign.target, CpuRegister.A, false)
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
DataType.FLOAT -> {
assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
asmgen.out(" jsr floats.SIGN | and #1 | eor #1")
assignRegisterByte(assign.target, CpuRegister.A, false)
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
else->{
@ -1645,7 +1645,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
assignExpressionToRegister(expr.left, RegisterOrPair.A, dt==DataType.BYTE)
asmgen.out(" beq + | lda #1")
asmgen.out("+")
assignRegisterByte(assign.target, CpuRegister.A, false)
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
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(" beq + | lda #1")
asmgen.out("+")
assignRegisterByte(assign.target, CpuRegister.A, false)
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
DataType.FLOAT -> {
assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
asmgen.out(" jsr floats.SIGN")
assignRegisterByte(assign.target, CpuRegister.A, true)
assignRegisterByte(assign.target, CpuRegister.A, true, false)
return true
}
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'")
}
assignRegisterByte(target, CpuRegister.A, false)
assignRegisterByte(target, CpuRegister.A, false, true)
}
private fun assignTypeCastedValue(target: AsmAssignTarget, targetDt: DataType, value: PtExpression, origTypeCastExpression: PtTypeCast) {
@ -1840,7 +1840,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.XY,
in Cx16VirtualRegisters -> {
assignExpressionToRegister(value, RegisterOrPair.A, false)
assignRegisterByte(target, CpuRegister.A, false)
assignRegisterByte(target, CpuRegister.A, false, true)
return
}
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
when(target.kind) {
TargetStorageKind.VARIABLE -> {
asmgen.out(" st${register.name.lowercase()} ${target.asmVarname}")
if(assignAsWord) {
if(assignAsWord && extendWord) {
if(target.datatype in SignedDatatypes) {
if(register!=CpuRegister.A)
asmgen.out(" t${register.name.lowercase()}a")
@ -2801,7 +2821,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
TargetStorageKind.ARRAY -> {
if(assignAsWord)
TODO("assign register byte as word into Array not yet supported")
assignRegisterByteToArray(target, register)
assignRegisterByteToByteArray(target, register)
}
TargetStorageKind.REGISTER -> {
when(register) {
@ -2810,6 +2830,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.X -> { asmgen.out(" tax") }
RegisterOrPair.Y -> { asmgen.out(" tay") }
RegisterOrPair.AY -> {
require(extendWord) {
"no extend"
}
if(signed)
asmgen.out("""
ldy #0
@ -2821,6 +2844,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" ldy #0")
}
RegisterOrPair.AX -> {
require(extendWord)
if(signed)
asmgen.out("""
ldx #0
@ -2832,6 +2856,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" ldx #0")
}
RegisterOrPair.XY -> {
require(extendWord)
if(signed)
asmgen.out("""
tax
@ -2845,8 +2870,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
in Cx16VirtualRegisters -> {
// only assign a single byte to the virtual register's Lsb
asmgen.out(" sta cx16.${target.register.toString().lowercase()}")
val reg = "cx16.${target.register.toString().lowercase()}"
asmgen.out(" sta $reg")
if(extendWord)
extendToMSBofVirtualReg(CpuRegister.A, reg, signed)
}
else -> throw AssemblyError("weird register")
}
@ -2855,6 +2882,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.X -> { }
RegisterOrPair.Y -> { asmgen.out(" txy") }
RegisterOrPair.AY -> {
require(extendWord)
if(signed)
asmgen.out("""
txa
@ -2867,6 +2895,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" txa | ldy #0")
}
RegisterOrPair.AX -> {
require(extendWord)
if(signed)
asmgen.out("""
txa
@ -2879,6 +2908,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" txa | ldx #0")
}
RegisterOrPair.XY -> {
require(extendWord)
if(signed)
asmgen.out("""
ldy #0
@ -2891,8 +2921,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
in Cx16VirtualRegisters -> {
// only assign a single byte to the virtual register's Lsb
asmgen.out(" stx cx16.${target.register.toString().lowercase()}")
val reg = "cx16.${target.register.toString().lowercase()}"
asmgen.out(" stx $reg")
if(extendWord)
extendToMSBofVirtualReg(CpuRegister.X, reg, signed)
}
else -> throw AssemblyError("weird register")
}
@ -2901,6 +2933,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.X -> { asmgen.out(" tyx") }
RegisterOrPair.Y -> { }
RegisterOrPair.AY -> {
require(extendWord)
if(signed)
asmgen.out("""
tya
@ -2913,6 +2946,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" tya | ldy #0")
}
RegisterOrPair.AX -> {
require(extendWord)
if(signed)
asmgen.out("""
tya
@ -2925,6 +2959,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" tya | ldx #0")
}
RegisterOrPair.XY -> {
require(extendWord)
if(signed)
asmgen.out("""
tya
@ -2939,8 +2974,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
in Cx16VirtualRegisters -> {
// only assign a single byte to the virtual register's Lsb
asmgen.out(" sty cx16.${target.register.toString().lowercase()}")
val reg = "cx16.${target.register.toString().lowercase()}"
asmgen.out(" sty $reg")
if(extendWord)
extendToMSBofVirtualReg(CpuRegister.Y, reg, signed)
}
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)
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 -> {
asmgen.out(" lda ${address.toHex()}")
assignRegisterByte(target, CpuRegister.A, false)
assignRegisterByte(target, CpuRegister.A, false, true)
}
TargetStorageKind.REGISTER -> when(target.register!!) {
RegisterOrPair.A -> asmgen.out(" lda ${address.toHex()}")
@ -3587,7 +3624,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
TargetStorageKind.ARRAY -> {
asmgen.loadByteFromPointerIntoA(identifier)
assignRegisterByte(target, CpuRegister.A, false)
assignRegisterByte(target, CpuRegister.A, false, true)
}
TargetStorageKind.REGISTER -> {
asmgen.loadByteFromPointerIntoA(identifier)

View File

@ -1,8 +1,6 @@
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)
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....