fixed lsb(value) not working when used in a comparison expression (needed to flip loading of A and Y register with the value)

This commit is contained in:
Irmen de Jong 2020-12-27 18:12:12 +01:00
parent dd82e550d5
commit 6cb0e6a936
3 changed files with 66 additions and 34 deletions

View File

@ -1056,6 +1056,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
asmgen.out(" sta P8ESTACK_LO,x | dex") asmgen.out(" sta P8ESTACK_LO,x | dex")
} else { } else {
asmgen.assignExpressionToRegister(fcall.args.single(), RegisterOrPair.AY) asmgen.assignExpressionToRegister(fcall.args.single(), RegisterOrPair.AY)
// NOTE: we rely on the fact that the above assignment to AY, assigns the Lsb to A as the last instruction.
// this is required because the compiler assumes the status bits are set according to what A is (lsb)
// and will not generate another cmp when lsb() is directly used inside a comparison expression.
if (resultToStack) if (resultToStack)
asmgen.out(" sta P8ESTACK_LO,x | dex") asmgen.out(" sta P8ESTACK_LO,x | dex")
} }

View File

@ -708,8 +708,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.A -> asmgen.out(" inx | lda P8ESTACK_LO,x") RegisterOrPair.A -> asmgen.out(" inx | lda P8ESTACK_LO,x")
RegisterOrPair.X -> throw AssemblyError("can't load X from stack here - use intermediary var? ${target.origAstTarget?.position}") RegisterOrPair.X -> throw AssemblyError("can't load X from stack here - use intermediary var? ${target.origAstTarget?.position}")
RegisterOrPair.Y -> asmgen.out(" inx | ldy P8ESTACK_LO,x") RegisterOrPair.Y -> asmgen.out(" inx | ldy P8ESTACK_LO,x")
RegisterOrPair.AX -> asmgen.out(" inx | lda P8ESTACK_LO,x | ldx #0") RegisterOrPair.AX -> asmgen.out(" inx | txy | ldx #0 | lda P8ESTACK_LO,y")
RegisterOrPair.AY -> asmgen.out(" inx | lda P8ESTACK_LO,x | ldy #0") RegisterOrPair.AY -> asmgen.out(" inx | ldy #0 | lda P8ESTACK_LO,x")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
asmgen.out(""" asmgen.out("""
inx inx
@ -725,7 +725,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
DataType.UWORD, DataType.WORD, in PassByReferenceDatatypes -> { DataType.UWORD, DataType.WORD, in PassByReferenceDatatypes -> {
when(target.register!!) { when(target.register!!) {
RegisterOrPair.AX -> throw AssemblyError("can't load X from stack here - use intermediary var? ${target.origAstTarget?.position}") RegisterOrPair.AX -> throw AssemblyError("can't load X from stack here - use intermediary var? ${target.origAstTarget?.position}")
RegisterOrPair.AY-> asmgen.out(" inx | lda P8ESTACK_LO,x | ldy P8ESTACK_HI,x") RegisterOrPair.AY-> asmgen.out(" inx | ldy P8ESTACK_HI,x | lda P8ESTACK_LO,x")
RegisterOrPair.XY-> throw AssemblyError("can't load X from stack here - use intermediary var? ${target.origAstTarget?.position}") RegisterOrPair.XY-> throw AssemblyError("can't load X from stack here - use intermediary var? ${target.origAstTarget?.position}")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
asmgen.out(""" asmgen.out("""
@ -773,9 +773,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
TargetStorageKind.REGISTER -> { TargetStorageKind.REGISTER -> {
when(target.register!!) { when(target.register!!) {
RegisterOrPair.AX -> asmgen.out(" lda #<$sourceName | ldx #>$sourceName") RegisterOrPair.AX -> asmgen.out(" ldx #>$sourceName | lda #<$sourceName")
RegisterOrPair.AY -> asmgen.out(" lda #<$sourceName | ldy #>$sourceName") RegisterOrPair.AY -> asmgen.out(" ldy #>$sourceName | lda #<$sourceName")
RegisterOrPair.XY -> asmgen.out(" ldx #<$sourceName | ldy #>$sourceName") RegisterOrPair.XY -> asmgen.out(" ldy #>$sourceName | ldx #<$sourceName")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
asmgen.out(""" asmgen.out("""
lda #<$sourceName lda #<$sourceName
@ -914,9 +914,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
TargetStorageKind.REGISTER -> { TargetStorageKind.REGISTER -> {
when(target.register!!) { when(target.register!!) {
RegisterOrPair.AX -> asmgen.out(" lda $sourceName | ldx $sourceName+1") RegisterOrPair.AX -> asmgen.out(" ldx $sourceName+1 | lda $sourceName")
RegisterOrPair.AY -> asmgen.out(" lda $sourceName | ldy $sourceName+1") RegisterOrPair.AY -> asmgen.out(" ldy $sourceName+1 | lda $sourceName")
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName | ldy $sourceName+1") RegisterOrPair.XY -> asmgen.out(" ldy $sourceName+1 | ldx $sourceName")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
asmgen.out(""" asmgen.out("""
lda $sourceName lda $sourceName
@ -1086,9 +1086,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.A -> asmgen.out(" lda $sourceName") RegisterOrPair.A -> asmgen.out(" lda $sourceName")
RegisterOrPair.X -> asmgen.out(" ldx $sourceName") RegisterOrPair.X -> asmgen.out(" ldx $sourceName")
RegisterOrPair.Y -> asmgen.out(" ldy $sourceName") RegisterOrPair.Y -> asmgen.out(" ldy $sourceName")
RegisterOrPair.AX -> asmgen.out(" lda $sourceName | ldx #0") RegisterOrPair.AX -> asmgen.out(" ldx #0 | lda $sourceName")
RegisterOrPair.AY -> asmgen.out(" lda $sourceName | ldy #0") RegisterOrPair.AY -> asmgen.out(" ldy #0 | lda $sourceName")
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName | ldy #0") RegisterOrPair.XY -> asmgen.out(" ldy #0 | ldx $sourceName")
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
asmgen.out(""" asmgen.out("""
@ -1203,9 +1203,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
TargetStorageKind.REGISTER -> { TargetStorageKind.REGISTER -> {
when(wordtarget.register!!) { when(wordtarget.register!!) {
RegisterOrPair.AX -> asmgen.out(" lda $sourceName | ldx #0") RegisterOrPair.AX -> asmgen.out(" ldx #0 | lda $sourceName")
RegisterOrPair.AY -> asmgen.out(" lda $sourceName | ldy #0") RegisterOrPair.AY -> asmgen.out(" ldy #0 | lda $sourceName")
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName | ldy #0") RegisterOrPair.XY -> asmgen.out(" ldy #0 | ldx $sourceName")
else -> throw AssemblyError("only reg pairs are words") else -> throw AssemblyError("only reg pairs are words")
} }
} }
@ -1466,9 +1466,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
TargetStorageKind.REGISTER -> { TargetStorageKind.REGISTER -> {
when(target.register!!) { when(target.register!!) {
RegisterOrPair.AX -> asmgen.out(" lda #<${word.toHex()} | ldx #>${word.toHex()}") RegisterOrPair.AX -> asmgen.out(" ldx #>${word.toHex()} | lda #<${word.toHex()}")
RegisterOrPair.AY -> asmgen.out(" lda #<${word.toHex()} | ldy #>${word.toHex()}") RegisterOrPair.AY -> asmgen.out(" ldy #>${word.toHex()} | lda #<${word.toHex()}")
RegisterOrPair.XY -> asmgen.out(" ldx #<${word.toHex()} | ldy #>${word.toHex()}") RegisterOrPair.XY -> asmgen.out(" ldy #>${word.toHex()} | ldx #<${word.toHex()}")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
asmgen.out(""" asmgen.out("""
lda #<${word.toHex()} lda #<${word.toHex()}
@ -1554,9 +1554,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.A -> asmgen.out(" lda #${byte.toHex()}") RegisterOrPair.A -> asmgen.out(" lda #${byte.toHex()}")
RegisterOrPair.X -> asmgen.out(" ldx #${byte.toHex()}") RegisterOrPair.X -> asmgen.out(" ldx #${byte.toHex()}")
RegisterOrPair.Y -> asmgen.out(" ldy #${byte.toHex()}") RegisterOrPair.Y -> asmgen.out(" ldy #${byte.toHex()}")
RegisterOrPair.AX -> asmgen.out(" lda #${byte.toHex()} | ldx #0") RegisterOrPair.AX -> asmgen.out(" ldx #0 | lda #${byte.toHex()}")
RegisterOrPair.AY -> asmgen.out(" lda #${byte.toHex()} | ldy #0") RegisterOrPair.AY -> asmgen.out(" ldy #0 | lda #${byte.toHex()}")
RegisterOrPair.XY -> asmgen.out(" ldx #${byte.toHex()} | ldy #0") RegisterOrPair.XY -> asmgen.out(" ldy #0 | ldx #${byte.toHex()}")
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
asmgen.out(" lda #${byte.toHex()} | sta cx16.${target.register.toString().toLowerCase()}") asmgen.out(" lda #${byte.toHex()} | sta cx16.${target.register.toString().toLowerCase()}")
@ -1731,9 +1731,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
RegisterOrPair.A -> asmgen.out(" lda ${address.toHex()}") RegisterOrPair.A -> asmgen.out(" lda ${address.toHex()}")
RegisterOrPair.X -> asmgen.out(" ldx ${address.toHex()}") RegisterOrPair.X -> asmgen.out(" ldx ${address.toHex()}")
RegisterOrPair.Y -> asmgen.out(" ldy ${address.toHex()}") RegisterOrPair.Y -> asmgen.out(" ldy ${address.toHex()}")
RegisterOrPair.AX -> asmgen.out(" lda ${address.toHex()} | ldx #0") RegisterOrPair.AX -> asmgen.out(" ldx #0 | lda ${address.toHex()}")
RegisterOrPair.AY -> asmgen.out(" lda ${address.toHex()} | ldy #0") RegisterOrPair.AY -> asmgen.out(" ldy #0 | lda ${address.toHex()}")
RegisterOrPair.XY -> asmgen.out(" ldy ${address.toHex()} | ldy #0") RegisterOrPair.XY -> asmgen.out(" ldy #0 | ldy ${address.toHex()}")
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> {
asmgen.out(""" asmgen.out("""
@ -1807,9 +1807,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
throw AssemblyError("no asm gen for assign memory byte at $address to array ${wordtarget.asmVarname}") throw AssemblyError("no asm gen for assign memory byte at $address to array ${wordtarget.asmVarname}")
} }
TargetStorageKind.REGISTER -> when(wordtarget.register!!) { TargetStorageKind.REGISTER -> when(wordtarget.register!!) {
RegisterOrPair.AX -> asmgen.out(" lda ${address.toHex()} | ldx #0") RegisterOrPair.AX -> asmgen.out(" ldx #0 | lda ${address.toHex()}")
RegisterOrPair.AY -> asmgen.out(" lda ${address.toHex()} | ldy #0") RegisterOrPair.AY -> asmgen.out(" ldy #0 | lda ${address.toHex()}")
RegisterOrPair.XY -> asmgen.out(" ldy ${address.toHex()} | ldy #0") RegisterOrPair.XY -> asmgen.out(" ldy #0 | ldy ${address.toHex()}")
else -> throw AssemblyError("word regs can only be pair") else -> throw AssemblyError("word regs can only be pair")
} }
TargetStorageKind.STACK -> { TargetStorageKind.STACK -> {

View File

@ -8,17 +8,46 @@ main {
sub start () { sub start () {
uword length uword length
uword total = 0
if length>256 { length=200
repeat length-1 count()
gfx2.next_pixel(color) txt.print_uw(total)
} else { txt.chrout('\n')
repeat (length-1) as ubyte ; TODO lsb(length-1) doesn't work!?!?!? length=255
gfx2.next_pixel(color) count()
} txt.print_uw(total)
txt.chrout('\n')
length=256
count()
txt.print_uw(total)
txt.chrout('\n')
length=257
count()
txt.print_uw(total)
txt.chrout('\n')
length=9999
count()
txt.print_uw(total)
txt.chrout('\n')
test_stack.test() test_stack.test()
sub count() {
total = 0
if length>256 {
repeat length-1
total++
} else {
uword total2
repeat lsb(length-1)
total++
; repeat (length-1) as ubyte ; TODO lsb(length-1) doesn't work!?!?!?
; total++
}
}
} }
} }