enable more optimizations for typecasted assignments. Fixed missing codegen for assigning bytes to words in certain cases.

This commit is contained in:
Irmen de Jong 2022-01-27 18:05:25 +01:00
parent fa48746ba9
commit 5ecf2a3357
7 changed files with 127 additions and 27 deletions

View File

@ -1584,6 +1584,16 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
null, RegisterOrPair.A -> asmgen.out(" lda $sourceName+1")
RegisterOrPair.X -> asmgen.out(" ldx $sourceName+1")
RegisterOrPair.Y -> asmgen.out(" ldy $sourceName+1")
RegisterOrPair.AX -> asmgen.out(" lda $sourceName+1 | ldx #0")
RegisterOrPair.AY -> asmgen.out(" lda $sourceName+1 | ldy #0")
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName+1 | ldy #0")
in Cx16VirtualRegisters -> {
val regname = resultRegister.name.lowercase()
if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" lda $sourceName+1 | sta cx16.$regname | stz cx16.$regname+1")
else
asmgen.out(" lda $sourceName+1 | sta cx16.$regname | lda #0 | sta cx16.$regname+1")
}
else -> throw AssemblyError("invalid reg")
}
}
@ -1629,6 +1639,16 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
null, RegisterOrPair.A -> asmgen.out(" lda $sourceName")
RegisterOrPair.X -> asmgen.out(" ldx $sourceName")
RegisterOrPair.Y -> asmgen.out(" ldy $sourceName")
RegisterOrPair.AX -> asmgen.out(" lda $sourceName | ldx #0")
RegisterOrPair.AY -> asmgen.out(" lda $sourceName | ldy #0")
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName | ldy #0")
in Cx16VirtualRegisters -> {
val regname = resultRegister.name.lowercase()
if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" lda $sourceName | sta cx16.$regname | stz cx16.$regname+1")
else
asmgen.out(" lda $sourceName | sta cx16.$regname | lda #0 | sta cx16.$regname+1")
}
else -> throw AssemblyError("invalid reg")
}
}

View File

