fixed lines in assembly source optimizer

This commit is contained in:
Irmen de Jong 2020-10-16 01:12:20 +02:00
parent 260fb65b06
commit a03e36828a
6 changed files with 72 additions and 52 deletions

View File

@ -1990,6 +1990,38 @@ strcpy .proc
.pend
strcmp_mem .proc
; -- compares strings in s1 (AY) and s2 (PZP_SCRATCH_W2).
; Returns -1,0,1 in A, depeding on the ordering. Clobbers Y.
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
_loop ldy #0
lda (P8ZP_SCRATCH_W1),y
bne +
lda (P8ZP_SCRATCH_W2),y
bne _return_minusone
beq _return
+ lda (P8ZP_SCRATCH_W2),y
sec
sbc (P8ZP_SCRATCH_W1),y
bmi _return_one
bne _return_minusone
inc P8ZP_SCRATCH_W1
bne +
inc P8ZP_SCRATCH_W1+1
+ inc P8ZP_SCRATCH_W2
bne _loop
inc P8ZP_SCRATCH_W2+1
bne _loop
_return_one
lda #1
_return rts
_return_minusone
lda #-1
rts
.pend
func_leftstr .proc
; leftstr(source, target, length) with params on stack
inx

View File

@ -6,4 +6,20 @@
prog8_lib {
%asminclude "library:prog8_lib.asm", ""
sub strcmp(uword s1, uword s2) -> byte {
; -- convenience wrapper for plain Prog8 to compare strings TODO turn this into a builtin function
byte result
%asm {{
lda s2
sta P8ZP_SCRATCH_W2
lda s2+1
sta P8ZP_SCRATCH_W2+1
lda s1
ldy s1+1
jsr prog8_lib.strcmp_mem
sta result
}}
return result
}
}

View File

@ -66,17 +66,22 @@ internal class AsmGen(private val program: Program,
block2asm(b)
footer()
val outputFile = outputDir.resolve("${program.name}.asm").toFile()
outputFile.printWriter().use {
for (line in assemblyLines) { it.println(line) }
}
if(optimize) {
assemblyLines.clear()
assemblyLines.addAll(outputFile.readLines())
var optimizationsDone = 1
while (optimizationsDone > 0) {
optimizationsDone = optimizeAssembly(assemblyLines)
}
}
val outputFile = outputDir.resolve("${program.name}.asm").toFile()
outputFile.printWriter().use {
for (line in assemblyLines) { it.println(line) }
}
}
return AssemblyProgram(program.name, outputDir)
}

View File

@ -196,8 +196,8 @@ private fun optimizeStoreLoadSame(linesByFour: List<List<IndexedValue<String>>>)
(first.startsWith("sty ") && second.startsWith("ldy ")) ||
(first.startsWith("stx ") && second.startsWith("ldx "))
) {
val firstLoc = first.substring(4)
val secondLoc = second.substring(4)
val firstLoc = first.substring(4).trimStart()
val secondLoc = second.substring(4).trimStart()
if (firstLoc == secondLoc) {
mods.add(Modification(pair[1].index, true, null))
}

View File

@ -168,12 +168,12 @@ class CallGraph(private val program: Program) : IAstVisitor {
override fun visit(inlineAssembly: InlineAssembly) {
// parse inline asm for subroutine calls (jmp, jsr)
val scope = inlineAssembly.definingSubroutine()!!
val scope = inlineAssembly.definingSubroutine()
scanAssemblyCode(inlineAssembly.assembly, inlineAssembly, scope)
super.visit(inlineAssembly)
}
private fun scanAssemblyCode(asm: String, context: Statement, scope: Subroutine) {
private fun scanAssemblyCode(asm: String, context: Statement, scope: Subroutine?) {
asm.lines().forEach { line ->
val matches = asmJumpRx.matchEntire(line)
if (matches != null) {
@ -181,12 +181,14 @@ class CallGraph(private val program: Program) : IAstVisitor {
if (jumptarget != null && (jumptarget[0].isLetter() || jumptarget[0] == '_')) {
val node = program.namespace.lookup(jumptarget.split('.'), context)
if (node is Subroutine) {
if(scope!=null)
calls[scope] = calls.getValue(scope).plus(node)
calledBy[node] = calledBy.getValue(node).plus(context)
} else if (jumptarget.contains('.')) {
// maybe only the first part already refers to a subroutine
val node2 = program.namespace.lookup(listOf(jumptarget.substringBefore('.')), context)
if (node2 is Subroutine) {
if(scope!=null)
calls[scope] = calls.getValue(scope).plus(node2)
calledBy[node2] = calledBy.getValue(node2).plus(context)
}
@ -200,6 +202,7 @@ class CallGraph(private val program: Program) : IAstVisitor {
if (target.contains('.')) {
val node = program.namespace.lookup(listOf(target.substringBefore('.')), context)
if (node is Subroutine) {
if(scope!=null)
calls[scope] = calls.getValue(scope).plus(node)
calledBy[node] = calledBy.getValue(node).plus(context)
}

View File

@ -13,58 +13,22 @@ main {
str hex4 = "aap3333"
byte result
result = strcmp(hex1, hex1)
result = prog8_lib.strcmp(hex1, hex1)
txt.print_b(result)
txt.chrout('\n')
result = strcmp(hex1, hex2)
result = prog8_lib.strcmp(hex1, hex2)
txt.print_b(result)
txt.chrout('\n')
result = strcmp(hex1, hex3)
result = prog8_lib.strcmp(hex1, hex3)
txt.print_b(result)
txt.chrout('\n')
result = strcmp(hex1, hex4)
result = prog8_lib.strcmp(hex1, hex4)
txt.print_b(result)
txt.chrout('\n')
testX()
}
sub strcmp(uword s1, uword s2) -> byte {
byte result = 0
%asm {{
_loop ldy #0
lda (s1),y
bne +
lda (s2),y
bne _return_minusone
beq _return
+ lda (s2),y
sec
sbc (s1),y
bmi _return_one
bne _return_minusone
inc s1
bne +
inc s1+1
+ inc s2
bne _loop
inc s2+1
bne _loop
_return_one
ldy #1
sty result
bne _return
_return_minusone
ldy #-1
sty result
_return
}}
return result
}
asmsub testX() {
%asm {{
stx _saveX