added some more missing aug assign operator code

This commit is contained in:
Irmen de Jong 2020-10-07 22:18:55 +02:00
parent 0e3c92626e
commit c426f4626c
4 changed files with 132 additions and 153 deletions

View File

@ -781,7 +781,7 @@ mul_byte_3 .proc
sta P8ZP_SCRATCH_REG sta P8ZP_SCRATCH_REG
asl a asl a
clc clc
adc P8P_P8ZP_SCRATCH_REG adc P8ZP_SCRATCH_REG
rts rts
.pend .pend

View File

@ -497,7 +497,7 @@ internal class AsmGen(private val program: Program,
} }
internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): Pair<Boolean, String> { internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): Pair<Boolean, String> {
// returns if the pointer is already on the ZP itself or not (in which case SCRATCH_W1 is used as intermediary) // returns if the pointer is already on the ZP itself or not (in the latter case SCRATCH_W1 is used as intermediary)
val sourceName = asmVariableName(pointervar) val sourceName = asmVariableName(pointervar)
val vardecl = pointervar.targetVarDecl(program.namespace)!! val vardecl = pointervar.targetVarDecl(program.namespace)!!
val scopedName = vardecl.makeScopedName(vardecl.name) val scopedName = vardecl.makeScopedName(vardecl.name)
@ -773,6 +773,7 @@ internal class AsmGen(private val program: Program,
CpuRegister.Y -> out(" tay") CpuRegister.Y -> out(" tay")
} }
} }
else -> throw AssemblyError("weird dt")
} }
} }
} }

View File

