mirror of
https://github.com/irmen/prog8.git
synced 2024-09-09 02:54:28 +00:00
clean up AugmentableAssignmentAsmGen a bit
This commit is contained in:
parent
9678bbae4b
commit
19a4bf1088
@ -68,58 +68,58 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
when (target.datatype) {
|
when (target.datatype) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_byte_litval_to_variable(target.asmVarname, target.datatype, operator, value.number!!.number.toInt())
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationByteVariableWithLiteralval(target.asmVarname, target.datatype, operator, value.number!!.number.toInt())
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_byte_variable_to_variable(target.asmVarname, target.datatype, operator, value.asmVarname)
|
SourceStorageKind.VARIABLE -> inplacemodificationByteVariableWithVariable(target.asmVarname, target.datatype, operator, value.asmVarname)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_byte_variable_to_variable(target.asmVarname, target.datatype, operator, regName(value))
|
SourceStorageKind.REGISTER -> inplacemodificationByteVariableWithVariable(target.asmVarname, target.datatype, operator, regName(value))
|
||||||
SourceStorageKind.MEMORY -> inplaceModification_byte_memread_to_variable(target.asmVarname, target.datatype, operator, value.memory!!)
|
SourceStorageKind.MEMORY -> inplacemodificationByteVariableWithValue(target.asmVarname, target.datatype, operator, value.memory!!)
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_byte_value_to_variable(target.asmVarname, target.datatype, operator, value.array!!)
|
SourceStorageKind.ARRAY -> inplacemodificationByteVariableWithValue(target.asmVarname, target.datatype, operator, value.array!!)
|
||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast) {
|
||||||
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
||||||
inplaceModification_byte_value_to_variable(target.asmVarname, target.datatype, operator, value.expression)
|
inplacemodificationByteVariableWithValue(target.asmVarname, target.datatype, operator, value.expression)
|
||||||
} else {
|
} else {
|
||||||
inplaceModification_byte_value_to_variable(target.asmVarname, target.datatype, operator, value.expression!!)
|
inplacemodificationByteVariableWithValue(target.asmVarname, target.datatype, operator, value.expression!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_word_litval_to_variable(target.asmVarname, target.datatype, operator, value.number!!.number.toInt())
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationWordWithLiteralval(target.asmVarname, target.datatype, operator, value.number!!.number.toInt())
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_word_variable_to_variable(target.asmVarname, target.datatype, operator, value.asmVarname, value.datatype)
|
SourceStorageKind.VARIABLE -> inplacemodificationWordWithVariable(target.asmVarname, target.datatype, operator, value.asmVarname, value.datatype)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_word_variable_to_variable(target.asmVarname, target.datatype, operator, regName(value), value.datatype)
|
SourceStorageKind.REGISTER -> inplacemodificationWordWithVariable(target.asmVarname, target.datatype, operator, regName(value), value.datatype)
|
||||||
SourceStorageKind.MEMORY -> inplaceModification_word_memread_to_variable(target.asmVarname, target.datatype, operator, value.memory!!)
|
SourceStorageKind.MEMORY -> inplacemodificationWordWithMemread(target.asmVarname, target.datatype, operator, value.memory!!)
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_word_value_to_variable(target.asmVarname, target.datatype, operator, value.array!!)
|
SourceStorageKind.ARRAY -> inplacemodificationWordWithValue(target.asmVarname, target.datatype, operator, value.array!!)
|
||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast) {
|
||||||
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
||||||
inplaceModification_word_value_to_variable(target.asmVarname, target.datatype, operator, value.expression)
|
inplacemodificationWordWithValue(target.asmVarname, target.datatype, operator, value.expression)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
inplaceModification_word_value_to_variable(target.asmVarname, target.datatype, operator, value.expression!!)
|
inplacemodificationWordWithValue(target.asmVarname, target.datatype, operator, value.expression!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_float_litval_to_variable(
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationFloatWithLiteralval(
|
||||||
target.asmVarname,
|
target.asmVarname,
|
||||||
operator,
|
operator,
|
||||||
value.number!!.number
|
value.number!!.number
|
||||||
)
|
)
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_float_variable_to_variable(
|
SourceStorageKind.VARIABLE -> inplacemodificationFloatWithVariable(
|
||||||
target.asmVarname,
|
target.asmVarname,
|
||||||
operator,
|
operator,
|
||||||
value.asmVarname
|
value.asmVarname
|
||||||
)
|
)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_float_variable_to_variable(
|
SourceStorageKind.REGISTER -> inplacemodificationFloatWithVariable(
|
||||||
target.asmVarname,
|
target.asmVarname,
|
||||||
operator,
|
operator,
|
||||||
regName(value)
|
regName(value)
|
||||||
)
|
)
|
||||||
SourceStorageKind.MEMORY -> TODO("memread into float")
|
SourceStorageKind.MEMORY -> TODO("memread into float")
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_float_value_to_variable(
|
SourceStorageKind.ARRAY -> inplacemodificationFloatWithValue(
|
||||||
target.asmVarname,
|
target.asmVarname,
|
||||||
operator,
|
operator,
|
||||||
value.array!!
|
value.array!!
|
||||||
@ -127,13 +127,13 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast) {
|
||||||
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
||||||
inplaceModification_float_value_to_variable(
|
inplacemodificationFloatWithValue(
|
||||||
target.asmVarname,
|
target.asmVarname,
|
||||||
operator,
|
operator,
|
||||||
value.expression
|
value.expression
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
inplaceModification_float_value_to_variable(
|
inplacemodificationFloatWithValue(
|
||||||
target.asmVarname,
|
target.asmVarname,
|
||||||
operator,
|
operator,
|
||||||
value.expression!!
|
value.expression!!
|
||||||
@ -151,17 +151,17 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
is PtNumber -> {
|
is PtNumber -> {
|
||||||
val addr = (memory.address as PtNumber).number.toInt()
|
val addr = (memory.address as PtNumber).number.toInt()
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_byte_litval_to_variable(addr.toHex(), DataType.UBYTE, operator, value.number!!.number.toInt())
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationByteVariableWithLiteralval(addr.toHex(), DataType.UBYTE, operator, value.number!!.number.toInt())
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_byte_variable_to_variable(addr.toHex(), DataType.UBYTE, operator, value.asmVarname)
|
SourceStorageKind.VARIABLE -> inplacemodificationByteVariableWithVariable(addr.toHex(), DataType.UBYTE, operator, value.asmVarname)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_byte_variable_to_variable(addr.toHex(), DataType.UBYTE, operator, regName(value))
|
SourceStorageKind.REGISTER -> inplacemodificationByteVariableWithVariable(addr.toHex(), DataType.UBYTE, operator, regName(value))
|
||||||
SourceStorageKind.MEMORY -> inplaceModification_byte_memread_to_variable(addr.toHex(), DataType.UBYTE, operator, value.memory!!)
|
SourceStorageKind.MEMORY -> inplacemodificationByteVariableWithValue(addr.toHex(), DataType.UBYTE, operator, value.memory!!)
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_byte_value_to_variable(addr.toHex(), DataType.UBYTE, operator, value.array!!)
|
SourceStorageKind.ARRAY -> inplacemodificationByteVariableWithValue(addr.toHex(), DataType.UBYTE, operator, value.array!!)
|
||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast) {
|
||||||
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
||||||
inplaceModification_byte_value_to_variable(addr.toHex(), DataType.UBYTE, operator, value.expression)
|
inplacemodificationByteVariableWithValue(addr.toHex(), DataType.UBYTE, operator, value.expression)
|
||||||
} else {
|
} else {
|
||||||
inplaceModification_byte_value_to_variable(addr.toHex(), DataType.UBYTE, operator, value.expression!!)
|
inplacemodificationByteVariableWithValue(addr.toHex(), DataType.UBYTE, operator, value.expression!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,17 +169,17 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
is PtIdentifier -> {
|
is PtIdentifier -> {
|
||||||
val pointer = memory.address as PtIdentifier
|
val pointer = memory.address as PtIdentifier
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_byte_litval_to_pointer(pointer, operator, value.number!!.number.toInt())
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationBytePointerWithLiteralval(pointer, operator, value.number!!.number.toInt())
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_byte_variable_to_pointer(pointer, operator, value.asmVarname)
|
SourceStorageKind.VARIABLE -> inplacemodificationBytePointerWithVariable(pointer, operator, value.asmVarname)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_byte_variable_to_pointer(pointer, operator, regName(value))
|
SourceStorageKind.REGISTER -> inplacemodificationBytePointerWithVariable(pointer, operator, regName(value))
|
||||||
SourceStorageKind.MEMORY -> TODO("memread into pointer")
|
SourceStorageKind.MEMORY -> TODO("memread into pointer")
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_byte_value_to_pointer(pointer, operator, value.array!!)
|
SourceStorageKind.ARRAY -> inplacemodificationBytePointerWithValue(pointer, operator, value.array!!)
|
||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast) {
|
||||||
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
||||||
inplaceModification_byte_value_to_pointer(pointer, operator, value.expression)
|
inplacemodificationBytePointerWithValue(pointer, operator, value.expression)
|
||||||
} else {
|
} else {
|
||||||
inplaceModification_byte_value_to_pointer(pointer, operator, value.expression!!)
|
inplacemodificationBytePointerWithValue(pointer, operator, value.expression!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,18 +189,18 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.saveRegisterStack(CpuRegister.A, true)
|
asmgen.saveRegisterStack(CpuRegister.A, true)
|
||||||
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
||||||
asmgen.out(" jsr prog8_lib.read_byte_from_address_in_AY | sta P8ZP_SCRATCH_B1")
|
asmgen.out(" jsr prog8_lib.read_byte_from_address_in_AY | sta P8ZP_SCRATCH_B1")
|
||||||
|
// TODO optimize the stuff below to not use temp variables??
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_byte_litval_to_variable("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.number!!.number.toInt())
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationByteVariableWithLiteralval("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.number!!.number.toInt())
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_byte_variable_to_variable("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.asmVarname)
|
SourceStorageKind.VARIABLE -> inplacemodificationByteVariableWithVariable("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.asmVarname)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_byte_variable_to_variable("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, regName(value))
|
SourceStorageKind.REGISTER -> inplacemodificationByteVariableWithVariable("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, regName(value))
|
||||||
SourceStorageKind.MEMORY -> inplaceModification_byte_memread_to_variable("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.memory!!)
|
SourceStorageKind.MEMORY -> inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.memory!!)
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_byte_value_to_variable("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.array!!)
|
SourceStorageKind.ARRAY -> inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.array!!)
|
||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast)
|
||||||
inplaceModification_byte_value_to_variable("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.expression)
|
inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.expression)
|
||||||
} else {
|
else
|
||||||
inplaceModification_byte_value_to_variable("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.expression!!)
|
inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.expression!!)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
asmgen.restoreRegisterStack(CpuRegister.Y, false)
|
asmgen.restoreRegisterStack(CpuRegister.Y, false)
|
||||||
@ -221,57 +221,57 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
when (target.datatype) {
|
when (target.datatype) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_byte_litval_to_variable(targetVarName, target.datatype, operator, value.number!!.number.toInt())
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationByteVariableWithLiteralval(targetVarName, target.datatype, operator, value.number!!.number.toInt())
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_byte_variable_to_variable(targetVarName, target.datatype, operator, value.asmVarname)
|
SourceStorageKind.VARIABLE -> inplacemodificationByteVariableWithVariable(targetVarName, target.datatype, operator, value.asmVarname)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_byte_variable_to_variable(targetVarName, target.datatype, operator, regName(value))
|
SourceStorageKind.REGISTER -> inplacemodificationByteVariableWithVariable(targetVarName, target.datatype, operator, regName(value))
|
||||||
SourceStorageKind.MEMORY -> inplaceModification_byte_memread_to_variable(targetVarName, target.datatype, operator, value.memory!!)
|
SourceStorageKind.MEMORY -> inplacemodificationByteVariableWithValue(targetVarName, target.datatype, operator, value.memory!!)
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_byte_value_to_variable(targetVarName, target.datatype, operator, value.array!!)
|
SourceStorageKind.ARRAY -> inplacemodificationByteVariableWithValue(targetVarName, target.datatype, operator, value.array!!)
|
||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast) {
|
||||||
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
||||||
inplaceModification_byte_value_to_variable(targetVarName, target.datatype, operator, value.expression)
|
inplacemodificationByteVariableWithValue(targetVarName, target.datatype, operator, value.expression)
|
||||||
} else {
|
} else {
|
||||||
inplaceModification_byte_value_to_variable(targetVarName, target.datatype, operator, value.expression!!)
|
inplacemodificationByteVariableWithValue(targetVarName, target.datatype, operator, value.expression!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_word_litval_to_variable(targetVarName, target.datatype, operator, value.number!!.number.toInt())
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationWordWithLiteralval(targetVarName, target.datatype, operator, value.number!!.number.toInt())
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_word_variable_to_variable(targetVarName, target.datatype, operator, value.asmVarname, value.datatype)
|
SourceStorageKind.VARIABLE -> inplacemodificationWordWithVariable(targetVarName, target.datatype, operator, value.asmVarname, value.datatype)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_word_variable_to_variable(targetVarName, target.datatype, operator, regName(value), value.datatype)
|
SourceStorageKind.REGISTER -> inplacemodificationWordWithVariable(targetVarName, target.datatype, operator, regName(value), value.datatype)
|
||||||
SourceStorageKind.MEMORY -> inplaceModification_word_memread_to_variable(targetVarName, target.datatype, operator, value.memory!!)
|
SourceStorageKind.MEMORY -> inplacemodificationWordWithMemread(targetVarName, target.datatype, operator, value.memory!!)
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_word_value_to_variable(targetVarName, target.datatype, operator, value.array!!)
|
SourceStorageKind.ARRAY -> inplacemodificationWordWithValue(targetVarName, target.datatype, operator, value.array!!)
|
||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast) {
|
||||||
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
||||||
inplaceModification_word_value_to_variable(targetVarName, target.datatype, operator, value.expression)
|
inplacemodificationWordWithValue(targetVarName, target.datatype, operator, value.expression)
|
||||||
} else {
|
} else {
|
||||||
inplaceModification_word_value_to_variable(targetVarName, target.datatype, operator, value.expression!!)
|
inplacemodificationWordWithValue(targetVarName, target.datatype, operator, value.expression!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_float_litval_to_variable(
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationFloatWithLiteralval(
|
||||||
targetVarName,
|
targetVarName,
|
||||||
operator,
|
operator,
|
||||||
value.number!!.number
|
value.number!!.number
|
||||||
)
|
)
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_float_variable_to_variable(
|
SourceStorageKind.VARIABLE -> inplacemodificationFloatWithVariable(
|
||||||
targetVarName,
|
targetVarName,
|
||||||
operator,
|
operator,
|
||||||
value.asmVarname
|
value.asmVarname
|
||||||
)
|
)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_float_variable_to_variable(
|
SourceStorageKind.REGISTER -> inplacemodificationFloatWithVariable(
|
||||||
targetVarName,
|
targetVarName,
|
||||||
operator,
|
operator,
|
||||||
regName(value)
|
regName(value)
|
||||||
)
|
)
|
||||||
SourceStorageKind.MEMORY -> TODO("memread into float array")
|
SourceStorageKind.MEMORY -> TODO("memread into float array")
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_float_value_to_variable(
|
SourceStorageKind.ARRAY -> inplacemodificationFloatWithValue(
|
||||||
targetVarName,
|
targetVarName,
|
||||||
operator,
|
operator,
|
||||||
value.array!!
|
value.array!!
|
||||||
@ -279,13 +279,13 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast) {
|
||||||
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
|
||||||
inplaceModification_float_value_to_variable(
|
inplacemodificationFloatWithValue(
|
||||||
targetVarName,
|
targetVarName,
|
||||||
operator,
|
operator,
|
||||||
value.expression
|
value.expression
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
inplaceModification_float_value_to_variable(
|
inplacemodificationFloatWithValue(
|
||||||
targetVarName,
|
targetVarName,
|
||||||
operator,
|
operator,
|
||||||
value.expression!!
|
value.expression!!
|
||||||
@ -307,18 +307,18 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UBYTE, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UBYTE, CpuRegister.Y)
|
||||||
asmgen.out(" lda ${target.array.variable.name},y | sta P8ZP_SCRATCH_B1")
|
asmgen.out(" lda ${target.array.variable.name},y | sta P8ZP_SCRATCH_B1")
|
||||||
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
||||||
|
// TODO optimize the stuff below to not use temp variables??
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_byte_litval_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, value.number!!.number.toInt())
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationByteVariableWithLiteralval("P8ZP_SCRATCH_B1", target.datatype, operator, value.number!!.number.toInt())
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_byte_variable_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, value.asmVarname)
|
SourceStorageKind.VARIABLE -> inplacemodificationByteVariableWithVariable("P8ZP_SCRATCH_B1", target.datatype, operator, value.asmVarname)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_byte_variable_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, regName(value))
|
SourceStorageKind.REGISTER -> inplacemodificationByteVariableWithVariable("P8ZP_SCRATCH_B1", target.datatype, operator, regName(value))
|
||||||
SourceStorageKind.MEMORY -> inplaceModification_byte_memread_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, value.memory!!)
|
SourceStorageKind.MEMORY -> inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", target.datatype, operator, value.memory!!)
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_byte_value_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, value.array!!)
|
SourceStorageKind.ARRAY -> inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", target.datatype, operator, value.array!!)
|
||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast)
|
||||||
inplaceModification_byte_value_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, value.expression)
|
inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", target.datatype, operator, value.expression)
|
||||||
} else {
|
else
|
||||||
inplaceModification_byte_value_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, value.expression!!)
|
inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", target.datatype, operator, value.expression!!)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
asmgen.restoreRegisterStack(CpuRegister.Y, false)
|
asmgen.restoreRegisterStack(CpuRegister.Y, false)
|
||||||
@ -338,18 +338,18 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" lda ${target.array.variable.name}+1,y | sta P8ZP_SCRATCH_W1+1")
|
asmgen.out(" lda ${target.array.variable.name}+1,y | sta P8ZP_SCRATCH_W1+1")
|
||||||
}
|
}
|
||||||
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
||||||
|
// TODO optimize the stuff below to not use temp variables??
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_word_litval_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, value.number!!.number.toInt())
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationWordWithLiteralval("P8ZP_SCRATCH_W1", target.datatype, operator, value.number!!.number.toInt())
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_word_variable_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, value.asmVarname, value.datatype)
|
SourceStorageKind.VARIABLE -> inplacemodificationWordWithVariable("P8ZP_SCRATCH_W1", target.datatype, operator, value.asmVarname, value.datatype)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_word_variable_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, regName(value), value.datatype)
|
SourceStorageKind.REGISTER -> inplacemodificationWordWithVariable("P8ZP_SCRATCH_W1", target.datatype, operator, regName(value), value.datatype)
|
||||||
SourceStorageKind.MEMORY -> inplaceModification_word_memread_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, value.memory!!)
|
SourceStorageKind.MEMORY -> inplacemodificationWordWithMemread("P8ZP_SCRATCH_W1", target.datatype, operator, value.memory!!)
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_word_value_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, value.array!!)
|
SourceStorageKind.ARRAY -> inplacemodificationWordWithValue("P8ZP_SCRATCH_W1", target.datatype, operator, value.array!!)
|
||||||
SourceStorageKind.EXPRESSION -> {
|
SourceStorageKind.EXPRESSION -> {
|
||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast)
|
||||||
inplaceModification_word_value_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, value.expression)
|
inplacemodificationWordWithValue("P8ZP_SCRATCH_W1", target.datatype, operator, value.expression)
|
||||||
} else {
|
else
|
||||||
inplaceModification_word_value_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, value.expression!!)
|
inplacemodificationWordWithValue("P8ZP_SCRATCH_W1", target.datatype, operator, value.expression!!)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
asmgen.restoreRegisterStack(CpuRegister.Y, false)
|
asmgen.restoreRegisterStack(CpuRegister.Y, false)
|
||||||
@ -376,23 +376,23 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
ldy #>$tempvar
|
ldy #>$tempvar
|
||||||
jsr floats.copy_float""") // copy from array into float temp var, clobbers A,Y
|
jsr floats.copy_float""") // copy from array into float temp var, clobbers A,Y
|
||||||
when(value.kind) {
|
when(value.kind) {
|
||||||
SourceStorageKind.LITERALNUMBER -> inplaceModification_float_litval_to_variable(
|
SourceStorageKind.LITERALNUMBER -> inplacemodificationFloatWithLiteralval(
|
||||||
tempvar,
|
tempvar,
|
||||||
operator,
|
operator,
|
||||||
value.number!!.number
|
value.number!!.number
|
||||||
)
|
)
|
||||||
SourceStorageKind.VARIABLE -> inplaceModification_float_variable_to_variable(
|
SourceStorageKind.VARIABLE -> inplacemodificationFloatWithVariable(
|
||||||
tempvar,
|
tempvar,
|
||||||
operator,
|
operator,
|
||||||
value.asmVarname
|
value.asmVarname
|
||||||
)
|
)
|
||||||
SourceStorageKind.REGISTER -> inplaceModification_float_variable_to_variable(
|
SourceStorageKind.REGISTER -> inplacemodificationFloatWithVariable(
|
||||||
tempvar,
|
tempvar,
|
||||||
operator,
|
operator,
|
||||||
regName(value)
|
regName(value)
|
||||||
)
|
)
|
||||||
SourceStorageKind.MEMORY -> TODO("memread into float")
|
SourceStorageKind.MEMORY -> TODO("memread into float")
|
||||||
SourceStorageKind.ARRAY -> inplaceModification_float_value_to_variable(
|
SourceStorageKind.ARRAY -> inplacemodificationFloatWithValue(
|
||||||
tempvar,
|
tempvar,
|
||||||
operator,
|
operator,
|
||||||
value.array!!
|
value.array!!
|
||||||
@ -401,13 +401,13 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
if(value.expression is PtTypeCast) {
|
if(value.expression is PtTypeCast) {
|
||||||
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator))
|
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator))
|
||||||
return
|
return
|
||||||
inplaceModification_float_value_to_variable(
|
inplacemodificationFloatWithValue(
|
||||||
tempvar,
|
tempvar,
|
||||||
operator,
|
operator,
|
||||||
value.expression
|
value.expression
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
inplaceModification_float_value_to_variable(
|
inplacemodificationFloatWithValue(
|
||||||
tempvar,
|
tempvar,
|
||||||
operator,
|
operator,
|
||||||
value.expression!!
|
value.expression!!
|
||||||
@ -452,62 +452,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_value_to_pointer(pointervar: PtIdentifier, operator: String, value: PtExpression) {
|
private fun inplacemodificationBytePointerWithValue(pointervar: PtIdentifier, operator: String, value: PtExpression) {
|
||||||
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", DataType.UBYTE)
|
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", DataType.UBYTE)
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
inplacemodificationBytePointerWithVariable(pointervar, operator, "P8ZP_SCRATCH_B1")
|
||||||
when (operator) {
|
|
||||||
"+" -> asmgen.out(" clc | adc P8ZP_SCRATCH_B1")
|
|
||||||
"-" -> asmgen.out(" sec | sbc P8ZP_SCRATCH_B1")
|
|
||||||
"*" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.multiply_bytes")
|
|
||||||
"/" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.divmod_ub_asm | tya")
|
|
||||||
"%" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.divmod_ub_asm")
|
|
||||||
"<<" -> {
|
|
||||||
asmgen.out("""
|
|
||||||
ldy P8ZP_SCRATCH_B1
|
|
||||||
beq +
|
|
||||||
- asl a
|
|
||||||
dey
|
|
||||||
bne -
|
|
||||||
+""")
|
|
||||||
}
|
|
||||||
">>" -> {
|
|
||||||
asmgen.out("""
|
|
||||||
ldy P8ZP_SCRATCH_B1
|
|
||||||
beq +
|
|
||||||
- lsr a
|
|
||||||
dey
|
|
||||||
bne -
|
|
||||||
+""")
|
|
||||||
}
|
|
||||||
"&" -> asmgen.out(" and P8ZP_SCRATCH_B1")
|
|
||||||
"|" -> asmgen.out(" ora P8ZP_SCRATCH_B1")
|
|
||||||
"^" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
|
|
||||||
"==" -> {
|
|
||||||
asmgen.out("""
|
|
||||||
cmp P8ZP_SCRATCH_B1
|
|
||||||
beq +
|
|
||||||
lda #0
|
|
||||||
beq ++
|
|
||||||
+ lda #1
|
|
||||||
+""")
|
|
||||||
}
|
|
||||||
"!=" -> {
|
|
||||||
asmgen.out("""
|
|
||||||
cmp P8ZP_SCRATCH_B1
|
|
||||||
bne +
|
|
||||||
lda #0
|
|
||||||
beq ++
|
|
||||||
+ lda #1
|
|
||||||
+""")
|
|
||||||
}
|
|
||||||
// pretty uncommon, who's going to assign a comparison boolean expresion to a pointer:
|
|
||||||
"<", "<=", ">", ">=" -> TODO("byte-value-to-pointer comparisons")
|
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
|
||||||
}
|
|
||||||
asmgen.storeAIntoZpPointerVar(sourceName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_variable_to_pointer(pointervar: PtIdentifier, operator: String, otherName: String) {
|
private fun inplacemodificationBytePointerWithVariable(pointervar: PtIdentifier, operator: String, otherName: String) {
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
|
|
||||||
when (operator) {
|
when (operator) {
|
||||||
@ -562,7 +512,8 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.storeAIntoZpPointerVar(sourceName)
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_litval_to_pointer(pointervar: PtIdentifier, operator: String, value: Int) {
|
private fun inplacemodificationBytePointerWithLiteralval(pointervar: PtIdentifier, operator: String, value: Int) {
|
||||||
|
// note: this contains special optimized cases because we know the exact value. Don't replace this with another routine.
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"+" -> {
|
"+" -> {
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
@ -653,297 +604,184 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_value_to_variable(name: String, dt: DataType, operator: String, value: PtExpression) {
|
private fun inplacemodificationByteVariableWithValue(name: String, dt: DataType, operator: String, value: PtExpression) {
|
||||||
when (operator) {
|
// TODO optimize the stuff below to not use temp variables??
|
||||||
"+" -> {
|
val tmpVar = if(name!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG"
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
asmgen.assignExpressionToVariable(value, tmpVar, value.type)
|
||||||
asmgen.out(" clc | adc $name | sta $name")
|
asmgen.out(" lda $name")
|
||||||
}
|
inplacemodificationRegisterAwithVariable(operator, tmpVar, dt in SignedDatatypes)
|
||||||
"-" -> {
|
asmgen.out(" sta $name")
|
||||||
val tmpByte = if(name!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG"
|
|
||||||
asmgen.assignExpressionToVariable(value, tmpByte, dt)
|
|
||||||
asmgen.out(" lda $name | sec | sbc $tmpByte | sta $name")
|
|
||||||
}
|
|
||||||
"*" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
|
||||||
asmgen.out(" ldy $name | jsr math.multiply_bytes | sta $name")
|
|
||||||
}
|
|
||||||
"/" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.Y)
|
|
||||||
if(dt==DataType.UBYTE)
|
|
||||||
asmgen.out(" lda $name | jsr math.divmod_ub_asm | sty $name")
|
|
||||||
else
|
|
||||||
asmgen.out(" lda $name | jsr math.divmod_b_asm | sty $name")
|
|
||||||
}
|
|
||||||
"%" -> {
|
|
||||||
if(dt==DataType.BYTE)
|
|
||||||
throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.Y)
|
|
||||||
asmgen.out(" lda $name | jsr math.divmod_ub_asm | sta $name")
|
|
||||||
}
|
|
||||||
"<<" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.Y)
|
|
||||||
asmgen.out("""
|
|
||||||
beq +
|
|
||||||
- asl $name
|
|
||||||
dey
|
|
||||||
bne -
|
|
||||||
+""")
|
|
||||||
}
|
|
||||||
">>" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.Y)
|
|
||||||
if(dt==DataType.UBYTE) {
|
|
||||||
asmgen.out("""
|
|
||||||
beq +
|
|
||||||
- lsr $name
|
|
||||||
dey
|
|
||||||
bne -
|
|
||||||
+""")
|
|
||||||
} else {
|
|
||||||
asmgen.out("""
|
|
||||||
beq +
|
|
||||||
- lda $name
|
|
||||||
asl a
|
|
||||||
ror $name
|
|
||||||
dey
|
|
||||||
bne -
|
|
||||||
+""")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"&" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
|
||||||
asmgen.out(" and $name | sta $name")
|
|
||||||
}
|
|
||||||
"|" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
|
||||||
asmgen.out(" ora $name | sta $name")
|
|
||||||
}
|
|
||||||
"^" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
|
||||||
asmgen.out(" eor $name | sta $name")
|
|
||||||
}
|
|
||||||
"==" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
|
||||||
asmgen.out("""
|
|
||||||
cmp $name
|
|
||||||
beq +
|
|
||||||
lda #0
|
|
||||||
beq ++
|
|
||||||
+ lda #1
|
|
||||||
+ sta $name""")
|
|
||||||
}
|
|
||||||
"!=" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
|
||||||
asmgen.out("""
|
|
||||||
cmp $name
|
|
||||||
beq +
|
|
||||||
lda #1
|
|
||||||
bne ++
|
|
||||||
+ lda #0
|
|
||||||
+ sta $name""")
|
|
||||||
}
|
|
||||||
"<" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
|
||||||
if(dt==DataType.UBYTE)
|
|
||||||
TODO("ubyte <")
|
|
||||||
else
|
|
||||||
TODO("byte <")
|
|
||||||
}
|
|
||||||
"<=" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
|
||||||
if(dt==DataType.UBYTE)
|
|
||||||
TODO("ubyte <=")
|
|
||||||
else
|
|
||||||
TODO("byte <=")
|
|
||||||
}
|
|
||||||
">" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
|
||||||
if(dt==DataType.UBYTE)
|
|
||||||
TODO("ubyte >")
|
|
||||||
else
|
|
||||||
TODO("byte >")
|
|
||||||
}
|
|
||||||
">=" -> {
|
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
|
||||||
if(dt==DataType.UBYTE)
|
|
||||||
TODO("ubyte >=")
|
|
||||||
else
|
|
||||||
TODO("byte >=")
|
|
||||||
}
|
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_variable_to_variable(name: String, dt: DataType, operator: String, otherName: String) {
|
private fun inplacemodificationByteVariableWithVariable(name: String, dt: DataType, operator: String, otherName: String) {
|
||||||
|
asmgen.out(" lda $name")
|
||||||
|
inplacemodificationRegisterAwithVariable(operator, otherName, dt in SignedDatatypes)
|
||||||
|
asmgen.out(" sta $name")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: optimization: use this directly in more places, rather than using a temporary variable
|
||||||
|
private fun inplacemodificationRegisterAwithVariable(operator: String, variable: String, signed: Boolean) {
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"+" -> asmgen.out(" lda $name | clc | adc $otherName | sta $name")
|
"+" -> asmgen.out(" clc | adc $variable")
|
||||||
"-" -> asmgen.out(" lda $name | sec | sbc $otherName | sta $name")
|
"-" -> asmgen.out(" sec | sbc $variable")
|
||||||
"*" -> asmgen.out(" lda $name | ldy $otherName | jsr math.multiply_bytes | sta $name")
|
"*" -> asmgen.out(" ldy $variable | jsr math.multiply_bytes")
|
||||||
"/" -> {
|
"/" -> {
|
||||||
if(dt==DataType.BYTE) {
|
if(signed)
|
||||||
asmgen.out(" lda $name | ldy $otherName | jsr math.divmod_b_asm | sty $name")
|
asmgen.out(" ldy $variable | jsr math.divmod_b_asm | tya")
|
||||||
}
|
else
|
||||||
else {
|
asmgen.out(" ldy $variable | jsr math.divmod_ub_asm | tya")
|
||||||
asmgen.out(" lda $name | ldy $otherName | jsr math.divmod_ub_asm | sty $name")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"%" -> {
|
"%" -> {
|
||||||
if(dt==DataType.BYTE)
|
if(signed)
|
||||||
throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
||||||
asmgen.out(" lda $name | ldy $otherName | jsr math.divmod_ub_asm | sta $name")
|
asmgen.out(" ldy $variable | jsr math.divmod_ub_asm")
|
||||||
}
|
}
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $otherName
|
ldy $variable
|
||||||
beq +
|
beq +
|
||||||
- asl $name
|
- asl a
|
||||||
dey
|
dey
|
||||||
bne -
|
bne -
|
||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
">>" -> {
|
">>" -> {
|
||||||
if(dt==DataType.UBYTE) {
|
if(!signed) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $otherName
|
ldy $variable
|
||||||
beq +
|
beq +
|
||||||
- lsr $name
|
- lsr a
|
||||||
dey
|
dey
|
||||||
bne -
|
bne -
|
||||||
+""")
|
+""")
|
||||||
} else {
|
} else {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $otherName
|
ldy $variable
|
||||||
beq +
|
beq +
|
||||||
- lda $name
|
sta P8ZP_SCRATCH_B1
|
||||||
asl a
|
- asl a
|
||||||
ror $name
|
ror P8ZP_SCRATCH_B1
|
||||||
|
lda P8ZP_SCRATCH_B1
|
||||||
dey
|
dey
|
||||||
bne -
|
bne -
|
||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"&" -> asmgen.out(" lda $name | and $otherName | sta $name")
|
"&" -> asmgen.out(" and $variable")
|
||||||
"|" -> asmgen.out(" lda $name | ora $otherName | sta $name")
|
"|" -> asmgen.out(" ora $variable")
|
||||||
"^" -> asmgen.out(" lda $name | eor $otherName | sta $name")
|
"^" -> asmgen.out(" eor $variable")
|
||||||
"==" -> {
|
"==" -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $otherName
|
cmp $variable
|
||||||
cmp $name
|
|
||||||
beq +
|
beq +
|
||||||
lda #0
|
lda #0
|
||||||
beq ++
|
beq ++
|
||||||
+ lda #1
|
+ lda #1
|
||||||
+ sta $name""")
|
+""")
|
||||||
}
|
}
|
||||||
"!=" -> {
|
"!=" -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $otherName
|
cmp $variable
|
||||||
cmp $name
|
|
||||||
beq +
|
beq +
|
||||||
lda #1
|
lda #1
|
||||||
bne ++
|
bne ++
|
||||||
+ lda #0
|
+ lda #0
|
||||||
+ sta $name""")
|
+""")
|
||||||
}
|
}
|
||||||
"<" -> {
|
"<" -> {
|
||||||
if(dt==DataType.UBYTE) {
|
if(!signed) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
|
tay
|
||||||
lda #0
|
lda #0
|
||||||
ldy $name
|
cpy $variable
|
||||||
cpy $otherName
|
|
||||||
rol a
|
rol a
|
||||||
eor #1
|
eor #1""")
|
||||||
sta $name""")
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// see http://www.6502.org/tutorials/compare_beyond.html
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $name
|
|
||||||
sec
|
sec
|
||||||
sbc $otherName
|
sbc $variable
|
||||||
bvc +
|
bvc +
|
||||||
eor #$80
|
eor #$80
|
||||||
+ bmi +
|
+ bmi +
|
||||||
lda #0
|
lda #0
|
||||||
beq ++
|
beq ++
|
||||||
+ lda #1
|
+ lda #1
|
||||||
+ sta $name""")
|
+""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"<=" -> {
|
"<=" -> {
|
||||||
if(dt==DataType.UBYTE) {
|
if(!signed) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
|
tay
|
||||||
lda #0
|
lda #0
|
||||||
ldy $otherName
|
ldy $variable
|
||||||
cpy $name
|
rol a""")
|
||||||
rol a
|
|
||||||
sta $name""")
|
|
||||||
} else {
|
} else {
|
||||||
// see http://www.6502.org/tutorials/compare_beyond.html
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $name
|
|
||||||
clc
|
clc
|
||||||
sbc $otherName
|
sbc $variable
|
||||||
bvc +
|
bvc +
|
||||||
eor #$80
|
eor #$80
|
||||||
+ bmi +
|
+ bmi +
|
||||||
lda #0
|
lda #0
|
||||||
beq ++
|
beq ++
|
||||||
+ lda #1
|
+ lda #1
|
||||||
+ sta $name""")
|
+""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">" -> {
|
">" -> {
|
||||||
if(dt==DataType.UBYTE) {
|
if(!signed) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
|
tay
|
||||||
lda #0
|
lda #0
|
||||||
ldy $name
|
cpy $variable
|
||||||
cpy $otherName
|
|
||||||
beq +
|
beq +
|
||||||
rol a
|
rol a
|
||||||
+ sta $name""")
|
+""")
|
||||||
} else {
|
} else {
|
||||||
// see http://www.6502.org/tutorials/compare_beyond.html
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $name
|
|
||||||
clc
|
clc
|
||||||
sbc $otherName
|
sbc $variable
|
||||||
bvc +
|
bvc +
|
||||||
eor #$80
|
eor #$80
|
||||||
+ bpl +
|
+ bpl +
|
||||||
lda #0
|
lda #0
|
||||||
beq ++
|
beq ++
|
||||||
+ lda #1
|
+ lda #1
|
||||||
+ sta $name""")
|
+""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">=" -> {
|
">=" -> {
|
||||||
if(dt==DataType.UBYTE) {
|
if(!signed) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
|
tay
|
||||||
lda #0
|
lda #0
|
||||||
ldy $name
|
cpy $variable
|
||||||
cpy $otherName
|
rol a""")
|
||||||
rol a
|
|
||||||
sta $name""")
|
|
||||||
} else {
|
} else {
|
||||||
// see http://www.6502.org/tutorials/compare_beyond.html
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $name
|
|
||||||
sec
|
sec
|
||||||
sbc $otherName
|
sbc $variable
|
||||||
bvc +
|
bvc +
|
||||||
eor #$80
|
eor #$80
|
||||||
+ bpl +
|
+ bpl +
|
||||||
lda #0
|
lda #0
|
||||||
beq ++
|
beq ++
|
||||||
+ lda #1
|
+ lda #1
|
||||||
+ sta $name""")
|
+""")
|
||||||
} }
|
}
|
||||||
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_litval_to_variable(name: String, dt: DataType, operator: String, value: Int) {
|
private fun inplacemodificationByteVariableWithLiteralval(name: String, dt: DataType, operator: String, value: Int) {
|
||||||
|
// note: this contains special optimized cases because we know the exact value. Don't replace this with another routine.
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"+" -> asmgen.out(" lda $name | clc | adc #$value | sta $name")
|
"+" -> asmgen.out(" lda $name | clc | adc #$value | sta $name")
|
||||||
"-" -> asmgen.out(" lda $name | sec | sbc #$value | sta $name")
|
"-" -> asmgen.out(" lda $name | sec | sbc #$value | sta $name")
|
||||||
@ -1128,44 +966,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_memread_to_variable(name: String, dt: DataType, operator: String, memread: PtMemoryByte) {
|
private fun inplacemodificationWordWithMemread(name: String, dt: DataType, operator: String, memread: PtMemoryByte) {
|
||||||
when (operator) {
|
|
||||||
"+" -> {
|
|
||||||
asmgen.translateDirectMemReadExpressionToRegA(memread)
|
|
||||||
asmgen.out("""
|
|
||||||
clc
|
|
||||||
adc $name
|
|
||||||
sta $name""")
|
|
||||||
}
|
|
||||||
"-" -> {
|
|
||||||
asmgen.translateDirectMemReadExpressionToRegA(memread)
|
|
||||||
val tmpByte = if(name!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG"
|
|
||||||
asmgen.out("""
|
|
||||||
sta $tmpByte
|
|
||||||
lda $name
|
|
||||||
sec
|
|
||||||
sbc $tmpByte
|
|
||||||
sta $name""")
|
|
||||||
}
|
|
||||||
"|" -> {
|
|
||||||
asmgen.translateDirectMemReadExpressionToRegA(memread)
|
|
||||||
asmgen.out(" ora $name | sta $name")
|
|
||||||
}
|
|
||||||
"&" -> {
|
|
||||||
asmgen.translateDirectMemReadExpressionToRegA(memread)
|
|
||||||
asmgen.out(" and $name | sta $name")
|
|
||||||
}
|
|
||||||
"^" -> {
|
|
||||||
asmgen.translateDirectMemReadExpressionToRegA(memread)
|
|
||||||
asmgen.out(" eor $name | sta $name")
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
inplaceModification_byte_value_to_variable(name, dt, operator, memread)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun inplaceModification_word_memread_to_variable(name: String, dt: DataType, operator: String, memread: PtMemoryByte) {
|
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"+" -> {
|
"+" -> {
|
||||||
asmgen.translateDirectMemReadExpressionToRegA(memread)
|
asmgen.translateDirectMemReadExpressionToRegA(memread)
|
||||||
@ -1209,12 +1010,13 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" eor $name | sta $name")
|
asmgen.out(" eor $name | sta $name")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
inplaceModification_word_value_to_variable(name, dt, operator, memread)
|
inplacemodificationWordWithValue(name, dt, operator, memread)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_word_litval_to_variable(name: String, dt: DataType, operator: String, value: Int) {
|
private fun inplacemodificationWordWithLiteralval(name: String, dt: DataType, operator: String, value: Int) {
|
||||||
|
// note: this contains special optimized cases because we know the exact value. Don't replace this with another routine.
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"+" -> {
|
"+" -> {
|
||||||
when {
|
when {
|
||||||
@ -1672,7 +1474,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_word_variable_to_variable(name: String, dt: DataType, operator: String, otherName: String, valueDt: DataType) {
|
private fun inplacemodificationWordWithVariable(name: String, dt: DataType, operator: String, otherName: String, valueDt: DataType) {
|
||||||
when (valueDt) {
|
when (valueDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
// the other variable is a BYTE type so optimize for that
|
// the other variable is a BYTE type so optimize for that
|
||||||
@ -2057,7 +1859,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_word_value_to_variable(name: String, dt: DataType, operator: String, value: PtExpression) {
|
private fun inplacemodificationWordWithValue(name: String, dt: DataType, operator: String, value: PtExpression) {
|
||||||
fun multiplyVarByWordInAY() {
|
fun multiplyVarByWordInAY() {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
sta P8ZP_SCRATCH_W1
|
sta P8ZP_SCRATCH_W1
|
||||||
@ -2270,7 +2072,6 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
val tmpWord = if(name!="P8ZP_SCRATCH_W1") "P8ZP_SCRATCH_W1" else "P8ZP_SCRATCH_W2"
|
val tmpWord = if(name!="P8ZP_SCRATCH_W1") "P8ZP_SCRATCH_W1" else "P8ZP_SCRATCH_W2"
|
||||||
asmgen.assignExpressionToVariable(value, tmpWord, valueDt)
|
asmgen.assignExpressionToVariable(value, tmpWord, valueDt)
|
||||||
asmgen.out(" lda $name | sec | sbc $tmpWord | sta $name | lda $name+1 | sbc $tmpWord+1 | sta $name+1")
|
asmgen.out(" lda $name | sec | sbc $tmpWord | sta $name | lda $name+1 | sbc $tmpWord+1 | sta $name+1")
|
||||||
// TODO wrong signed word subtraction code??? ^^^
|
|
||||||
}
|
}
|
||||||
"*" -> {
|
"*" -> {
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||||
@ -2344,7 +2145,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_float_value_to_variable(name: String, operator: String, value: PtExpression) {
|
private fun inplacemodificationFloatWithValue(name: String, operator: String, value: PtExpression) {
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.FAC1)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.FAC1)
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"+" -> {
|
"+" -> {
|
||||||
@ -2389,7 +2190,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_float_variable_to_variable(name: String, operator: String, otherName: String) {
|
private fun inplacemodificationFloatWithVariable(name: String, operator: String, otherName: String) {
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"+" -> {
|
"+" -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -2503,7 +2304,8 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_float_litval_to_variable(name: String, operator: String, value: Double) {
|
private fun inplacemodificationFloatWithLiteralval(name: String, operator: String, value: Double) {
|
||||||
|
// note: this contains special optimized cases because we know the exact value. Don't replace this with another routine.
|
||||||
val constValueName = allocator.getFloatAsmConst(value)
|
val constValueName = allocator.getFloatAsmConst(value)
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"+" -> {
|
"+" -> {
|
||||||
|
@ -44,7 +44,7 @@ romsub $fe21 = FMULTT() clobbers(A,X,Y) ; fac1 *= fac2
|
|||||||
romsub $fe24 = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1
|
romsub $fe24 = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1
|
||||||
romsub $fe27 = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 mind the order of the operands
|
romsub $fe27 = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 mind the order of the operands
|
||||||
romsub $fe2a = LOG() clobbers(A,X,Y) ; fac1 = LN(fac1) (natural log)
|
romsub $fe2a = LOG() clobbers(A,X,Y) ; fac1 = LN(fac1) (natural log)
|
||||||
romsub $fe2d = INT() clobbers(A,X,Y) ; INT() truncates, use FADDH first to round instead of trunc
|
romsub $fe2d = INT() clobbers(A,X,Y) ; INT() truncates, use ROUND or FADDH first to round instead of trunc
|
||||||
romsub $fe30 = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1)
|
romsub $fe30 = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1)
|
||||||
romsub $fe33 = NEGOP() clobbers(A) ; switch the sign of fac1 (fac1 = -fac1)
|
romsub $fe33 = NEGOP() clobbers(A) ; switch the sign of fac1 (fac1 = -fac1)
|
||||||
romsub $fe36 = FPWR(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = fac2 ** float in A/Y
|
romsub $fe36 = FPWR(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = fac2 ** float in A/Y
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- try to reduce the number of uses of temp variables for example in array[idx] -= amount /
|
- try to reduce the number of uses of temp variables for example in array[idx] -= amount see AugmentableAssignmentAsmGen
|
||||||
- investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... / - investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
- investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... / - investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
||||||
|
|
||||||
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
|
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
%import textio
|
%import textio
|
||||||
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
const ubyte ATTR_FALLING=$04
|
|
||||||
const ubyte ATTRF_EATABLE=$80
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
void test(10,20)
|
ubyte[10] array
|
||||||
}
|
ubyte idx = 20
|
||||||
|
idx += 10
|
||||||
ubyte[10] attributes
|
ubyte amount = 20
|
||||||
|
array[idx] -= amount
|
||||||
sub test(ubyte tattr, ubyte tobject) -> bool {
|
|
||||||
return tattr&ATTR_FALLING==0 and attributes[tobject]&ATTRF_EATABLE
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user