mirror of
https://github.com/irmen/prog8.git
synced 2026-10-22 20:02:27 +00:00
229 lines
7.5 KiB
Kotlin
229 lines
7.5 KiB
Kotlin
package prog8tests.compiler
|
|
|
|
import io.kotest.core.spec.style.FunSpec
|
|
import io.kotest.engine.spec.tempdir
|
|
import io.kotest.matchers.string.shouldContain
|
|
import prog8.code.target.VMTarget
|
|
import prog8tests.helpers.compileText
|
|
import kotlin.io.path.readText
|
|
|
|
class TestInplaceOptimization: FunSpec({
|
|
val outputDir = tempdir().toPath()
|
|
|
|
test("array shift right in-place with variable index") {
|
|
val src = """
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
main {
|
|
ubyte[] arr = [8, 16, 32, 64]
|
|
ubyte @shared result
|
|
sub start() {
|
|
ubyte @shared idx = 2
|
|
ubyte @shared sh = 1
|
|
arr[idx] >>= sh
|
|
result = arr[idx]
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
|
val ir = outputDir.resolve(result.compilerAst.name + ".p8ir").readText()
|
|
ir shouldContain "loadx.b"
|
|
ir shouldContain "lsrn.b"
|
|
ir shouldContain "storex.b"
|
|
}
|
|
|
|
test("array shift left in-place with variable index") {
|
|
val src = """
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
main {
|
|
ubyte[] arr = [1, 2, 4, 8]
|
|
ubyte @shared result
|
|
sub start() {
|
|
ubyte @shared idx = 1
|
|
arr[idx] <<= 2
|
|
result = arr[idx]
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
|
val ir = outputDir.resolve(result.compilerAst.name + ".p8ir").readText()
|
|
ir shouldContain "loadx.b"
|
|
ir shouldContain "lsln.b"
|
|
ir shouldContain "storex.b"
|
|
}
|
|
|
|
test("array multiply in-place with variable index") {
|
|
val src = """
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
main {
|
|
ubyte[] arr = [1, 2, 4, 8]
|
|
ubyte @shared result
|
|
sub start() {
|
|
ubyte @shared idx = 2
|
|
arr[idx] *= 3
|
|
result = arr[idx]
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
|
val ir = outputDir.resolve(result.compilerAst.name + ".p8ir").readText()
|
|
ir shouldContain "loadx.b"
|
|
ir shouldContain "mul.b"
|
|
ir shouldContain "storex.b"
|
|
}
|
|
|
|
test("array divide in-place with variable index") {
|
|
val src = """
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
main {
|
|
ubyte[] arr = [8, 16, 32, 64]
|
|
ubyte @shared result
|
|
sub start() {
|
|
ubyte @shared idx = 2
|
|
arr[idx] /= 3
|
|
result = arr[idx]
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
|
val ir = outputDir.resolve(result.compilerAst.name + ".p8ir").readText()
|
|
ir shouldContain "loadx.b"
|
|
ir shouldContain "div.b"
|
|
ir shouldContain "storex.b"
|
|
}
|
|
|
|
test("array modulo in-place with variable index") {
|
|
val src = """
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
main {
|
|
ubyte[] arr = [8, 16, 32, 64]
|
|
ubyte @shared result
|
|
sub start() {
|
|
ubyte @shared idx = 2
|
|
arr[idx] %= 6
|
|
result = arr[idx]
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
|
val ir = outputDir.resolve(result.compilerAst.name + ".p8ir").readText()
|
|
ir shouldContain "loadx.b"
|
|
ir shouldContain "mod.b"
|
|
ir shouldContain "storex.b"
|
|
}
|
|
|
|
test("memory multiply in-place with variable address") {
|
|
val src = $$"""
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
main {
|
|
uword @shared ptr
|
|
ubyte @shared result
|
|
sub start() {
|
|
ptr = $c000
|
|
@(ptr) = 5
|
|
@(ptr) *= 3
|
|
result = @(ptr)
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
|
val ir = outputDir.resolve(result.compilerAst.name + ".p8ir").readText()
|
|
ir shouldContain "loadi.b"
|
|
ir shouldContain "mul.b"
|
|
ir shouldContain "storei.b"
|
|
}
|
|
|
|
test("memory divide in-place with variable address") {
|
|
val src = $$"""
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
main {
|
|
uword @shared ptr
|
|
ubyte @shared result
|
|
sub start() {
|
|
ptr = $c000
|
|
@(ptr) = 20
|
|
@(ptr) /= 3
|
|
result = @(ptr)
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
|
val ir = outputDir.resolve(result.compilerAst.name + ".p8ir").readText()
|
|
ir shouldContain "loadi.b"
|
|
ir shouldContain "div.b"
|
|
ir shouldContain "storei.b"
|
|
}
|
|
|
|
test("memory modulo in-place with variable address") {
|
|
val src = $$"""
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
main {
|
|
uword @shared ptr
|
|
ubyte @shared result
|
|
sub start() {
|
|
ptr = $c000
|
|
@(ptr) = 20
|
|
@(ptr) %= 6
|
|
result = @(ptr)
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
|
val ir = outputDir.resolve(result.compilerAst.name + ".p8ir").readText()
|
|
ir shouldContain "loadi.b"
|
|
ir shouldContain "mod.b"
|
|
ir shouldContain "storei.b"
|
|
}
|
|
|
|
test("memory shift right in-place with variable address") {
|
|
val src = $$"""
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
main {
|
|
uword @shared ptr
|
|
ubyte @shared result
|
|
sub start() {
|
|
ptr = $c000
|
|
@(ptr) = 16
|
|
@(ptr) >>= 1
|
|
result = @(ptr)
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
|
val ir = outputDir.resolve(result.compilerAst.name + ".p8ir").readText()
|
|
ir shouldContain "loadi.b"
|
|
ir shouldContain "lsr.b"
|
|
ir shouldContain "storei.b"
|
|
}
|
|
|
|
test("memory shift left in-place with variable address") {
|
|
val src = $$"""
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
main {
|
|
uword @shared ptr
|
|
ubyte @shared result
|
|
sub start() {
|
|
ptr = $c000
|
|
@(ptr) = 4
|
|
@(ptr) <<= 1
|
|
result = @(ptr)
|
|
}
|
|
}
|
|
""".trimIndent()
|
|
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
|
|
val ir = outputDir.resolve(result.compilerAst.name + ".p8ir").readText()
|
|
ir shouldContain "loadi.b"
|
|
ir shouldContain "lsl.b"
|
|
ir shouldContain "storei.b"
|
|
}
|
|
})
|