@@ -623,7 +623,7 @@ class AsmGen6502Internal (
623623 is PtJump -> {
624624 val target = getJumpTarget(stmt)
625625 require(! target.needsExpressionEvaluation)
626- jmp(target.asmLabel, target.indirect)
626+ jmp(target.asmLabel, target.indirect, target.indexedX )
627627 }
628628 is PtLabel -> translate(stmt)
629629 is PtConditionalBranch -> translate(stmt)
@@ -1066,28 +1066,36 @@ $repeatLabel""")
10661066 }
10671067 }
10681068
1069- class JumpTarget (val asmLabel : String , val indirect : Boolean , val needsExpressionEvaluation : Boolean )
1069+ class JumpTarget (val asmLabel : String , val indirect : Boolean , val indexedX : Boolean , val needsExpressionEvaluation : Boolean )
10701070
10711071 internal fun getJumpTarget (jump : PtJump , evaluateAddressExpression : Boolean = true): JumpTarget {
10721072 val ident = jump.target as ? PtIdentifier
10731073 if (ident!= null ) {
10741074 // can be a label, or a pointer variable
10751075 val symbol = symbolTable.lookup(ident.name)
10761076 return if (symbol?.type in arrayOf(StNodeType .STATICVAR , StNodeType .MEMVAR , StNodeType .CONSTANT ))
1077- JumpTarget (asmSymbolName(ident), true , false ) // indirect jump if the jump symbol is a variable
1077+ JumpTarget (asmSymbolName(ident), true , false , false ) // indirect jump if the jump symbol is a variable
10781078 else
1079- JumpTarget (asmSymbolName(ident), false , false )
1079+ JumpTarget (asmSymbolName(ident), false , false , false )
10801080 }
10811081 val addr = jump.target.asConstInteger()
10821082 if (addr!= null )
1083- return JumpTarget (addr.toHex(), false , false )
1083+ return JumpTarget (addr.toHex(), false , false , false )
10841084 else {
10851085 if (evaluateAddressExpression) {
1086+ val arrayIdx = jump.target as ? PtArrayIndexer
1087+ if (arrayIdx!= null && ! arrayIdx.splitWords) {
1088+ // if the jump target is an address in a non-split array (like a jump table of only pointers),
1089+ // more optimal assembly can be generated using JMP address,X
1090+ assignExpressionToRegister(arrayIdx.index, RegisterOrPair .A )
1091+ out (" asl a | tax" )
1092+ return JumpTarget (asmSymbolName(arrayIdx.variable), true , true , false )
1093+ }
10861094 // we can do the address evaluation right now and just use a temporary pointer variable
10871095 assignExpressionToVariable(jump.target, " P8ZP_SCRATCH_W1" , DataType .UWORD )
1088- return JumpTarget (" P8ZP_SCRATCH_W1" , true , false )
1096+ return JumpTarget (" P8ZP_SCRATCH_W1" , true , false , false )
10891097 } else {
1090- return JumpTarget (" PROG8_JUMP_TARGET_IS_UNEVALUATED_ADDRESS_EXPRESSION" , true , true )
1098+ return JumpTarget (" PROG8_JUMP_TARGET_IS_UNEVALUATED_ADDRESS_EXPRESSION" , true , false , true )
10911099 }
10921100 }
10931101 }
@@ -1207,10 +1215,14 @@ $repeatLabel""")
12071215
12081216 internal fun isZpVar (variable : PtIdentifier ): Boolean = allocator.isZpVar(variable.name)
12091217
1210- internal fun jmp (asmLabel : String , indirect : Boolean =false) {
1218+ internal fun jmp (asmLabel : String , indirect : Boolean =false, indexedX : Boolean =false ) {
12111219 if (indirect) {
1212- out (" jmp ($asmLabel )" )
1220+ if (indexedX)
1221+ out (" jmp ($asmLabel ,x)" )
1222+ else
1223+ out (" jmp ($asmLabel )" )
12131224 } else {
1225+ require(! indexedX) { " indexedX only allowed for indirect jumps" }
12141226 if (isTargetCpu(CpuType .CPU65C02 ))
12151227 out (" bra $asmLabel " ) // note: 64tass will convert this automatically to a jmp if the relative distance is too large
12161228 else
0 commit comments