@ -222,123 +222,92 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
private fun inplaceModification_byte_value_to_memory(pointervar: IdentifierReference, operator: String, value: Expression) { private fun inplaceModification_byte_value_to_memory(pointervar: IdentifierReference, operator: String, value: Expression) {
println("warning: slow stack evaluation used (3): @(${pointervar.nameInSource.last()}) $operator= ${value::class.simpleName} at ${value.position}") // TODO println("warning: slow stack evaluation used (3): @(${pointervar.nameInSource.last()}) $operator= ${value::class.simpleName} at ${value.position}") // TODO
asmgen.translateExpression(value) asmgen.translateExpression(value)
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
when (operator) { when (operator) {
// note: ** (power) operator requires floats. // note: ** (power) operator requires floats.
"+" -> { "+" -> asmgen.out(" clc | adc P8ESTACK_LO+1,x")
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) "-" -> asmgen.out(" sec | sbc P8ESTACK_LO+1,x")
asmgen.out(" clc | adc P8ESTACK_LO+1,x") "*" -> asmgen.out(" pha | lda P8ESTACK_LO+1,x | tay | pla | jsr math.multiply_bytes | ldy #0")
if(ptrOnZp) "/" -> asmgen.out(" pha | lda P8ESTACK_LO+1,x | tay | pla | jsr math.divmod_ub_asm | tya | ldy #0")
asmgen.out(" sta ($sourceName),y") "%" -> asmgen.out(" pha | lda P8ESTACK_LO+1,x | tay | pla | jsr math.divmod_ub_asm | ldy #0")
else "<<" -> {
asmgen.out(" sta (P8ZP_SCRATCH_W1),y") asmgen.out("""
pha
lda P8ESTACK_LO+1,x
bne +
pla
rts
+ tay
pla
- asl a
dey
bne -
+""")
} }
"-" -> { ">>" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out("""
asmgen.out(" sec | sbc P8ESTACK_LO+1,x") pha
if(ptrOnZp) lda P8ESTACK_LO+1,x
asmgen.out(" sta ($sourceName),y") bne +
else pla
asmgen.out(" sta (P8ZP_SCRATCH_W1),y") rts
} + tay
"*" -> { pla
TODO("mul mem byte")// asmgen.out(" jsr prog8_lib.mul_byte") - lsr a
} dey
"/" -> TODO("div mem byte")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b") bne -
"%" -> { +""")
TODO("mem byte remainder")
// if(types==DataType.BYTE)
// throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
// asmgen.out(" jsr prog8_lib.remainder_ub")
}
"<<" -> TODO("mem ubyte asl")
">>" -> TODO("mem ubyte lsr")
"&" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" and P8ESTACK_LO+1,x")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
}
"^" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" eor P8ESTACK_LO+1,x")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
}
"|" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" ora P8ESTACK_LO+1,x")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"&" -> asmgen.out(" and P8ESTACK_LO+1,x")
"^" -> asmgen.out(" eor P8ESTACK_LO+1,x")
"|" -> asmgen.out(" ora P8ESTACK_LO+1,x")
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")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
asmgen.out(" inx") asmgen.out(" inx")
} }
private fun inplaceModification_byte_variable_to_memory(pointervar: IdentifierReference, operator: String, value: IdentifierReference) { private fun inplaceModification_byte_variable_to_memory(pointervar: IdentifierReference, operator: String, value: IdentifierReference) {
val otherName = asmgen.asmVariableName(value) val otherName = asmgen.asmVariableName(value)
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
when (operator) { when (operator) {
// note: ** (power) operator requires floats. // note: ** (power) operator requires floats.
"+" -> { "+" -> asmgen.out(" clc | adc $otherName")
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) "-" -> asmgen.out(" sec | sbc $otherName")
asmgen.out(" clc | adc $otherName") "*" -> asmgen.out(" ldy $otherName | jsr math.multiply_bytes | ldy #0")
if(ptrOnZp) "/" -> asmgen.out(" ldy $otherName | jsr math.divmod_ub_asm | tya | ldy #0")
asmgen.out(" sta ($sourceName),y") "%" -> asmgen.out(" ldy $otherName | jsr math.divmod_ub_asm | ldy #0")
else "<<" -> {
asmgen.out(" sta (P8ZP_SCRATCH_W1),y") asmgen.out("""
ldy $otherName
beq +
- asl a
dey
bne -
+""")
} }
"-" -> { ">>" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out("""
asmgen.out(" sec | sbc $otherName") ldy $otherName
if(ptrOnZp) beq +
asmgen.out(" sta ($sourceName),y") - lsr a
else dey
asmgen.out(" sta (P8ZP_SCRATCH_W1),y") bne -
} +""")
"*" -> {
TODO("mem mul")// asmgen.out(" jsr prog8_lib.mul_byte")
}
"/" -> TODO("mem div")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
"%" -> {
TODO("mem byte remainder")
// if(types==DataType.BYTE)
// throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
// asmgen.out(" jsr prog8_lib.remainder_ub")
}
"<<" -> TODO("mem ubyte asl")
">>" -> TODO("mem ubyte lsr")
"&" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" and $otherName")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
}
"^" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" eor $otherName")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
}
"|" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out(" ora $otherName")
if(ptrOnZp)
asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"&" -> asmgen.out(" and $otherName")
"^" -> asmgen.out(" eor $otherName")
"|" -> asmgen.out(" ora $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")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
private fun inplaceModification_byte_litval_to_memory(pointervar: IdentifierReference, operator: String, value: Int) { private fun inplaceModification_byte_litval_to_memory(pointervar: IdentifierReference, operator: String, value: Int) {
@ -361,26 +330,35 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
asmgen.out(" sta (P8ZP_SCRATCH_W1),y") asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"*" -> { "*" -> {
if(value in asmgen.optimizedByteMultiplications) { val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
TODO("optimized mem mul ubyte litval $value") if(value in asmgen.optimizedByteMultiplications)
} else { asmgen.out(" jsr math.mul_byte_${value}")
TODO("mem mul ubyte litval $value") else
// asmgen.out(" jsr prog8_lib.mul_byte") asmgen.out(" ldy #$value | jsr math.multiply_bytes | ldy #0")
} if(ptrOnZp)
asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"/" -> { "/" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
if(value==0) if(value==0)
throw AssemblyError("division by zero") throw AssemblyError("division by zero")
TODO("mem div byte litval") asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya | ldy #0")
// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b") if(ptrOnZp)
asmgen.out(" sta ($sourceName),y")
else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"%" -> { "%" -> {
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
if(value==0) if(value==0)
throw AssemblyError("division by zero") throw AssemblyError("division by zero")
TODO("mem byte remainder litval") asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | ldy #0")
// if(types==DataType.BYTE) if(ptrOnZp)
// throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead") asmgen.out(" sta ($sourceName),y")
// asmgen.out(" jsr prog8_lib.remainder_ub") else
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
} }
"<<" -> { "<<" -> {
if (value > 0) { if (value > 0) {
@ -439,19 +417,17 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
// note: ** (power) operator requires floats. // note: ** (power) operator requires floats.
"+" -> asmgen.out(" lda $name | clc | adc P8ESTACK_LO+1,x | sta $name") "+" -> asmgen.out(" lda $name | clc | adc P8ESTACK_LO+1,x | sta $name")
"-" -> asmgen.out(" lda $name | sec | sbc P8ESTACK_LO+1,x | sta $name") "-" -> asmgen.out(" lda $name | sec | sbc P8ESTACK_LO+1,x | sta $name")
"*" -> { "*" -> asmgen.out(" lda P8ESTACK_LO+1,x | ldy $name | jsr math.multiply_bytes | sta $name")
TODO("var mul byte expr")
// check optimizedByteMultiplications
// asmgen.out(" jsr prog8_lib.mul_byte")
}
"/" -> { "/" -> {
TODO("var div byte expr")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b") if(dt==DataType.UBYTE)
asmgen.out(" lda P8ESTACK_LO+1,x | tay | lda $name | jsr math.divmod_ub_asm | sty $name")
else
asmgen.out(" lda P8ESTACK_LO+1,x | tay | lda $name | jsr math.divmod_b_asm | sty $name")
} }
"%" -> { "%" -> {
TODO("var byte remainder expr") if(dt==DataType.BYTE)
// if(types==DataType.BYTE) 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 P8ESTACK_LO+1,x | tay | lda $name | jsr math.divmod_ub_asm | sta $name")
// asmgen.out(" jsr prog8_lib.remainder_ub")
} }
"<<" -> { "<<" -> {
asmgen.translateExpression(value) asmgen.translateExpression(value)
@ -571,33 +547,16 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
"+" -> 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")
"*" -> { "*" -> {
if(dt == DataType.UBYTE) { if(value in asmgen.optimizedByteMultiplications)
if(value in asmgen.optimizedByteMultiplications) { asmgen.out(" lda $name | jsr math.mul_byte_$value | sta $name")
asmgen.out(" lda $name | jsr math.mul_byte_$value | sta $name") else
} else { asmgen.out(" lda $name | ldy #$value | jsr math.multiply_bytes | sta $name")
TODO("var mul ubyte litval $value")
// asmgen.out(" jsr prog8_lib.mul_byte")
}
} else {
if(value.absoluteValue in asmgen.optimizedByteMultiplications) {
asmgen.out(" lda $name | jsr math.mul_byte_$value | sta $name")
} else {
TODO("var mul sbyte litval $value")
// asmgen.out(" jsr prog8_lib.mul_byte")
}
}
} }
"/" -> { "/" -> {
if (dt == DataType.UBYTE) { if (dt == DataType.UBYTE)
asmgen.out(""" asmgen.out(" lda $name | ldy #$value | jsr math.divmod_ub_asm | sty $name")
lda $name else
ldy #$value asmgen.out(" lda $name | ldy #$value | jsr math.divmod_b_asm | sty $name")
jsr math.divmod_ub_asm
sty $name
""")
} else {
TODO("var BYTE div litval")
}
} }
"%" -> { "%" -> {
if(dt==DataType.BYTE) if(dt==DataType.BYTE)

View File

@ -14,11 +14,30 @@ main {
ubyte ii ubyte ii
uword ww uword ww
uword wptr = &warray uword wptr = &warray
&uword wmap = $c000 ubyte wmap
wmap += ii ii = 2
wmap <<= ii
wmap >>= ii wmap = %11110000
wmap >>= 3
txt.print_ubbin(wmap, 1)
txt.chrout('\n')
wmap <<= 3
txt.print_ubbin(wmap, 1)
txt.chrout('\n')
wmap = 9
wmap *= 17
txt.print_ub(wmap)
txt.chrout('\n')
wmap /= 17
txt.print_ub(wmap)
txt.chrout('\n')
wmap = 211
wmap %= 40
txt.print_ub(wmap)
txt.chrout('\n')
txt.chrout('\n')
txt.print(planet_name) txt.print(planet_name)
txt.chrout('\n') txt.chrout('\n')