mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
fixed missing code for certain memread expressions when casted to uword
This commit is contained in:
parent
4ed7fb771c
commit
055f917a2e
@ -197,13 +197,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
val number = (what.addressExpression as NumericLiteralValue).number
|
||||
asmgen.out(" lda ${number.toHex()} | lsr a | bcc + | ora #\$80 |+ | sta ${number.toHex()}")
|
||||
} else {
|
||||
val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(what.addressExpression)
|
||||
if(ptrAndIndex!=null) {
|
||||
TODO("memread via pointer+indexregister ${ptrAndIndex.first},${ptrAndIndex.second}")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
||||
asmgen.out(" jsr prog8_lib.ror2_mem_ub")
|
||||
}
|
||||
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
||||
asmgen.out(" jsr prog8_lib.ror2_mem_ub")
|
||||
}
|
||||
}
|
||||
is IdentifierReference -> {
|
||||
@ -247,7 +242,14 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
} else {
|
||||
val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(what.addressExpression)
|
||||
if(ptrAndIndex!=null) {
|
||||
TODO("memread via pointer+indexregister ${ptrAndIndex.first},${ptrAndIndex.second}")
|
||||
asmgen.assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.X)
|
||||
asmgen.saveRegisterLocal(CpuRegister.X, (fcall as FunctionCallStatement).definingSubroutine()!!)
|
||||
asmgen.assignExpressionToRegister(ptrAndIndex.first, RegisterOrPair.AY)
|
||||
asmgen.restoreRegisterLocal(CpuRegister.X)
|
||||
asmgen.out("""
|
||||
sta (+) + 1
|
||||
sty (+) + 2
|
||||
+ ror ${'$'}ffff,x ; modified""")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
||||
asmgen.out("""
|
||||
@ -296,13 +298,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
val number = (what.addressExpression as NumericLiteralValue).number
|
||||
asmgen.out(" lda ${number.toHex()} | cmp #\$80 | rol a | sta ${number.toHex()}")
|
||||
} else {
|
||||
val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(what.addressExpression)
|
||||
if(ptrAndIndex!=null) {
|
||||
TODO("memread via pointer+indexregister ${ptrAndIndex.first},${ptrAndIndex.second}")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
||||
asmgen.out(" jsr prog8_lib.rol2_mem_ub")
|
||||
}
|
||||
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
||||
asmgen.out(" jsr prog8_lib.rol2_mem_ub")
|
||||
}
|
||||
}
|
||||
is IdentifierReference -> {
|
||||
@ -346,7 +343,14 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
} else {
|
||||
val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(what.addressExpression)
|
||||
if(ptrAndIndex!=null) {
|
||||
TODO("memread via pointer+indexregister ${ptrAndIndex.first},${ptrAndIndex.second}")
|
||||
asmgen.assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.X)
|
||||
asmgen.saveRegisterLocal(CpuRegister.X, (fcall as FunctionCallStatement).definingSubroutine()!!)
|
||||
asmgen.assignExpressionToRegister(ptrAndIndex.first, RegisterOrPair.AY)
|
||||
asmgen.restoreRegisterLocal(CpuRegister.X)
|
||||
asmgen.out("""
|
||||
sta (+) + 1
|
||||
sty (+) + 2
|
||||
+ rol ${'$'}ffff,x ; modified""")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
||||
asmgen.out("""
|
||||
@ -530,6 +534,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
|
||||
// optimized simple case: swap two memory locations
|
||||
if(first is DirectMemoryRead && second is DirectMemoryRead) {
|
||||
// TODO optimize swap of two memread values with index, using the same pointer expression/variable, like swap(@(ptr+1), @(ptr+2))
|
||||
val addr1 = (first.addressExpression as? NumericLiteralValue)?.number?.toHex()
|
||||
val addr2 = (second.addressExpression as? NumericLiteralValue)?.number?.toHex()
|
||||
val name1 = if(first.addressExpression is IdentifierReference) asmgen.asmVariableName(first.addressExpression as IdentifierReference) else null
|
||||
@ -584,7 +589,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
}
|
||||
|
||||
// all other types of swap() calls are done via a temporary variable
|
||||
// TODO optimize swapping of pointer+indexregister
|
||||
|
||||
fun targetFromExpr(expr: Expression, datatype: DataType): AsmAssignTarget {
|
||||
return when (expr) {
|
||||
|
@ -309,6 +309,16 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
is DirectMemoryRead -> {
|
||||
if(targetDt in WordDatatypes) {
|
||||
|
||||
fun assignViaExprEval(addressExpression: Expression) {
|
||||
asmgen.assignExpressionToVariable(addressExpression, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
|
||||
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02)
|
||||
asmgen.out(" lda (P8ZP_SCRATCH_W2)")
|
||||
else
|
||||
asmgen.out(" ldy #0 | lda (P8ZP_SCRATCH_W2),y")
|
||||
assignRegisterByte(target, CpuRegister.A)
|
||||
}
|
||||
|
||||
when (value.addressExpression) {
|
||||
is NumericLiteralValue -> {
|
||||
val address = (value.addressExpression as NumericLiteralValue).number.toInt()
|
||||
@ -319,8 +329,16 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
assignMemoryByteIntoWord(target, null, value.addressExpression as IdentifierReference)
|
||||
return
|
||||
}
|
||||
is BinaryExpression -> {
|
||||
if(asmgen.tryOptimizedPointerAccessWithA(value.addressExpression as BinaryExpression, false)) {
|
||||
asmgen.out(" ldy #0")
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
} else {
|
||||
assignViaExprEval(value.addressExpression)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
TODO("memread from expression ${value.addressExpression}")
|
||||
assignViaExprEval(value.addressExpression)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1322,7 +1340,12 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
asmgen.out(" st${register.name.toLowerCase()} ${target.asmVarname}")
|
||||
}
|
||||
TargetStorageKind.MEMORY -> {
|
||||
TODO("assignRegisterByte via storeByteViaRegisterAInMemoryAddress()")
|
||||
when(register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
|
@ -2,14 +2,16 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- optimize pointer access @(ptr+ix) if ix<=255 (i.e. if it is of ubyte type) to use indexing register
|
||||
- add any2(), all2(), max2(), min2(), reverse2(), sum2(), sort2() that take (array, startindex, length) arguments
|
||||
- [pointer-index-optimize branch] fix imageviewer color cycling on champagne and weathermap iff images
|
||||
- allow uwordpointer[index] syntax -> transform into @(uwordpointer+index) allow index to be >255!
|
||||
- add any2(), all2(), max2(), min2(), reverse2(), sum2(), sort2() that take (array, startindex, length) arguments
|
||||
- optimize for loop iterations better to allow proper inx, cpx #value, bne loop instructions
|
||||
- optimize swap of two memread values with index, using the same pointer expression/variable, like swap(@(ptr+1), @(ptr+2))
|
||||
|
||||
- can we get rid of the --longOptionName command line options and only keep the short versions? https://github.com/Kotlin/kotlinx-cli/issues/50
|
||||
- add a f_seek() routine for the Cx16 that uses its seek dos api?
|
||||
- optimizer: detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation
|
||||
- add a compiler option to not remove unused subroutines. this allows for building library programs
|
||||
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
|
||||
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
|
||||
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
|
||||
|
@ -13,14 +13,16 @@ main {
|
||||
|
||||
|
||||
ubyte ix = 0
|
||||
ubyte cc
|
||||
ubyte cc = 0
|
||||
|
||||
@(screen) = 1
|
||||
@(screen+1) = 2
|
||||
swap(@(screen), @(screen+1))
|
||||
|
||||
; cc = @(screen+2)
|
||||
; cc++
|
||||
; @(screen+2) = cc
|
||||
|
||||
@(screen + ix + cc*$0008) = cc
|
||||
|
||||
; cc = @(screen+ix)
|
||||
; cc++
|
||||
; @(screen+ix) = cc
|
||||
|
Loading…
Reference in New Issue
Block a user