mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
fix parameter passing bug introduced recently (byte not converted to word)
This commit is contained in:
parent
16b24fadea
commit
d54ab856e7
@ -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,
|
||||||
|
@ -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")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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 ....
|
||||||
|
Loading…
Reference in New Issue
Block a user