mirror of
https://github.com/irmen/prog8.git
synced 2025-01-14 01:29:55 +00:00
fixed lines in assembly source optimizer
This commit is contained in:
parent
260fb65b06
commit
a03e36828a
@ -1990,6 +1990,38 @@ strcpy .proc
|
|||||||
.pend
|
.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
|
func_leftstr .proc
|
||||||
; leftstr(source, target, length) with params on stack
|
; leftstr(source, target, length) with params on stack
|
||||||
inx
|
inx
|
||||||
|
@ -6,4 +6,20 @@
|
|||||||
|
|
||||||
prog8_lib {
|
prog8_lib {
|
||||||
%asminclude "library:prog8_lib.asm", ""
|
%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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,17 +66,22 @@ internal class AsmGen(private val program: Program,
|
|||||||
block2asm(b)
|
block2asm(b)
|
||||||
footer()
|
footer()
|
||||||
|
|
||||||
|
val outputFile = outputDir.resolve("${program.name}.asm").toFile()
|
||||||
|
outputFile.printWriter().use {
|
||||||
|
for (line in assemblyLines) { it.println(line) }
|
||||||
|
}
|
||||||
|
|
||||||
if(optimize) {
|
if(optimize) {
|
||||||
|
assemblyLines.clear()
|
||||||
|
assemblyLines.addAll(outputFile.readLines())
|
||||||
var optimizationsDone = 1
|
var optimizationsDone = 1
|
||||||
while (optimizationsDone > 0) {
|
while (optimizationsDone > 0) {
|
||||||
optimizationsDone = optimizeAssembly(assemblyLines)
|
optimizationsDone = optimizeAssembly(assemblyLines)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val outputFile = outputDir.resolve("${program.name}.asm").toFile()
|
|
||||||
outputFile.printWriter().use {
|
outputFile.printWriter().use {
|
||||||
for (line in assemblyLines) { it.println(line) }
|
for (line in assemblyLines) { it.println(line) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return AssemblyProgram(program.name, outputDir)
|
return AssemblyProgram(program.name, outputDir)
|
||||||
}
|
}
|
||||||
|
@ -196,8 +196,8 @@ private fun optimizeStoreLoadSame(linesByFour: List<List<IndexedValue<String>>>)
|
|||||||
(first.startsWith("sty ") && second.startsWith("ldy ")) ||
|
(first.startsWith("sty ") && second.startsWith("ldy ")) ||
|
||||||
(first.startsWith("stx ") && second.startsWith("ldx "))
|
(first.startsWith("stx ") && second.startsWith("ldx "))
|
||||||
) {
|
) {
|
||||||
val firstLoc = first.substring(4)
|
val firstLoc = first.substring(4).trimStart()
|
||||||
val secondLoc = second.substring(4)
|
val secondLoc = second.substring(4).trimStart()
|
||||||
if (firstLoc == secondLoc) {
|
if (firstLoc == secondLoc) {
|
||||||
mods.add(Modification(pair[1].index, true, null))
|
mods.add(Modification(pair[1].index, true, null))
|
||||||
}
|
}
|
||||||
|
@ -168,12 +168,12 @@ class CallGraph(private val program: Program) : IAstVisitor {
|
|||||||
|
|
||||||
override fun visit(inlineAssembly: InlineAssembly) {
|
override fun visit(inlineAssembly: InlineAssembly) {
|
||||||
// parse inline asm for subroutine calls (jmp, jsr)
|
// parse inline asm for subroutine calls (jmp, jsr)
|
||||||
val scope = inlineAssembly.definingSubroutine()!!
|
val scope = inlineAssembly.definingSubroutine()
|
||||||
scanAssemblyCode(inlineAssembly.assembly, inlineAssembly, scope)
|
scanAssemblyCode(inlineAssembly.assembly, inlineAssembly, scope)
|
||||||
super.visit(inlineAssembly)
|
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 ->
|
asm.lines().forEach { line ->
|
||||||
val matches = asmJumpRx.matchEntire(line)
|
val matches = asmJumpRx.matchEntire(line)
|
||||||
if (matches != null) {
|
if (matches != null) {
|
||||||
@ -181,12 +181,14 @@ class CallGraph(private val program: Program) : IAstVisitor {
|
|||||||
if (jumptarget != null && (jumptarget[0].isLetter() || jumptarget[0] == '_')) {
|
if (jumptarget != null && (jumptarget[0].isLetter() || jumptarget[0] == '_')) {
|
||||||
val node = program.namespace.lookup(jumptarget.split('.'), context)
|
val node = program.namespace.lookup(jumptarget.split('.'), context)
|
||||||
if (node is Subroutine) {
|
if (node is Subroutine) {
|
||||||
|
if(scope!=null)
|
||||||
calls[scope] = calls.getValue(scope).plus(node)
|
calls[scope] = calls.getValue(scope).plus(node)
|
||||||
calledBy[node] = calledBy.getValue(node).plus(context)
|
calledBy[node] = calledBy.getValue(node).plus(context)
|
||||||
} else if (jumptarget.contains('.')) {
|
} else if (jumptarget.contains('.')) {
|
||||||
// maybe only the first part already refers to a subroutine
|
// maybe only the first part already refers to a subroutine
|
||||||
val node2 = program.namespace.lookup(listOf(jumptarget.substringBefore('.')), context)
|
val node2 = program.namespace.lookup(listOf(jumptarget.substringBefore('.')), context)
|
||||||
if (node2 is Subroutine) {
|
if (node2 is Subroutine) {
|
||||||
|
if(scope!=null)
|
||||||
calls[scope] = calls.getValue(scope).plus(node2)
|
calls[scope] = calls.getValue(scope).plus(node2)
|
||||||
calledBy[node2] = calledBy.getValue(node2).plus(context)
|
calledBy[node2] = calledBy.getValue(node2).plus(context)
|
||||||
}
|
}
|
||||||
@ -200,6 +202,7 @@ class CallGraph(private val program: Program) : IAstVisitor {
|
|||||||
if (target.contains('.')) {
|
if (target.contains('.')) {
|
||||||
val node = program.namespace.lookup(listOf(target.substringBefore('.')), context)
|
val node = program.namespace.lookup(listOf(target.substringBefore('.')), context)
|
||||||
if (node is Subroutine) {
|
if (node is Subroutine) {
|
||||||
|
if(scope!=null)
|
||||||
calls[scope] = calls.getValue(scope).plus(node)
|
calls[scope] = calls.getValue(scope).plus(node)
|
||||||
calledBy[node] = calledBy.getValue(node).plus(context)
|
calledBy[node] = calledBy.getValue(node).plus(context)
|
||||||
}
|
}
|
||||||
|
@ -13,58 +13,22 @@ main {
|
|||||||
str hex4 = "aap3333"
|
str hex4 = "aap3333"
|
||||||
|
|
||||||
byte result
|
byte result
|
||||||
result = strcmp(hex1, hex1)
|
result = prog8_lib.strcmp(hex1, hex1)
|
||||||
txt.print_b(result)
|
txt.print_b(result)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
result = strcmp(hex1, hex2)
|
result = prog8_lib.strcmp(hex1, hex2)
|
||||||
txt.print_b(result)
|
txt.print_b(result)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
result = strcmp(hex1, hex3)
|
result = prog8_lib.strcmp(hex1, hex3)
|
||||||
txt.print_b(result)
|
txt.print_b(result)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
result = strcmp(hex1, hex4)
|
result = prog8_lib.strcmp(hex1, hex4)
|
||||||
txt.print_b(result)
|
txt.print_b(result)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
|
||||||
testX()
|
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() {
|
asmsub testX() {
|
||||||
%asm {{
|
%asm {{
|
||||||
stx _saveX
|
stx _saveX
|
||||||
|
Loading…
x
Reference in New Issue
Block a user