@ -1520,7 +1520,7 @@ $containsLabel lda #1
pha
ora #$7f
bmi +
ldx #0
lda #0
+ tax
pla""")
RegisterOrPair.AY -> asmgen.out("""
@ -1528,7 +1528,7 @@ $containsLabel lda #1
pha
ora #$7f
bmi +
ldy #0
lda #0
+ tay
pla""")
RegisterOrPair.XY -> asmgen.out("""
@ -1536,9 +1536,19 @@ $containsLabel lda #1
tax
ora #$7f
bmi +
ldy #0
lda #0
+ tay""")
else -> throw AssemblyError("only reg pairs are words")
in Cx16VirtualRegisters -> {
val regname = wordtarget.register.name.lowercase()
asmgen.out("""
lda $sourceName
sta cx16.$regname
ora #$7f
bmi +
lda #0
+ sta cx16.$regname+1""")
}
else -> throw AssemblyError("only reg pairs allowed as word target ${wordtarget.register}")
}
}
TargetStorageKind.STACK -> {
@ -1589,7 +1599,14 @@ $containsLabel lda #1
RegisterOrPair.AX -> asmgen.out(" ldx #0 | lda $sourceName")
RegisterOrPair.AY -> asmgen.out(" ldy #0 | lda $sourceName")
RegisterOrPair.XY -> asmgen.out(" ldy #0 | ldx $sourceName")
else -> throw AssemblyError("only reg pairs are words")
in Cx16VirtualRegisters -> {
val regname = wordtarget.register.name.lowercase()
if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" lda $sourceName | sta cx16.$regname | stz cx16.$regname+1")
else
asmgen.out(" lda $sourceName | sta cx16.$regname | lda #0 | sta cx16.$regname+1")
}
else -> throw AssemblyError("only reg pairs allowed as word target")
}
}
TargetStorageKind.STACK -> {

View File

@ -181,9 +181,8 @@ class TestTypecasts: FunSpec({
}
}"""
val result = compileText(C64Target, false, text, writeAssembly = true).assertSuccess()
printProgram(result.program)
val statements = result.program.entrypoint.statements
statements.size shouldBe 16
statements.size shouldBe 14
}
test("no infinite typecast loop in assignment asmgen") {
@ -200,4 +199,52 @@ class TestTypecasts: FunSpec({
"""
compileText(C64Target, false, text, writeAssembly = true).assertSuccess()
}
test("(u)byte extend to word parameters") {
val text = """
main {
sub start() {
byte ub1 = -50
byte ub2 = -51
byte ub3 = -52
byte ub4 = 100
word @shared ww = func(ub1, ub2, ub3, ub4)
ww = func(ub4, ub2, ub3, ub1)
ww=afunc(ub1, ub2, ub3, ub4)
ww=afunc(ub4, ub2, ub3, ub1)
}
sub func(word x1, word y1, word x2, word y2) -> word {
return x1
}
asmsub afunc(word x1 @R0, word y1 @R1, word x2 @R2, word y2 @R3) -> word @AY {
%asm {{
lda cx16.r0
ldy cx16.r0+1
rts
}}
}
}"""
compileText(C64Target, true, text, writeAssembly = true).assertSuccess()
}
test("lsb msb used as args with word types") {
val text = """
main {
sub start() {
uword xx=${'$'}ea31
uword @shared ww = plot(lsb(xx), msb(xx))
}
inline asmsub plot(uword plotx @R0, uword ploty @R1) -> uword @AY{
%asm {{
lda cx16.r0
ldy cx16.r1
rts
}}
}
}"""
compileText(C64Target, true, text, writeAssembly = true).assertSuccess()
}
})

View File

@ -338,7 +338,7 @@ class TypecastExpression(var expression: Expression, var type: DataType, val imp
expression.linkParents(this)
}
override val isSimple = false
override val isSimple = expression.isSimple
override fun replaceChildNode(node: Node, replacement: Node) {
require(replacement is Expression && node===expression)

View File

@ -3,6 +3,22 @@ TODO
For next release
^^^^^^^^^^^^^^^^
fix the value of ww being wrong (with optimizations enabled) in :
sub start() {
byte ub1 = -50
byte ub2 = -51
byte ub3 = -52
byte ub4 = -53
word ww = func(ub1, ub2, ub3, ub4)
txt.print_w(ww)
}
sub func(word x1, word y1, word x2, word y2) -> word {
return x1
}
- optimize w=msb(w), w=lsb(w)
...
@ -22,7 +38,6 @@ Blocked by an official Commander-x16 r39 release
Future Things and Ideas
^^^^^^^^^^^^^^^^^^^^^^^
- nameInAssemblyCode() should search smarter
- Typecastexpression.isSimple: make it 'expression.isSimple' rather than always false. (this breaks some things atm)
- IdentifierReference: fix equality to also include position. CallGraph can then also only store IdentifierRef instead of pair(ident, position) as keys.
- Fix: don't report as recursion if code assigns address of its own subroutine to something, rather than calling it
- allow "xxx" * constexpr (where constexpr is not a number literal, now gives expression error not same type)

View File

@ -43,9 +43,9 @@ main {
for pixelxb in 0 to 255 {
pixelyw = cos16u(pixelxb) / 1024 + 120
graphics.plot(pixelxb, lsb(pixelyw))
graphics.plot(pixelxb, pixelyw)
pixelyw = sin16u(pixelxb) / 1024 + 120
graphics.plot(pixelxb, lsb(pixelyw))
graphics.plot(pixelxb, pixelyw)
}
}
@ -65,9 +65,9 @@ main {
for pixelxb in 0 to 179 {
pixelyw = cosr16u(pixelxb) / 1024 + 120
graphics.plot(pixelxb, lsb(pixelyw))
graphics.plot(pixelxb, pixelyw)
pixelyw = sinr16u(pixelxb) / 1024 + 120
graphics.plot(pixelxb, lsb(pixelyw))
graphics.plot(pixelxb, pixelyw)
}
}

View File

@ -4,19 +4,20 @@
main {
sub start() {
str s1 = "irmen"
ubyte ff = 1
txt.print(&s1+ff)
txt.nl()
txt.print(&s1+ff)
txt.nl()
txt.print_uwhex(&s1+ff, true)
uword xx=$ea31
xx = lsb(xx)
uword ww = plot(lsb(xx), msb(xx))
ww=msb(ww)
txt.print_uwhex(ww, true)
}
inline asmsub plot(uword plotx @R0, uword ploty @R1) -> uword @AY{
%asm {{
lda cx16.r0
ldy cx16.r1
rts
}}
}
ubyte[] array = [1,2,3,4]
txt.print_uwhex(&array+ff, true)
txt.nl()
txt.print_uwhex(&array+ff, true)
txt.nl()
}
}