cleaner return type

This commit is contained in:
Irmen de Jong 2021-10-12 22:21:38 +02:00
parent 4f7465ba44
commit 367a2a4cee
2 changed files with 41 additions and 82 deletions

View File

@ -555,13 +555,14 @@ internal class AsmGen(private val program: Program,
internal fun asmVariableName(name: Iterable<String>) = fixNameSymbols(name.joinToString(".")) internal fun asmVariableName(name: Iterable<String>) = fixNameSymbols(name.joinToString("."))
internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): Pair<Boolean, String> { internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): String {
// returns if the pointer is already on the ZP itself or not (in the latter case SCRATCH_W1 is used as intermediary) // returns the source name of the zero page pointervar if it's already in the ZP,
// otherwise returns "P8ZP_SCRATCH_W1" which is the intermediary
when (val target = pointervar.targetStatement(program)) { when (val target = pointervar.targetStatement(program)) {
is Label -> { is Label -> {
val sourceName = asmSymbolName(pointervar) val sourceName = asmSymbolName(pointervar)
out(" lda $sourceName") out(" lda $sourceName")
return Pair(true, sourceName) return sourceName
} }
is VarDecl -> { is VarDecl -> {
val sourceName = asmVariableName(pointervar) val sourceName = asmVariableName(pointervar)
@ -570,7 +571,7 @@ internal class AsmGen(private val program: Program,
return if (isZpVar(scopedName)) { return if (isZpVar(scopedName)) {
// pointervar is already in the zero page, no need to copy // pointervar is already in the zero page, no need to copy
out(" lda ($sourceName)") out(" lda ($sourceName)")
Pair(true, sourceName) sourceName
} else { } else {
out(""" out("""
lda $sourceName lda $sourceName
@ -578,13 +579,13 @@ internal class AsmGen(private val program: Program,
sta P8ZP_SCRATCH_W1 sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1 sty P8ZP_SCRATCH_W1+1
lda (P8ZP_SCRATCH_W1)""") lda (P8ZP_SCRATCH_W1)""")
Pair(false, sourceName) "P8ZP_SCRATCH_W1"
} }
} else { } else {
return if (isZpVar(scopedName)) { return if (isZpVar(scopedName)) {
// pointervar is already in the zero page, no need to copy // pointervar is already in the zero page, no need to copy
out(" ldy #0 | lda ($sourceName),y") out(" ldy #0 | lda ($sourceName),y")
Pair(true, sourceName) sourceName
} else { } else {
out(""" out("""
lda $sourceName lda $sourceName
@ -593,7 +594,7 @@ internal class AsmGen(private val program: Program,
sty P8ZP_SCRATCH_W1+1 sty P8ZP_SCRATCH_W1+1
ldy #0 ldy #0
lda (P8ZP_SCRATCH_W1),y""") lda (P8ZP_SCRATCH_W1),y""")
Pair(false, sourceName) "P8ZP_SCRATCH_W1"
} }
} }
} }

View File

@ -293,7 +293,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
private fun inplaceModification_byte_value_to_pointer(pointervar: IdentifierReference, operator: String, value: Expression) { private fun inplaceModification_byte_value_to_pointer(pointervar: IdentifierReference, operator: String, value: Expression) {
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
when (operator) { when (operator) {
// note: ** (power) operator requires floats. // note: ** (power) operator requires floats.
"+" -> asmgen.out(" clc | adc P8ZP_SCRATCH_B1") "+" -> asmgen.out(" clc | adc P8ZP_SCRATCH_B1")
@ -324,15 +323,13 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1") "^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
else -> throw AssemblyError("invalid operator for in-place modification $operator") else -> throw AssemblyError("invalid operator for in-place modification $operator")
} }
if(ptrOnZp) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
private fun inplaceModification_byte_variable_to_pointer(pointervar: IdentifierReference, operator: String, value: IdentifierReference) { private fun inplaceModification_byte_variable_to_pointer(pointervar: IdentifierReference, operator: String, value: IdentifierReference) {
val otherName = asmgen.asmVariableName(value) val otherName = asmgen.asmVariableName(value)
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
when (operator) { when (operator) {
// note: ** (power) operator requires floats. // note: ** (power) operator requires floats.
@ -364,105 +361,72 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
"^", "xor" -> asmgen.out(" eor $otherName") "^", "xor" -> asmgen.out(" eor $otherName")
else -> throw AssemblyError("invalid operator for in-place modification $operator") else -> throw AssemblyError("invalid operator for in-place modification $operator")
} }
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
private fun inplaceModification_byte_litval_to_pointer(pointervar: IdentifierReference, operator: String, value: Int) { private fun inplaceModification_byte_litval_to_pointer(pointervar: IdentifierReference, operator: String, value: Int) {
when (operator) { when (operator) {
// note: ** (power) operator requires floats. // note: ** (power) operator requires floats.
"+" -> { "+" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" clc | adc #$value") asmgen.out(" clc | adc #$value")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"-" -> { "-" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" sec | sbc #$value") asmgen.out(" sec | sbc #$value")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"*" -> { "*" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
if(value in asmgen.optimizedByteMultiplications) if(value in asmgen.optimizedByteMultiplications)
asmgen.out(" jsr math.mul_byte_${value}") asmgen.out(" jsr math.mul_byte_${value}")
else else
asmgen.out(" ldy #$value | jsr math.multiply_bytes | ldy #0") asmgen.out(" ldy #$value | jsr math.multiply_bytes | ldy #0")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"/" -> { "/" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
if(value==0) if(value==0)
throw AssemblyError("division by zero") throw AssemblyError("division by zero")
asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya | ldy #0") asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya | ldy #0")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"%" -> { "%" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
if(value==0) if(value==0)
throw AssemblyError("division by zero") throw AssemblyError("division by zero")
asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | ldy #0") asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | ldy #0")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"<<" -> { "<<" -> {
if (value > 0) { if (value > 0) {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
repeat(value) { asmgen.out(" asl a") } repeat(value) { asmgen.out(" asl a") }
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
} }
">>" -> { ">>" -> {
if (value > 0) { if (value > 0) {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
repeat(value) { asmgen.out(" lsr a") } repeat(value) { asmgen.out(" lsr a") }
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
} }
"&", "and" -> { "&", "and" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" and #$value") asmgen.out(" and #$value")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"|", "or" -> { "|", "or" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" ora #$value") asmgen.out(" ora #$value")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"^", "xor" -> { "^", "xor" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" eor #$value") asmgen.out(" eor #$value")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
else -> throw AssemblyError("invalid operator for in-place modification $operator") else -> throw AssemblyError("invalid operator for in-place modification $operator")
} }
@ -1766,15 +1730,12 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta $addr""") sta $addr""")
} }
is IdentifierReference -> { is IdentifierReference -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(mem.addressExpression as IdentifierReference) val sourceName = asmgen.loadByteFromPointerIntoA(mem.addressExpression as IdentifierReference)
asmgen.out(""" asmgen.out("""
beq + beq +
lda #1 lda #1
+ eor #1""") + eor #1""")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
else -> { else -> {
asmgen.assignExpressionToVariable(mem.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope) asmgen.assignExpressionToVariable(mem.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope)
@ -1837,12 +1798,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta $addr""") sta $addr""")
} }
is IdentifierReference -> { is IdentifierReference -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(memory.addressExpression as IdentifierReference) val sourceName = asmgen.loadByteFromPointerIntoA(memory.addressExpression as IdentifierReference)
asmgen.out(" eor #255") asmgen.out(" eor #255")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y") asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
else -> { else -> {
asmgen.assignExpressionToVariable(memory.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope) asmgen.assignExpressionToVariable(memory.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope)