mirror of
https://github.com/irmen/prog8.git
synced 2024-09-29 08:57:51 +00:00
enable more optimizations for typecasted assignments. Fixed missing codegen for assigning bytes to words in certain cases.
This commit is contained in:
parent
fa48746ba9
commit
5ecf2a3357
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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 -> {
|
||||
|
@ -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()
|
||||
}
|
||||
})
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user