mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
fix and optimize storing A into pointervar
This commit is contained in:
parent
b867d8f731
commit
e545ea9504
@ -604,6 +604,45 @@ class AsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun storeAIntoPointerVar(pointervar: IdentifierReference) {
|
||||||
|
val sourceName = asmVariableName(pointervar)
|
||||||
|
val vardecl = pointervar.targetVarDecl(program)!!
|
||||||
|
val scopedName = vardecl.scopedName.joinToString(".")
|
||||||
|
if (isTargetCpu(CpuType.CPU65c02)) {
|
||||||
|
if (isZpVar(scopedName)) {
|
||||||
|
// pointervar is already in the zero page, no need to copy
|
||||||
|
out(" sta ($sourceName)")
|
||||||
|
} else {
|
||||||
|
out("""
|
||||||
|
ldy $sourceName
|
||||||
|
sty P8ZP_SCRATCH_W2
|
||||||
|
ldy $sourceName+1
|
||||||
|
sty P8ZP_SCRATCH_W2+1
|
||||||
|
sta (P8ZP_SCRATCH_W2)""")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isZpVar(scopedName)) {
|
||||||
|
// pointervar is already in the zero page, no need to copy
|
||||||
|
out(" ldy #0 | sta ($sourceName),y")
|
||||||
|
} else {
|
||||||
|
out("""
|
||||||
|
ldy $sourceName
|
||||||
|
sty P8ZP_SCRATCH_W2
|
||||||
|
ldy $sourceName+1
|
||||||
|
sty P8ZP_SCRATCH_W2+1
|
||||||
|
ldy #0
|
||||||
|
sta (P8ZP_SCRATCH_W2),y""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun storeAIntoZpPointerVar(zpPointerVar: String) {
|
||||||
|
if (isTargetCpu(CpuType.CPU65c02))
|
||||||
|
out(" sta ($zpPointerVar)")
|
||||||
|
else
|
||||||
|
out(" ldy #0 | sta ($zpPointerVar),y")
|
||||||
|
}
|
||||||
|
|
||||||
private fun fixNameSymbols(name: String): String {
|
private fun fixNameSymbols(name: String): String {
|
||||||
val name2 = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names
|
val name2 = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names
|
||||||
return name2.replace("prog8_lib.P8ZP_SCRATCH_", "P8ZP_SCRATCH_") // take care of the 'hooks' to the temp vars
|
return name2.replace("prog8_lib.P8ZP_SCRATCH_", "P8ZP_SCRATCH_") // take care of the 'hooks' to the temp vars
|
||||||
|
@ -2140,52 +2140,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
when(addressExpr) {
|
when(addressExpr) {
|
||||||
is NumericLiteralValue, is IdentifierReference -> {
|
is NumericLiteralValue, is IdentifierReference -> {
|
||||||
assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
|
assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
|
||||||
if (asmgen.isTargetCpu(CpuType.CPU65c02))
|
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2")
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W2)")
|
|
||||||
else
|
|
||||||
asmgen.out(" ldy #0 | sta (P8ZP_SCRATCH_W2),y")
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// same as above but we need to save the A register
|
// same as above but we need to save the A register
|
||||||
asmgen.out(" pha")
|
asmgen.out(" pha")
|
||||||
assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
|
assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
|
||||||
asmgen.out(" pla")
|
asmgen.out(" pla")
|
||||||
if (asmgen.isTargetCpu(CpuType.CPU65c02))
|
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2")
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W2)")
|
|
||||||
else
|
|
||||||
asmgen.out(" ldy #0 | sta (P8ZP_SCRATCH_W2),y")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun storeAIntoPointerVar(pointervar: IdentifierReference) {
|
|
||||||
val sourceName = asmgen.asmVariableName(pointervar)
|
|
||||||
val vardecl = pointervar.targetVarDecl(program)!!
|
|
||||||
val scopedName = vardecl.scopedName.joinToString(".")
|
|
||||||
if (asmgen.isTargetCpu(CpuType.CPU65c02)) {
|
|
||||||
if (asmgen.isZpVar(scopedName)) {
|
|
||||||
// pointervar is already in the zero page, no need to copy
|
|
||||||
asmgen.out(" sta ($sourceName)")
|
|
||||||
} else {
|
|
||||||
asmgen.out("""
|
|
||||||
ldy $sourceName
|
|
||||||
sty P8ZP_SCRATCH_W2
|
|
||||||
ldy $sourceName+1
|
|
||||||
sty P8ZP_SCRATCH_W2+1
|
|
||||||
sta (P8ZP_SCRATCH_W2)""")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (asmgen.isZpVar(scopedName)) {
|
|
||||||
// pointervar is already in the zero page, no need to copy
|
|
||||||
asmgen.out(" ldy #0 | sta ($sourceName),y")
|
|
||||||
} else {
|
|
||||||
asmgen.out("""
|
|
||||||
ldy $sourceName
|
|
||||||
sty P8ZP_SCRATCH_W2
|
|
||||||
ldy $sourceName+1
|
|
||||||
sty P8ZP_SCRATCH_W2+1
|
|
||||||
ldy #0
|
|
||||||
sta (P8ZP_SCRATCH_W2),y""")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2195,7 +2157,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.out(" sta ${addressLv.number.toHex()}")
|
asmgen.out(" sta ${addressLv.number.toHex()}")
|
||||||
}
|
}
|
||||||
addressExpr is IdentifierReference -> {
|
addressExpr is IdentifierReference -> {
|
||||||
storeAIntoPointerVar(addressExpr)
|
asmgen.storeAIntoPointerVar(addressExpr)
|
||||||
}
|
}
|
||||||
addressExpr is BinaryExpression -> {
|
addressExpr is BinaryExpression -> {
|
||||||
if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, true))
|
if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, true))
|
||||||
|
@ -372,9 +372,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" clc | adc P8ZP_SCRATCH_B1")
|
"+" -> asmgen.out(" clc | adc P8ZP_SCRATCH_B1")
|
||||||
"-" -> asmgen.out(" sec | sbc P8ZP_SCRATCH_B1")
|
"-" -> asmgen.out(" sec | sbc P8ZP_SCRATCH_B1")
|
||||||
"*" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.multiply_bytes | ldy #0")
|
"*" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.multiply_bytes")
|
||||||
"/" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.divmod_ub_asm | tya | ldy #0")
|
"/" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.divmod_ub_asm | tya")
|
||||||
"%" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.divmod_ub_asm | ldy #0")
|
"%" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.divmod_ub_asm")
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy P8ZP_SCRATCH_B1
|
ldy P8ZP_SCRATCH_B1
|
||||||
@ -398,8 +398,9 @@ 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")
|
||||||
}
|
}
|
||||||
|
// TODO THIS IS WRONG:????
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@ -410,9 +411,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" clc | adc $otherName")
|
"+" -> asmgen.out(" clc | adc $otherName")
|
||||||
"-" -> asmgen.out(" sec | sbc $otherName")
|
"-" -> asmgen.out(" sec | sbc $otherName")
|
||||||
"*" -> asmgen.out(" ldy $otherName | jsr math.multiply_bytes | ldy #0")
|
"*" -> asmgen.out(" ldy $otherName | jsr math.multiply_bytes")
|
||||||
"/" -> asmgen.out(" ldy $otherName | jsr math.divmod_ub_asm | tya | ldy #0")
|
"/" -> asmgen.out(" ldy $otherName | jsr math.divmod_ub_asm | tya")
|
||||||
"%" -> asmgen.out(" ldy $otherName | jsr math.divmod_ub_asm | ldy #0")
|
"%" -> asmgen.out(" ldy $otherName | jsr math.divmod_ub_asm")
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $otherName
|
ldy $otherName
|
||||||
@ -436,7 +437,7 @@ 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")
|
||||||
}
|
}
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@ -445,63 +446,63 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
"+" -> {
|
"+" -> {
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" clc | adc #$value")
|
asmgen.out(" clc | adc #$value")
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" sec | sbc #$value")
|
asmgen.out(" sec | sbc #$value")
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
"*" -> {
|
"*" -> {
|
||||||
val 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")
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
"/" -> {
|
"/" -> {
|
||||||
val 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")
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
"%" -> {
|
"%" -> {
|
||||||
val 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")
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
repeat(value) { asmgen.out(" asl a") }
|
repeat(value) { asmgen.out(" asl a") }
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">>" -> {
|
">>" -> {
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
repeat(value) { asmgen.out(" lsr a") }
|
repeat(value) { asmgen.out(" lsr a") }
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"&", "and" -> {
|
"&", "and" -> {
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" and #$value")
|
asmgen.out(" and #$value")
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
"|", "or" -> {
|
"|", "or" -> {
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" ora #$value")
|
asmgen.out(" ora #$value")
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
"^", "xor" -> {
|
"^", "xor" -> {
|
||||||
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" eor #$value")
|
asmgen.out(" eor #$value")
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
@ -1811,7 +1812,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
beq +
|
beq +
|
||||||
lda #1
|
lda #1
|
||||||
+ eor #1""")
|
+ eor #1""")
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.assignExpressionToVariable(mem.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope)
|
asmgen.assignExpressionToVariable(mem.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope)
|
||||||
@ -1820,8 +1821,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
lda (P8ZP_SCRATCH_W2),y
|
lda (P8ZP_SCRATCH_W2),y
|
||||||
beq +
|
beq +
|
||||||
lda #1
|
lda #1
|
||||||
+ eor #1
|
+ eor #1""")
|
||||||
sta (P8ZP_SCRATCH_W2),y""")
|
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1942,8 +1943,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (P8ZP_SCRATCH_W2),y
|
lda (P8ZP_SCRATCH_W2),y
|
||||||
eor #255
|
eor #255""")
|
||||||
sta (P8ZP_SCRATCH_W2),y""")
|
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ X = BinExpr X = LeftExpr
|
|||||||
// )
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO breaks imageviewer EHB palette
|
||||||
if(binExpr.right.isSimple) {
|
if(binExpr.right.isSimple) {
|
||||||
val firstAssign = Assignment(assignment.target.copy(), binExpr.left, binExpr.left.position)
|
val firstAssign = Assignment(assignment.target.copy(), binExpr.left, binExpr.left.position)
|
||||||
val targetExpr = assignment.target.toExpression()
|
val targetExpr = assignment.target.toExpression()
|
||||||
|
@ -3,6 +3,10 @@ TODO
|
|||||||
|
|
||||||
For next compiler release (7.5)
|
For next compiler release (7.5)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
BUG: imageviewer.p8 iff loader: winterqueen.iff (EHB image) is not displayed correctly!
|
||||||
|
--> make_ehb_palette() is wrong with optimizations, ok without.
|
||||||
|
--> caused by splitBinaryExpressions()
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,15 +3,41 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
|
ubyte[64*3] palette
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
uword scrpos = $0400
|
ubyte i
|
||||||
repeat 256 {
|
for i in 0 to len(palette)-1 {
|
||||||
@(scrpos) = 81
|
palette[i] = 15
|
||||||
scrpos++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
txt.print_uw(scrpos)
|
for i in 0 to len(palette)-1 {
|
||||||
|
txt.print_ubhex(palette[i], false)
|
||||||
|
}
|
||||||
|
txt.nl()
|
||||||
|
make_ehb_palette()
|
||||||
|
for i in 0 to len(palette)-1 {
|
||||||
|
txt.print_ubhex(palette[i], false)
|
||||||
|
}
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub make_ehb_palette() {
|
||||||
|
; generate 32 additional Extra-Halfbrite colors in the cmap
|
||||||
|
uword palletteptr = &palette
|
||||||
|
uword ehbptr = palletteptr + 32*3
|
||||||
|
repeat 32 {
|
||||||
|
@(ehbptr) = @(palletteptr)>>1
|
||||||
|
ehbptr++
|
||||||
|
palletteptr++
|
||||||
|
@(ehbptr) = @(palletteptr)>>1
|
||||||
|
ehbptr++
|
||||||
|
palletteptr++
|
||||||
|
@(ehbptr) = @(palletteptr)>>1
|
||||||
|
ehbptr++
|
||||||
|
palletteptr++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user