6502 asmgen

This commit is contained in:
Irmen de Jong 2024-02-05 23:31:55 +01:00
parent 10d12f73d6
commit 6b52ba9397
10 changed files with 136 additions and 55 deletions

View File

@ -142,11 +142,12 @@ private fun PtVariable.prefix(st: SymbolTable): PtVariable {
return this
val arrayValue = value as? PtArray
return if(arrayValue!=null && arrayValue.children.any { it !is PtNumber} ) {
return if(arrayValue!=null && arrayValue.children.any { it !is PtNumber && it !is PtBool } ) {
val newValue = PtArray(arrayValue.type, arrayValue.position)
arrayValue.children.forEach { elt ->
when(elt) {
is PtIdentifier -> newValue.add(elt.prefix(arrayValue, st))
is PtBool -> newValue.add(elt)
is PtNumber -> newValue.add(elt)
is PtAddressOf -> {
if(elt.definingBlock()?.options?.noSymbolPrefixing==true)
@ -624,7 +625,7 @@ class AsmGen6502Internal (
}
when (expr.type) {
in ByteDatatypes -> {
in ByteDatatypesWithBoolean -> {
assignExpressionToRegister(expr.index, RegisterOrPair.fromCpuRegister(register), false)
}
in WordDatatypes -> {
@ -691,7 +692,7 @@ class AsmGen6502Internal (
internal fun assignExpressionTo(value: PtExpression, target: AsmAssignTarget) {
when (target.datatype) {
in ByteDatatypes -> {
in ByteDatatypesWithBoolean -> {
if (value.asConstInteger()==0) {
when(target.kind) {
TargetStorageKind.VARIABLE -> {
@ -805,7 +806,7 @@ class AsmGen6502Internal (
}
when(stmt.condition.type) {
in WordDatatypes -> translateWordEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, label)
in ByteDatatypes -> translateByteEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, label)
in ByteDatatypesWithBoolean -> translateByteEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, label)
else -> throw AssemblyError("weird condition dt")
}
} else {
@ -813,7 +814,7 @@ class AsmGen6502Internal (
val endLabel = makeLabel("if_end")
when(stmt.condition.type) {
in WordDatatypes -> translateWordNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, endLabel)
in ByteDatatypes -> translateByteNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, endLabel)
in ByteDatatypesWithBoolean -> translateByteNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, endLabel)
else -> throw AssemblyError("weird condition dt")
}
translate(stmt.ifScope)
@ -825,7 +826,7 @@ class AsmGen6502Internal (
val endLabel = makeLabel("if_end")
when(stmt.condition.type) {
in WordDatatypes -> translateWordNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, elseLabel)
in ByteDatatypes -> translateByteNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, elseLabel)
in ByteDatatypesWithBoolean -> translateByteNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, elseLabel)
else -> throw AssemblyError("weird condition dt")
}
translate(stmt.ifScope)
@ -839,7 +840,7 @@ class AsmGen6502Internal (
private fun requireComparisonExpression(condition: PtExpression) {
if (!(condition is PtBinaryExpression && condition.operator in ComparisonOperators))
throw AssemblyError("expected boolean comparison expression $condition")
throw AssemblyError("expected boolean comparison expression")
}
private fun translate(stmt: PtRepeatLoop) {
@ -1118,7 +1119,7 @@ $repeatLabel""")
val sub = ret.definingSub()!!
val returnReg = sub.returnRegister()!!
when (sub.returntype) {
in NumericDatatypes -> {
in NumericDatatypes, DataType.BOOL -> {
assignExpressionToRegister(returnvalue, returnReg.registerOrPair!!)
}
else -> {
@ -1256,6 +1257,7 @@ $repeatLabel""")
return when(expr) {
is PtIdentifier -> false
is PtNumber -> false
is PtBool -> false
is PtMemoryByte -> expr.address !is PtIdentifier && expr.address !is PtNumber
is PtTypeCast -> evalBytevalueWillClobberA(expr.value)
else -> true
@ -1344,7 +1346,7 @@ $repeatLabel""")
// invert the comparison, so we can reuse the JumpIfFalse code generation routines
val invertedComparisonOperator = invertedComparisonOperator(expr.operator)
?: throw AssemblyError("can't invert comparison $expr")
?: throw AssemblyError("can't invert comparison ${expr.operator} $expr")
val left = expr.left
val right = expr.right
@ -1383,7 +1385,7 @@ $repeatLabel""")
jumpIfFalseLabel: String
) {
val dt = left.type
if(dt in IntegerDatatypes && left is PtIdentifier)
if(dt in IntegerDatatypesWithBoolean && left is PtIdentifier)
return testVariableZeroOrJumpElsewhere(left, dt, operator, jumpIfFalseLabel)
when(dt) {
@ -1543,7 +1545,7 @@ $repeatLabel""")
when (operator) {
"==" -> {
when (dt) {
in ByteDatatypes -> translateByteEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
in ByteDatatypesWithBoolean -> translateByteEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
in WordDatatypes -> translateWordEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.FLOAT -> translateFloatEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.STR -> translateStringEqualsOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
@ -1552,7 +1554,7 @@ $repeatLabel""")
}
"!=" -> {
when (dt) {
in ByteDatatypes -> translateByteNotEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
in ByteDatatypesWithBoolean -> translateByteNotEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
in WordDatatypes -> translateWordNotEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.FLOAT -> translateFloatNotEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.STR -> translateStringNotEqualsOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
@ -2547,6 +2549,7 @@ $repeatLabel""")
}
when (right) {
is PtBool -> TODO("word equals for bool operand")
is PtNumber -> {
assignExpressionToRegister(left, RegisterOrPair.AY)
val number = right.number.toHex()
@ -2635,6 +2638,7 @@ $repeatLabel""")
}
when (right) {
is PtBool -> TODO("word not equals for bool operand")
is PtNumber -> {
assignExpressionToRegister(left, RegisterOrPair.AY)
val number = right.number.toHex()
@ -2669,6 +2673,7 @@ $repeatLabel""")
}
}
else -> {
TODO("word not equals boolean in special case?")
if(left.isSimple()) {
assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD)
assignExpressionToRegister(left, RegisterOrPair.AY)
@ -2983,6 +2988,7 @@ $repeatLabel""")
private fun wordJumpForSimpleLeftOperand(left: PtExpression, right: PtExpression, code: (String, String)->Unit): Boolean {
when (left) {
is PtBool -> TODO("word jump for bool operand")
is PtNumber -> {
assignExpressionToRegister(right, RegisterOrPair.AY)
val number = left.number.toHex()
@ -3010,32 +3016,44 @@ $repeatLabel""")
}
private fun byteJumpForSimpleRightOperand(left: PtExpression, right: PtExpression, code: (String)->Unit): Boolean {
if(right is PtNumber) {
assignExpressionToRegister(left, RegisterOrPair.A)
code("#${right.number.toHex()}")
return true
}
if(right is PtIdentifier) {
assignExpressionToRegister(left, RegisterOrPair.A)
code(asmVariableName(right))
return true
}
var memread = right as? PtMemoryByte
if(memread==null && right is PtTypeCast)
memread = right.value as? PtMemoryByte
if(memread!=null) {
val address = memread.address as? PtNumber
if(address!=null) {
when (right) {
is PtBool -> {
assignExpressionToRegister(left, RegisterOrPair.A)
code(address.number.toHex())
code("#${right.asInt()} ; TODO can we get rid of this cmp when dealing with booleans?") // TODO can we get rid of the cmp when dealing with booleans?
return true
}
is PtNumber -> {
assignExpressionToRegister(left, RegisterOrPair.A)
code("#${right.number.toHex()}")
return true
}
is PtIdentifier -> {
assignExpressionToRegister(left, RegisterOrPair.A)
code(asmVariableName(right))
return true
}
else -> {
var memread = right as? PtMemoryByte
if (memread == null && right is PtTypeCast)
memread = right.value as? PtMemoryByte
if (memread != null) {
val address = memread.address as? PtNumber
if (address != null) {
assignExpressionToRegister(left, RegisterOrPair.A)
code(address.number.toHex())
return true
}
}
return false
}
}
return false
}
private fun wordJumpForSimpleRightOperands(left: PtExpression, right: PtExpression, code: (String, String)->Unit): Boolean {
when (right) {
is PtBool -> TODO("word jump for bool operand")
is PtNumber -> {
assignExpressionToRegister(left, RegisterOrPair.AY)
val number = right.number.toHex()
@ -3077,7 +3095,7 @@ $repeatLabel""")
out(" lda P8ZP_SCRATCH_REG")
}
else {
if (parameter.type in ByteDatatypes) {
if (parameter.type in ByteDatatypesWithBoolean) {
if (isTargetCpu(CpuType.CPU65c02)) {
when (reg.registerOrPair) {
RegisterOrPair.A -> out(" pla")
@ -3135,7 +3153,7 @@ $repeatLabel""")
}
internal fun popCpuStack(dt: DataType) {
if (dt in ByteDatatypes) {
if (dt in ByteDatatypesWithBoolean) {
out(" pla")
} else if (dt in WordDatatypes) {
if (isTargetCpu(CpuType.CPU65c02))
@ -3149,7 +3167,7 @@ $repeatLabel""")
internal fun pushCpuStack(dt: DataType, value: PtExpression) {
val signed = value.type.oneOf(DataType.BYTE, DataType.WORD)
if(dt in ByteDatatypes) {
if(dt in ByteDatatypesWithBoolean) {
assignExpressionToRegister(value, RegisterOrPair.A, signed)
out(" pha")
} else if(dt in WordDatatypes) {
@ -3176,7 +3194,7 @@ $repeatLabel""")
}
internal fun needAsaveForExpr(arg: PtExpression): Boolean =
arg !is PtNumber && arg !is PtIdentifier && (arg !is PtMemoryByte || !arg.isSimple())
arg !is PtNumber && arg !is PtBool && arg !is PtIdentifier && (arg !is PtMemoryByte || !arg.isSimple())
private val subroutineExtrasCache = mutableMapOf<IPtSubroutine, SubroutineExtraAsmInfo>()

View File

@ -315,6 +315,10 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A)
asmgen.out(" cmp #${arg2.number.toInt()}")
}
is PtBool -> {
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A)
asmgen.out(" cmp #${arg2.asInt()}")
}
is PtMemoryByte -> {
if(arg2.address is PtNumber) {
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A)
@ -343,6 +347,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
cmp ${asmgen.asmVariableName(arg2)}
+""")
}
is PtBool -> TODO("word compare against bool")
is PtNumber -> {
asmgen.assignExpressionToRegister(arg1, RegisterOrPair.AY)
asmgen.out("""

View File

@ -359,7 +359,7 @@ $loopLabel lda ${65535.toHex()} ; modified
bne $loopLabel
$endLabel""")
}
DataType.ARRAY_UB, DataType.ARRAY_B -> {
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_BOOL -> {
val indexVar = asmgen.makeLabel("for_index")
asmgen.out("""
ldy #0

View File

@ -16,8 +16,8 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
}
internal fun optimizeIntArgsViaRegisters(sub: PtSub) =
(sub.parameters.size==1 && sub.parameters[0].type in IntegerDatatypes)
|| (sub.parameters.size==2 && sub.parameters[0].type in ByteDatatypes && sub.parameters[1].type in ByteDatatypes)
(sub.parameters.size==1 && sub.parameters[0].type in IntegerDatatypesWithBoolean)
|| (sub.parameters.size==2 && sub.parameters[0].type in ByteDatatypesWithBoolean && sub.parameters[1].type in ByteDatatypesWithBoolean)
internal fun translateFunctionCall(call: PtFunctionCall) {
// Output only the code to set up the parameters and perform the actual call
@ -84,6 +84,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
is PtMachineRegister -> false
is PtMemoryByte -> return usesOtherRegistersWhileEvaluating(arg.address)
is PtNumber -> false
is PtBool -> false
else -> true
}
}
@ -152,7 +153,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
}
if (statusflag!=null) {
if(requiredDt!=value.type)
throw AssemblyError("for statusflag, byte value is required")
throw AssemblyError("for statusflag, byte or bool value is required")
if (statusflag == Statusflag.Pc) {
// this boolean param needs to be set last, right before the jsr
// for now, this is already enforced on the subroutine definition by the Ast Checker
@ -161,6 +162,9 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
val carrySet = value.number.toInt() != 0
asmgen.out(if(carrySet) " sec" else " clc")
}
is PtBool -> {
asmgen.out(if(value.value) " sec" else " clc")
}
is PtIdentifier -> {
val sourceName = asmgen.asmVariableName(value)
// note: cannot use X register here to store A because it might be used for other arguments

View File

@ -404,7 +404,7 @@ internal class ProgramAndVarsGen(
if(sub.parameters.size==1) {
val dt = sub.parameters[0].type
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, dt, sub, sub.parameters[0].position, variableAsmName = sub.parameters[0].name)
if(dt in ByteDatatypes)
if(dt in ByteDatatypesWithBoolean)
asmgen.assignRegister(RegisterOrPair.A, target)
else
asmgen.assignRegister(RegisterOrPair.AY, target)
@ -604,7 +604,7 @@ internal class ProgramAndVarsGen(
private fun uninitializedVariable2asm(variable: StStaticVariable) {
when (variable.dt) {
DataType.UBYTE -> asmgen.out("${variable.name}\t.byte ?")
DataType.BOOL, DataType.UBYTE -> asmgen.out("${variable.name}\t.byte ?")
DataType.BYTE -> asmgen.out("${variable.name}\t.char ?")
DataType.UWORD -> asmgen.out("${variable.name}\t.word ?")
DataType.WORD -> asmgen.out("${variable.name}\t.sint ?")
@ -634,6 +634,7 @@ internal class ProgramAndVarsGen(
} else 0
when (variable.dt) {
DataType.BOOL -> TODO("bool var to asm")
DataType.UBYTE -> asmgen.out("${variable.name}\t.byte ${initialValue.toHex()}")
DataType.BYTE -> asmgen.out("${variable.name}\t.char $initialValue")
DataType.UWORD -> asmgen.out("${variable.name}\t.word ${initialValue.toHex()}")
@ -658,7 +659,7 @@ internal class ProgramAndVarsGen(
private fun arrayVariable2asm(varname: String, dt: DataType, value: StArray?, orNumberOfZeros: Int?) {
when(dt) {
DataType.ARRAY_UB -> {
DataType.ARRAY_UB, DataType.ARRAY_BOOL -> {
val data = makeArrayFillDataUnsigned(dt, value, orNumberOfZeros)
if (data.size <= 16)
asmgen.out("$varname\t.byte ${data.joinToString()}")
@ -763,6 +764,16 @@ internal class ProgramAndVarsGen(
private fun makeArrayFillDataUnsigned(dt: DataType, value: StArray?, orNumberOfZeros: Int?): List<String> {
val array = value ?: zeroFilledArray(orNumberOfZeros!!)
return when (dt) {
DataType.ARRAY_BOOL ->
// byte array can never contain pointer-to types, so treat values as all integers
array.map {
if(it.boolean!=null)
if(it.boolean==true) "1" else "0"
else {
val number = it.number!!
if(number==0.0) "0" else "1"
}
}
DataType.ARRAY_UB ->
// byte array can never contain pointer-to types, so treat values as all integers
array.map {

View File

@ -18,8 +18,8 @@ internal class AnyExprAsmGen(
) {
fun assignAnyExpressionUsingStack(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
when(expr.type) {
in ByteDatatypes -> {
if(expr.left.type in ByteDatatypes && expr.right.type in ByteDatatypes)
in ByteDatatypesWithBoolean -> {
if(expr.left.type in ByteDatatypesWithBoolean && expr.right.type in ByteDatatypesWithBoolean)
return assignByteBinExpr(expr, assign)
if (expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
require(expr.operator in ComparisonOperators)

View File

@ -14,6 +14,7 @@ internal enum class TargetStorageKind {
}
internal enum class SourceStorageKind {
LITERALBOOLEAN,
LITERALNUMBER,
VARIABLE,
ARRAY,
@ -133,6 +134,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
val memory: PtMemoryByte? = null,
val register: RegisterOrPair? = null,
val number: PtNumber? = null,
val boolean: PtBool? = null,
val expression: PtExpression? = null
)
{
@ -147,6 +149,9 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
val cv = value as? PtNumber
if(cv!=null)
return AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, asmgen, cv.type, number = cv)
val bv = value as? PtBool
if(bv!=null)
return AsmAssignSource(SourceStorageKind.LITERALBOOLEAN, program, asmgen, DataType.BOOL, boolean = bv)
return when(value) {
// checked above: is PtNumber -> throw AssemblyError("should have been constant value")
@ -194,7 +199,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
// allow some signed/unsigned relaxations
fun withAdjustedDt(newType: DataType) =
AsmAssignSource(kind, program, asmgen, newType, variableAsmName, array, memory, register, number, expression)
AsmAssignSource(kind, program, asmgen, newType, variableAsmName, array, memory, register, number, boolean, expression)
if(target.datatype!=datatype) {
if(target.datatype in ByteDatatypes && datatype in ByteDatatypes) {

View File

@ -33,6 +33,16 @@ internal class AssignmentAsmGen(private val program: PtProgram,
fun translateNormalAssignment(assign: AsmAssignment, scope: IPtSubroutine?) {
when(assign.source.kind) {
SourceStorageKind.LITERALBOOLEAN -> {
// simple case: assign a constant number
val num = assign.source.boolean!!.asInt()
when (assign.target.datatype) {
DataType.BOOL, DataType.UBYTE, DataType.BYTE -> assignConstantByte(assign.target, num)
DataType.UWORD, DataType.WORD -> assignConstantWord(assign.target, num)
DataType.FLOAT -> assignConstantFloat(assign.target, num.toDouble())
else -> throw AssemblyError("weird numval type")
}
}
SourceStorageKind.LITERALNUMBER -> {
// simple case: assign a constant number
val num = assign.source.number!!.number

View File

@ -18,13 +18,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
val a2 = AsmAssignment(assign.source, assign.target, assign.memsizer, assign.position)
assignmentAsmGen.inplaceNegate(a2, false, scope)
}
"~" -> {
"~", "not" -> {
val a2 = AsmAssignment(assign.source, assign.target, assign.memsizer, assign.position)
assignmentAsmGen.inplaceInvert(a2, scope)
}
"+" -> { /* is a nop */ }
else -> {
require(assign.operator in ComparisonOperators || assign.operator.length>=2) { "invalid aug assign operator ${assign.operator}" }
augmentedAssignExpr(assign)
}
}
@ -64,11 +63,15 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
fun regName(v: AsmAssignSource) = "cx16.${v.register!!.name.lowercase()}"
if(value.kind==SourceStorageKind.LITERALBOOLEAN)
TODO("inplace modification literalboolean")
when (target.kind) {
TargetStorageKind.VARIABLE -> {
when (target.datatype) {
in ByteDatatypes -> {
in ByteDatatypesWithBoolean -> {
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationByteVariableWithLiteralval(target.asmVarname, target.datatype, operator, value.boolean!!.asInt())
SourceStorageKind.LITERALNUMBER -> inplacemodificationByteVariableWithLiteralval(target.asmVarname, target.datatype, operator, value.number!!.number.toInt())
SourceStorageKind.VARIABLE -> inplacemodificationByteVariableWithVariable(target.asmVarname, target.datatype, operator, value.asmVarname)
SourceStorageKind.REGISTER -> inplacemodificationByteVariableWithVariable(target.asmVarname, target.datatype, operator, regName(value))
@ -87,6 +90,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
in WordDatatypes -> {
val block = target.origAstTarget?.definingBlock()
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationWordWithLiteralval(target.asmVarname, target.datatype, operator, value.boolean!!.asInt(), block)
SourceStorageKind.LITERALNUMBER -> inplacemodificationWordWithLiteralval(target.asmVarname, target.datatype, operator, value.number!!.number.toInt(), block)
SourceStorageKind.VARIABLE -> inplacemodificationWordWithVariable(target.asmVarname, target.datatype, operator, value.asmVarname, value.datatype, block)
SourceStorageKind.REGISTER -> inplacemodificationWordWithVariable(target.asmVarname, target.datatype, operator, regName(value), value.datatype, block)
@ -105,6 +109,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
DataType.FLOAT -> {
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationFloatWithLiteralval(target.asmVarname, operator, value.boolean!!.asInt().toDouble())
SourceStorageKind.LITERALNUMBER -> inplacemodificationFloatWithLiteralval(target.asmVarname, operator, value.number!!.number)
SourceStorageKind.VARIABLE -> inplacemodificationFloatWithVariable(target.asmVarname, operator, value.asmVarname)
SourceStorageKind.REGISTER -> inplacemodificationFloatWithVariable(target.asmVarname, operator, regName(value))
@ -129,6 +134,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
is PtNumber -> {
val addr = (memory.address as PtNumber).number.toInt()
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationByteVariableWithLiteralval(addr.toHex(), DataType.UBYTE, operator, value.boolean!!.asInt())
SourceStorageKind.LITERALNUMBER -> inplacemodificationByteVariableWithLiteralval(addr.toHex(), DataType.UBYTE, operator, value.number!!.number.toInt())
SourceStorageKind.VARIABLE -> inplacemodificationByteVariableWithVariable(addr.toHex(), DataType.UBYTE, operator, value.asmVarname)
SourceStorageKind.REGISTER -> inplacemodificationByteVariableWithVariable(addr.toHex(), DataType.UBYTE, operator, regName(value))
@ -147,6 +153,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
is PtIdentifier -> {
val pointer = memory.address as PtIdentifier
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationBytePointerWithLiteralval(pointer, operator, value.boolean!!.asInt())
SourceStorageKind.LITERALNUMBER -> inplacemodificationBytePointerWithLiteralval(pointer, operator, value.number!!.number.toInt())
SourceStorageKind.VARIABLE -> inplacemodificationBytePointerWithVariable(pointer, operator, value.asmVarname)
SourceStorageKind.REGISTER -> inplacemodificationBytePointerWithVariable(pointer, operator, regName(value))
@ -170,6 +177,10 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
asmgen.saveRegisterStack(CpuRegister.Y, true)
asmgen.out(" jsr prog8_lib.read_byte_from_address_in_AY_into_A")
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> {
inplacemodificationRegisterAwithVariable(operator, "#${value.boolean!!.asInt()}", false)
asmgen.out(" tax")
}
SourceStorageKind.LITERALNUMBER -> {
inplacemodificationRegisterAwithVariable(operator, "#${value.number!!.number.toInt()}", false)
asmgen.out(" tax")
@ -231,6 +242,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
when (target.datatype) {
in ByteDatatypes -> {
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationByteVariableWithLiteralval(targetVarName, target.datatype, operator, value.boolean!!.asInt())
SourceStorageKind.LITERALNUMBER -> inplacemodificationByteVariableWithLiteralval(targetVarName, target.datatype, operator, value.number!!.number.toInt())
SourceStorageKind.VARIABLE -> inplacemodificationByteVariableWithVariable(targetVarName, target.datatype, operator, value.asmVarname)
SourceStorageKind.REGISTER -> inplacemodificationByteVariableWithVariable(targetVarName, target.datatype, operator, regName(value))
@ -250,6 +262,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
in WordDatatypes -> {
val block = target.origAstTarget?.definingBlock()
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationWordWithLiteralval(targetVarName, target.datatype, operator, value.boolean!!.asInt(), block)
SourceStorageKind.LITERALNUMBER -> inplacemodificationWordWithLiteralval(targetVarName, target.datatype, operator, value.number!!.number.toInt(), block)
SourceStorageKind.VARIABLE -> inplacemodificationWordWithVariable(targetVarName, target.datatype, operator, value.asmVarname, value.datatype, block)
SourceStorageKind.REGISTER -> inplacemodificationWordWithVariable(targetVarName, target.datatype, operator, regName(value), value.datatype, block)
@ -268,6 +281,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
DataType.FLOAT -> {
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationFloatWithLiteralval(targetVarName, operator, value.boolean!!.asInt().toDouble())
SourceStorageKind.LITERALNUMBER -> inplacemodificationFloatWithLiteralval(targetVarName, operator, value.number!!.number)
SourceStorageKind.VARIABLE -> inplacemodificationFloatWithVariable(targetVarName, operator, value.asmVarname)
SourceStorageKind.REGISTER -> inplacemodificationFloatWithVariable(targetVarName, operator, regName(value))
@ -304,6 +318,10 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
asmgen.saveRegisterStack(CpuRegister.Y, false)
asmgen.out(" lda ${target.array.variable.name},y")
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> {
inplacemodificationRegisterAwithVariable(operator, "#${value.boolean!!.asInt()}", target.datatype in SignedDatatypes)
asmgen.restoreRegisterStack(CpuRegister.Y, true)
}
SourceStorageKind.LITERALNUMBER -> {
inplacemodificationRegisterAwithVariable(operator, "#${value.number!!.number.toInt()}", target.datatype in SignedDatatypes)
asmgen.restoreRegisterStack(CpuRegister.Y, true)
@ -363,6 +381,14 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
val block = target.origAstTarget?.definingBlock()
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> {
val number = value.boolean!!.asInt()
if(!inplacemodificationRegisterAXwithLiteralval(operator, number)) {
asmgen.out(" sta P8ZP_SCRATCH_W1 | stx P8ZP_SCRATCH_W1+1")
inplacemodificationWordWithLiteralval("P8ZP_SCRATCH_W1", target.datatype, operator, number, block)
asmgen.out(" lda P8ZP_SCRATCH_W1 | ldx P8ZP_SCRATCH_W1+1")
}
}
SourceStorageKind.LITERALNUMBER -> {
val number = value.number!!.number.toInt()
if(!inplacemodificationRegisterAXwithLiteralval(operator, number)) {
@ -446,6 +472,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
// calculate on tempvar
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationFloatWithLiteralval(tempvar, operator, value.boolean!!.asInt().toDouble())
SourceStorageKind.LITERALNUMBER -> inplacemodificationFloatWithLiteralval(tempvar, operator, value.number!!.number)
SourceStorageKind.VARIABLE -> inplacemodificationFloatWithVariable(tempvar, operator, value.asmVarname)
SourceStorageKind.REGISTER -> inplacemodificationFloatWithVariable(tempvar, operator, regName(value))
@ -953,7 +980,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
+ lda #1
+""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a pointer?
// pretty uncommon, who's going to assign a comparison boolean expression to a pointer?
"<", "<=", ">", ">=" -> TODO("byte-var-to-pointer comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
@ -1058,7 +1085,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
+""")
asmgen.storeAIntoZpPointerVar(sourceName, false)
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a pointer?:
// pretty uncommon, who's going to assign a comparison boolean expression to a pointer?:
"<", "<=", ">", ">=" -> TODO("byte-litval-to-pointer comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
@ -2400,7 +2427,7 @@ $shortcutLabel:""")
lda #0
sta $name+1""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a word var?:
// pretty uncommon, who's going to assign a comparison boolean expression to a word var?:
"<", "<=", ">", ">=" -> TODO("word-bytevar-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
@ -2827,7 +2854,7 @@ $shortcutLabel:""")
lda #0
sta $name+1""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a word var?:
// pretty uncommon, who's going to assign a comparison boolean expression to a word var?:
"<", "<=", ">", ">=" -> TODO("word-bytevalue-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
@ -2907,7 +2934,7 @@ $shortcutLabel:""")
lda #0
sta $name+1""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a word var?:
// pretty uncommon, who's going to assign a comparison boolean expression to a word var?:
"<", "<=", ">", ">=" -> TODO("word-value-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
@ -2947,7 +2974,7 @@ $shortcutLabel:""")
jsr floats.FDIV
""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a float var:
// pretty uncommon, who's going to assign a comparison boolean expression to a float var:
"==" -> TODO("float-value-to-var comparison ==")
"!=" -> TODO("float-value-to-var comparison !=")
"<", "<=", ">", ">=" -> TODO("float-value-to-var comparisons")
@ -3003,7 +3030,7 @@ $shortcutLabel:""")
jsr floats.FDIV
""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a float var:
// pretty uncommon, who's going to assign a comparison boolean expression to a float var:
"==" -> {
asmgen.out("""
lda #<$name

View File

@ -1,8 +1,8 @@
TODO
====
while not cx16.mouse_pos() should give error
merge last 2 codegen files from booleans-tryout branch: AssignmentAsmGen, ExpressionGen (everything else was merged)
ConstantFoldingOptimizer (after merging master):
after(numLiteral..) : check that cast to/from BOOL is not done??
@ -29,6 +29,7 @@ ok . type error for bool[3] derp = 99 and also for init value [1,0,1]
ok . while booleanvar==42 and do..until booleanvar==42 should give type error
ok . while not <integervar> should give type error
ok . while not <integer functioncall> should give type error
ok . while not cx16.mouse_pos() should give condition type error
ok . while boolean should produce identical code as while integer!=0
ok . while not boolvar -> can we get rid of the cmp? (6502 only?)
ok . if someint==0 / ==1 should stil produce good asm same as what it used to be with if not someint/if someint