mirror of
https://github.com/irmen/prog8.git
synced 2025-01-14 01:29:55 +00:00
fixed missing code for certain memread expressions when casted to uword
This commit is contained in:
parent
4ed7fb771c
commit
055f917a2e
@ -196,16 +196,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
if (what.addressExpression is NumericLiteralValue) {
|
if (what.addressExpression is NumericLiteralValue) {
|
||||||
val number = (what.addressExpression as NumericLiteralValue).number
|
val number = (what.addressExpression as NumericLiteralValue).number
|
||||||
asmgen.out(" lda ${number.toHex()} | lsr a | bcc + | ora #\$80 |+ | sta ${number.toHex()}")
|
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 {
|
} else {
|
||||||
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
||||||
asmgen.out(" jsr prog8_lib.ror2_mem_ub")
|
asmgen.out(" jsr prog8_lib.ror2_mem_ub")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
is IdentifierReference -> {
|
is IdentifierReference -> {
|
||||||
val variable = asmgen.asmVariableName(what)
|
val variable = asmgen.asmVariableName(what)
|
||||||
asmgen.out(" lda $variable | lsr a | bcc + | ora #\$80 |+ | sta $variable")
|
asmgen.out(" lda $variable | lsr a | bcc + | ora #\$80 |+ | sta $variable")
|
||||||
@ -247,7 +242,14 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
} else {
|
} else {
|
||||||
val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(what.addressExpression)
|
val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(what.addressExpression)
|
||||||
if(ptrAndIndex!=null) {
|
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 {
|
} else {
|
||||||
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -295,16 +297,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
if (what.addressExpression is NumericLiteralValue) {
|
if (what.addressExpression is NumericLiteralValue) {
|
||||||
val number = (what.addressExpression as NumericLiteralValue).number
|
val number = (what.addressExpression as NumericLiteralValue).number
|
||||||
asmgen.out(" lda ${number.toHex()} | cmp #\$80 | rol a | sta ${number.toHex()}")
|
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 {
|
} else {
|
||||||
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
||||||
asmgen.out(" jsr prog8_lib.rol2_mem_ub")
|
asmgen.out(" jsr prog8_lib.rol2_mem_ub")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
is IdentifierReference -> {
|
is IdentifierReference -> {
|
||||||
val variable = asmgen.asmVariableName(what)
|
val variable = asmgen.asmVariableName(what)
|
||||||
asmgen.out(" lda $variable | cmp #\$80 | rol a | sta $variable")
|
asmgen.out(" lda $variable | cmp #\$80 | rol a | sta $variable")
|
||||||
@ -346,7 +343,14 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
} else {
|
} else {
|
||||||
val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(what.addressExpression)
|
val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(what.addressExpression)
|
||||||
if(ptrAndIndex!=null) {
|
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 {
|
} else {
|
||||||
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
asmgen.assignExpressionToRegister(what.addressExpression, RegisterOrPair.AY)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -530,6 +534,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
|
|
||||||
// optimized simple case: swap two memory locations
|
// optimized simple case: swap two memory locations
|
||||||
if(first is DirectMemoryRead && second is DirectMemoryRead) {
|
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 addr1 = (first.addressExpression as? NumericLiteralValue)?.number?.toHex()
|
||||||
val addr2 = (second.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
|
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
|
// 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 {
|
fun targetFromExpr(expr: Expression, datatype: DataType): AsmAssignTarget {
|
||||||
return when (expr) {
|
return when (expr) {
|
||||||
|
@ -309,6 +309,16 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
is DirectMemoryRead -> {
|
is DirectMemoryRead -> {
|
||||||
if(targetDt in WordDatatypes) {
|
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) {
|
when (value.addressExpression) {
|
||||||
is NumericLiteralValue -> {
|
is NumericLiteralValue -> {
|
||||||
val address = (value.addressExpression as NumericLiteralValue).number.toInt()
|
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)
|
assignMemoryByteIntoWord(target, null, value.addressExpression as IdentifierReference)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
is BinaryExpression -> {
|
||||||
|
if(asmgen.tryOptimizedPointerAccessWithA(value.addressExpression as BinaryExpression, false)) {
|
||||||
|
asmgen.out(" ldy #0")
|
||||||
|
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||||
|
} else {
|
||||||
|
assignViaExprEval(value.addressExpression)
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> {
|
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}")
|
asmgen.out(" st${register.name.toLowerCase()} ${target.asmVarname}")
|
||||||
}
|
}
|
||||||
TargetStorageKind.MEMORY -> {
|
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 -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
if (target.constArrayIndexValue!=null) {
|
if (target.constArrayIndexValue!=null) {
|
||||||
|
@ -2,14 +2,16 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- optimize pointer access @(ptr+ix) if ix<=255 (i.e. if it is of ubyte type) to use indexing register
|
- [pointer-index-optimize branch] fix imageviewer color cycling on champagne and weathermap iff images
|
||||||
- add any2(), all2(), max2(), min2(), reverse2(), sum2(), sort2() that take (array, startindex, length) arguments
|
|
||||||
- allow uwordpointer[index] syntax -> transform into @(uwordpointer+index) allow index to be >255!
|
- 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 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
|
- 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?
|
- 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
|
- 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)
|
- 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 '_'
|
- 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)
|
- 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 ix = 0
|
||||||
ubyte cc
|
ubyte cc = 0
|
||||||
|
|
||||||
|
@(screen) = 1
|
||||||
|
@(screen+1) = 2
|
||||||
|
swap(@(screen), @(screen+1))
|
||||||
|
|
||||||
; cc = @(screen+2)
|
; cc = @(screen+2)
|
||||||
; cc++
|
; cc++
|
||||||
; @(screen+2) = cc
|
; @(screen+2) = cc
|
||||||
|
|
||||||
@(screen + ix + cc*$0008) = cc
|
|
||||||
|
|
||||||
; cc = @(screen+ix)
|
; cc = @(screen+ix)
|
||||||
; cc++
|
; cc++
|
||||||
; @(screen+ix) = cc
|
; @(screen+ix) = cc
|
||||||
|
Loading…
x
Reference in New Issue
Block a user