mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
fixed and optimized pointervar indexed in-place operations
This commit is contained in:
parent
e63a8f0c01
commit
820541e427
@ -382,21 +382,18 @@ private fun optimizeStoreLoadSame(
|
|||||||
machine: IMachineDefinition,
|
machine: IMachineDefinition,
|
||||||
symbolTable: SymbolTable
|
symbolTable: SymbolTable
|
||||||
): List<Modification> {
|
): List<Modification> {
|
||||||
// sta X + lda X, sty X + ldy X, stx X + ldx X -> the second instruction can OFTEN be eliminated
|
|
||||||
val mods = mutableListOf<Modification>()
|
val mods = mutableListOf<Modification>()
|
||||||
for (lines in linesByFour) {
|
for (lines in linesByFour) {
|
||||||
val first = lines[1].value.trimStart()
|
val first = lines[1].value.trimStart()
|
||||||
val second = lines[2].value.trimStart()
|
val second = lines[2].value.trimStart()
|
||||||
|
|
||||||
|
// sta X + lda X, sty X + ldy X, stx X + ldx X -> the second instruction can OFTEN be eliminated
|
||||||
if ((first.startsWith("sta ") && second.startsWith("lda ")) ||
|
if ((first.startsWith("sta ") && second.startsWith("lda ")) ||
|
||||||
(first.startsWith("stx ") && second.startsWith("ldx ")) ||
|
(first.startsWith("stx ") && second.startsWith("ldx ")) ||
|
||||||
(first.startsWith("sty ") && second.startsWith("ldy ")) ||
|
(first.startsWith("sty ") && second.startsWith("ldy ")) ||
|
||||||
(first.startsWith("lda ") && second.startsWith("lda ")) ||
|
(first.startsWith("lda ") && second.startsWith("lda ")) ||
|
||||||
(first.startsWith("ldy ") && second.startsWith("ldy ")) ||
|
(first.startsWith("ldy ") && second.startsWith("ldy ")) ||
|
||||||
(first.startsWith("ldx ") && second.startsWith("ldx ")) ||
|
(first.startsWith("ldx ") && second.startsWith("ldx "))
|
||||||
(first.startsWith("sta ") && second.startsWith("lda ")) ||
|
|
||||||
(first.startsWith("sty ") && second.startsWith("ldy ")) ||
|
|
||||||
(first.startsWith("stx ") && second.startsWith("ldx "))
|
|
||||||
) {
|
) {
|
||||||
val third = lines[3].value.trimStart()
|
val third = lines[3].value.trimStart()
|
||||||
val attemptRemove =
|
val attemptRemove =
|
||||||
@ -439,6 +436,18 @@ private fun optimizeStoreLoadSame(
|
|||||||
mods.add(Modification(lines[1].index, true, null))
|
mods.add(Modification(lines[1].index, true, null))
|
||||||
mods.add(Modification(lines[2].index, false, " tya"))
|
mods.add(Modification(lines[2].index, false, " tya"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// lda X + sta X, ldy X + sty X, ldx X + stx X -> the second instruction can be eliminated
|
||||||
|
if ((first.startsWith("lda ") && second.startsWith("sta ")) ||
|
||||||
|
(first.startsWith("ldx ") && second.startsWith("stx ")) ||
|
||||||
|
(first.startsWith("ldy ") && second.startsWith("sty "))
|
||||||
|
) {
|
||||||
|
val firstLoc = first.substring(4).trimStart()
|
||||||
|
val secondLoc = second.substring(4).trimStart()
|
||||||
|
if (firstLoc == secondLoc)
|
||||||
|
mods.add(Modification(lines[2].index, true, null))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return mods
|
return mods
|
||||||
}
|
}
|
||||||
@ -485,6 +494,7 @@ private fun optimizeIncDec(linesByFour: Sequence<List<IndexedValue<String>>>): L
|
|||||||
mods.add(Modification(lines[0].index, true, null))
|
mods.add(Modification(lines[0].index, true, null))
|
||||||
mods.add(Modification(lines[1].index, true, null))
|
mods.add(Modification(lines[1].index, true, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return mods
|
return mods
|
||||||
}
|
}
|
||||||
|
@ -570,31 +570,68 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
private fun tryOptimizedMemoryInplace(address: PtBinaryExpression, operator: String, value: AsmAssignSource): Boolean {
|
private fun tryOptimizedMemoryInplace(address: PtBinaryExpression, operator: String, value: AsmAssignSource): Boolean {
|
||||||
if(value.datatype !in ByteDatatypes || operator !in "|&^+-")
|
if(value.datatype !in ByteDatatypes || operator !in "|&^+-")
|
||||||
return false
|
return false
|
||||||
val rightTc = address.right as? PtTypeCast
|
|
||||||
val constOffset = (address.right as? PtNumber)?.number?.toInt()
|
fun addrIntoZpPointer(): String {
|
||||||
if(address.operator=="+" && (address.right.type in ByteDatatypes || (rightTc!=null && rightTc.value.type in ByteDatatypes) || (constOffset!=null && constOffset<256)) ) {
|
|
||||||
if(rightTc!=null)
|
|
||||||
asmgen.assignExpressionToRegister(rightTc.value, RegisterOrPair.A, false)
|
|
||||||
else if(constOffset!=null)
|
|
||||||
asmgen.out(" lda #${constOffset}")
|
|
||||||
else
|
|
||||||
asmgen.assignExpressionToRegister(address.right, RegisterOrPair.A, false)
|
|
||||||
asmgen.out(" pha") // offset on stack
|
|
||||||
val zpPointerVarName: String
|
|
||||||
if(address.left is PtIdentifier && asmgen.isZpVar(address.left as PtIdentifier)) {
|
if(address.left is PtIdentifier && asmgen.isZpVar(address.left as PtIdentifier)) {
|
||||||
zpPointerVarName = (address.left as PtIdentifier).name
|
return (address.left as PtIdentifier).name
|
||||||
} else {
|
} else {
|
||||||
zpPointerVarName = "P8ZP_SCRATCH_W2"
|
|
||||||
asmgen.assignExpressionToRegister(address.left, RegisterOrPair.AY, false)
|
asmgen.assignExpressionToRegister(address.left, RegisterOrPair.AY, false)
|
||||||
asmgen.out(" sta $zpPointerVarName | sty $zpPointerVarName+1")
|
asmgen.out(" sta P8ZP_SCRATCH_W2 | sty P8ZP_SCRATCH_W2+1")
|
||||||
|
return "P8ZP_SCRATCH_W2"
|
||||||
}
|
}
|
||||||
// calculate value into A
|
}
|
||||||
|
|
||||||
|
fun assignValueToA() {
|
||||||
val assignValue = AsmAssignment(value,
|
val assignValue = AsmAssignment(value,
|
||||||
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UBYTE,
|
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UBYTE,
|
||||||
address.definingISub(), Position.DUMMY, register = RegisterOrPair.A),
|
address.definingISub(), Position.DUMMY, register = RegisterOrPair.A),
|
||||||
program.memsizer, Position.DUMMY)
|
program.memsizer, Position.DUMMY)
|
||||||
assignmentAsmGen.translateNormalAssignment(assignValue, address.definingISub())
|
assignmentAsmGen.translateNormalAssignment(assignValue, address.definingISub()) // calculate value into A
|
||||||
asmgen.restoreRegisterStack(CpuRegister.Y, false) // offset into Y
|
}
|
||||||
|
|
||||||
|
val rightTc = address.right as? PtTypeCast
|
||||||
|
val constOffset = (address.right as? PtNumber)?.number?.toInt()
|
||||||
|
if(address.operator=="+" && (address.right.type in ByteDatatypes || (rightTc!=null && rightTc.value.type in ByteDatatypes) || (constOffset!=null && constOffset<256)) ) {
|
||||||
|
if(constOffset!=null) {
|
||||||
|
val zpPointerVarName = addrIntoZpPointer()
|
||||||
|
if(value.number==null) assignValueToA()
|
||||||
|
asmgen.out(" ldy #$constOffset")
|
||||||
|
when(operator) {
|
||||||
|
"|" -> {
|
||||||
|
if(value.number!=null) asmgen.out(" lda #${value.number.number.toInt()}")
|
||||||
|
asmgen.out(" ora ($zpPointerVarName),y")
|
||||||
|
}
|
||||||
|
"&" -> {
|
||||||
|
if(value.number!=null) asmgen.out(" lda #${value.number.number.toInt()}")
|
||||||
|
asmgen.out(" and ($zpPointerVarName),y")
|
||||||
|
}
|
||||||
|
"^" -> {
|
||||||
|
if(value.number!=null) asmgen.out(" lda #${value.number.number.toInt()}")
|
||||||
|
asmgen.out(" eor ($zpPointerVarName),y")
|
||||||
|
}
|
||||||
|
"+" -> {
|
||||||
|
// note: there is no inc (ZP),y instruction...
|
||||||
|
if (value.number != null) asmgen.out(" lda #${value.number.number.toInt()}")
|
||||||
|
asmgen.out(" clc | adc ($zpPointerVarName),y")
|
||||||
|
}
|
||||||
|
"-" -> {
|
||||||
|
// note: there is no dec (ZP),y instruction...
|
||||||
|
if (value.number != null) asmgen.out(" lda ($zpPointerVarName),y | sec | sbc #${value.number.number.toInt()}")
|
||||||
|
else asmgen.out(" sta P8ZP_SCRATCH_REG | lda ($zpPointerVarName),y | sec | sbc P8ZP_SCRATCH_REG")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("invalid op")
|
||||||
|
}
|
||||||
|
asmgen.out(" sta ($zpPointerVarName),y")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if(rightTc!=null)
|
||||||
|
asmgen.assignExpressionToRegister(rightTc.value, RegisterOrPair.A, false)
|
||||||
|
else
|
||||||
|
asmgen.assignExpressionToRegister(address.right, RegisterOrPair.A, false)
|
||||||
|
asmgen.out(" pha") // offset on stack
|
||||||
|
val zpPointerVarName = addrIntoZpPointer()
|
||||||
|
assignValueToA()
|
||||||
|
asmgen.restoreRegisterStack(CpuRegister.Y, true) // offset from stack back into Y
|
||||||
when(operator) {
|
when(operator) {
|
||||||
"|" -> asmgen.out(" ora ($zpPointerVarName),y")
|
"|" -> asmgen.out(" ora ($zpPointerVarName),y")
|
||||||
"&" -> asmgen.out(" and ($zpPointerVarName),y")
|
"&" -> asmgen.out(" and ($zpPointerVarName),y")
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
Petaxian has gameplay problems on the C64 (with and without optimization) , cx16 target is fine.
|
|
||||||
(seems unrelated to boolean type changes. 10.1 was still fine.)
|
|
||||||
caused by 358215e4ddf408e568ded0d36afce9f0162e21d1 Removed PostIncrDecr
|
|
||||||
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
131
examples/test.p8
131
examples/test.p8
@ -4,21 +4,124 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
derp("hello")
|
uword @shared ref = $2000
|
||||||
mult3("hello")
|
ref[5]=10
|
||||||
}
|
txt.print_ub(ref[5])
|
||||||
|
txt.spc()
|
||||||
|
ref[5]--
|
||||||
|
txt.print_ub(ref[5])
|
||||||
|
txt.spc()
|
||||||
|
ref[5]++
|
||||||
|
txt.print_ub(ref[5])
|
||||||
|
txt.nl()
|
||||||
|
ref[5]-=2
|
||||||
|
txt.print_ub(ref[5])
|
||||||
|
txt.spc()
|
||||||
|
ref[5]+=2
|
||||||
|
txt.print_ub(ref[5])
|
||||||
|
txt.nl()
|
||||||
|
ref[5]-=3
|
||||||
|
txt.print_ub(ref[5])
|
||||||
|
txt.spc()
|
||||||
|
ref[5]+=3
|
||||||
|
txt.print_ub(ref[5])
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
sub derp(str arg) -> str {
|
|
||||||
cx16.r0++
|
|
||||||
return arg
|
|
||||||
}
|
|
||||||
|
|
||||||
asmsub mult3(str input @XY) -> ubyte @A, str @XY {
|
ubyte[] array = [1,2,3,4,5,10]
|
||||||
%asm {{
|
array[5]=10
|
||||||
lda #99
|
txt.print_ub(array[5])
|
||||||
ldx #100
|
txt.spc()
|
||||||
ldy #101
|
array[5]--
|
||||||
rts
|
txt.print_ub(array[5])
|
||||||
}}
|
txt.spc()
|
||||||
|
array[5]++
|
||||||
|
txt.print_ub(array[5])
|
||||||
|
txt.nl()
|
||||||
|
array[5]-=2
|
||||||
|
txt.print_ub(array[5])
|
||||||
|
txt.spc()
|
||||||
|
array[5]+=2
|
||||||
|
txt.print_ub(array[5])
|
||||||
|
txt.nl()
|
||||||
|
array[5]-=3
|
||||||
|
txt.print_ub(array[5])
|
||||||
|
txt.spc()
|
||||||
|
array[5]+=3
|
||||||
|
txt.print_ub(array[5])
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
|
||||||
|
; cx16.r0L = 5
|
||||||
|
; ref[cx16.r0L]=10
|
||||||
|
; txt.print_ub(ref[cx16.r0L])
|
||||||
|
; txt.spc()
|
||||||
|
; ref[cx16.r0L]--
|
||||||
|
; txt.print_ub(ref[cx16.r0L])
|
||||||
|
; txt.spc()
|
||||||
|
; ref[cx16.r0L]++
|
||||||
|
; txt.print_ub(ref[cx16.r0L])
|
||||||
|
; txt.nl()
|
||||||
|
;
|
||||||
|
; uword @shared uw = 1000
|
||||||
|
; word @shared sw = -1000
|
||||||
|
;
|
||||||
|
; txt.print_uw(uw)
|
||||||
|
; txt.spc()
|
||||||
|
; uw++
|
||||||
|
; txt.print_uw(uw)
|
||||||
|
; txt.spc()
|
||||||
|
; uw--
|
||||||
|
; txt.print_uw(uw)
|
||||||
|
; txt.nl()
|
||||||
|
; uw = $00ff
|
||||||
|
; txt.print_uw(uw)
|
||||||
|
; txt.spc()
|
||||||
|
; uw++
|
||||||
|
; txt.print_uw(uw)
|
||||||
|
; txt.spc()
|
||||||
|
; uw--
|
||||||
|
; txt.print_uw(uw)
|
||||||
|
; txt.nl()
|
||||||
|
;
|
||||||
|
; txt.print_w(sw)
|
||||||
|
; txt.spc()
|
||||||
|
; sw++
|
||||||
|
; txt.print_w(sw)
|
||||||
|
; txt.spc()
|
||||||
|
; sw--
|
||||||
|
; txt.print_w(sw)
|
||||||
|
; txt.nl()
|
||||||
|
; sw = $00ff
|
||||||
|
; txt.print_w(sw)
|
||||||
|
; txt.spc()
|
||||||
|
; sw++
|
||||||
|
; txt.print_w(sw)
|
||||||
|
; txt.spc()
|
||||||
|
; sw--
|
||||||
|
; txt.print_w(sw)
|
||||||
|
; txt.nl()
|
||||||
|
; sw = -257
|
||||||
|
; txt.print_w(sw)
|
||||||
|
; txt.spc()
|
||||||
|
; sw++
|
||||||
|
; txt.print_w(sw)
|
||||||
|
; txt.spc()
|
||||||
|
; sw--
|
||||||
|
; txt.print_w(sw)
|
||||||
|
; txt.nl()
|
||||||
|
|
||||||
|
/*
|
||||||
|
seekerRef[SKR_X]-- this code looks very wrong with the pha/pla stuff
|
||||||
|
bulletRef[BD_Y]--/++
|
||||||
|
enemyRef[EN_MOVE_CNT]--/++
|
||||||
|
|
||||||
|
signed word--/++
|
||||||
|
unsigned word--/++
|
||||||
|
|
||||||
|
attackRef+=FIELD_COUNT
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user