Skip to content

Commit e6079df

Browse files
committed
don't always use pha/pla in pointer expression code
1 parent 2b435fe commit e6079df

File tree

2 files changed

+42
-28
lines changed

2 files changed

+42
-28
lines changed

compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,39 +1407,44 @@ $label nop""")
14071407

14081408
internal fun tryOptimizedPointerAccessWithA(expr: BinaryExpression, write: Boolean): Boolean {
14091409
// optimize pointer,indexregister if possible
1410+
1411+
fun evalBytevalueWillClobberA(expr: Expression): Boolean {
1412+
val dt = expr.inferType(program)
1413+
if(!dt.istype(DataType.UBYTE) && !dt.istype(DataType.BYTE))
1414+
return true
1415+
return when(expr) {
1416+
is IdentifierReference -> false
1417+
is NumericLiteralValue -> false
1418+
is DirectMemoryRead -> expr.addressExpression !is IdentifierReference && expr.addressExpression !is NumericLiteralValue
1419+
is TypecastExpression -> evalBytevalueWillClobberA(expr.expression)
1420+
else -> true
1421+
}
1422+
}
1423+
1424+
14101425
if(expr.operator=="+") {
14111426
val ptrAndIndex = pointerViaIndexRegisterPossible(expr)
14121427
if(ptrAndIndex!=null) {
14131428
val pointervar = ptrAndIndex.first as? IdentifierReference
14141429
if(write) {
1415-
when(ptrAndIndex.second) {
1416-
is NumericLiteralValue, is IdentifierReference -> {
1417-
if(pointervar!=null && isZpVar(pointervar)) {
1418-
out(" pha")
1419-
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
1420-
out(" pla | sta (${asmSymbolName(pointervar)}),y")
1421-
} else {
1422-
// copy the pointer var to zp first
1423-
out(" pha")
1424-
assignExpressionToVariable(ptrAndIndex.first, asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
1425-
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
1426-
out(" pla | sta (P8ZP_SCRATCH_W2),y")
1427-
}
1428-
}
1429-
else -> {
1430-
// same as above but we need to save the A register
1431-
if(pointervar!=null && isZpVar(pointervar)) {
1432-
out(" pha")
1433-
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
1434-
out(" pla | sta (${asmSymbolName(pointervar)}),y")
1435-
} else {
1436-
// copy the pointer var to zp first
1437-
assignExpressionToVariable(ptrAndIndex.first, asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
1438-
out(" pha")
1439-
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
1440-
out(" pla | sta (P8ZP_SCRATCH_W2),y")
1441-
}
1442-
}
1430+
if(pointervar!=null && isZpVar(pointervar)) {
1431+
val saveA = evalBytevalueWillClobberA(ptrAndIndex.second)
1432+
if(saveA)
1433+
out(" pha")
1434+
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
1435+
if(saveA)
1436+
out(" pla")
1437+
out(" sta (${asmSymbolName(pointervar)}),y")
1438+
} else {
1439+
// copy the pointer var to zp first
1440+
val saveA = evalBytevalueWillClobberA(ptrAndIndex.first) || evalBytevalueWillClobberA(ptrAndIndex.second)
1441+
if(saveA)
1442+
out(" pha")
1443+
assignExpressionToVariable(ptrAndIndex.first, asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
1444+
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
1445+
if(saveA)
1446+
out(" pla")
1447+
out(" sta (P8ZP_SCRATCH_W2),y")
14431448
}
14441449
} else {
14451450
if(pointervar!=null && isZpVar(pointervar)) {

examples/test.p8

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
main {
55

66
sub start() {
7+
uword screen = 2000
8+
ubyte i = 1
9+
uword w = 33
10+
str derp ="derp"
11+
ubyte[] array = [1,2,3]
12+
13+
@(screen+i) = 128
14+
@(i+screen) = 129
15+
716
txt.print("done\n")
817
}
918
}

0 commit comments

Comments
 (0)