implement the missing in-place array operators for split word arrays and numeric operand

This commit is contained in:
Irmen de Jong 2024-03-13 21:16:49 +01:00
parent 3535c1acda
commit 1fc79ff6dd
3 changed files with 177 additions and 239 deletions

View File

@ -222,7 +222,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
val index = indexNum.number.toInt() val index = indexNum.number.toInt()
if(target.array.splitWords) { if(target.array.splitWords) {
when(value.kind) { when(value.kind) {
SourceStorageKind.LITERALNUMBER -> inplacemodificationSplitWordWithLiteralval(target.asmVarname, index, operator, value.number!!.number.toInt()) SourceStorageKind.LITERALNUMBER -> inplacemodificationSplitWordWithLiteralval(target.asmVarname, target.datatype, index, operator, value.number!!.number.toInt())
else -> { else -> {
// TODO: more optimized code for VARIABLE, REGISTER, MEMORY, ARRAY, EXPRESSION in the case of split-word arrays // TODO: more optimized code for VARIABLE, REGISTER, MEMORY, ARRAY, EXPRESSION in the case of split-word arrays
val scope = target.origAstTarget?.definingSub() val scope = target.origAstTarget?.definingSub()
@ -672,77 +672,9 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
} }
} }
private fun inplacemodificationSplitWordWithLiteralval(arrayVar: String, index: Int, operator: String, value: Int) { private fun inplacemodificationSplitWordWithLiteralval(arrayVar: String, dt: DataType, index: Int, operator: String, value: Int) {
// note: this contains special optimized cases because we know the exact value. Don't replace this with another routine. // note: this contains special optimized cases because we know the exact value. Don't replace this with another routine.
when (operator) { inplacemodificationSomeWordWithLiteralval("${arrayVar}_lsb+$index", "${arrayVar}_msb+$index", dt, operator, value, null)
"+" -> {
when {
value==0 -> {}
value==1 -> {
asmgen.out("""
inc ${arrayVar}_lsb+$index
bne +
inc ${arrayVar}_msb+$index
+""")
}
value in 1..0xff -> asmgen.out("""
lda ${arrayVar}_lsb+$index
clc
adc #$value
sta ${arrayVar}_lsb+$index
bcc +
inc ${arrayVar}_msb+$index
+""")
value==0x0100 -> asmgen.out(" inc ${arrayVar}_msb+$index")
value==0x0200 -> asmgen.out(" inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index")
value==0x0300 -> asmgen.out(" inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index")
value==0x0400 -> asmgen.out(" inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index")
value and 255==0 -> asmgen.out(" lda ${arrayVar}_msb+$index | clc | adc #>$value | sta ${arrayVar}_msb+$index")
else -> asmgen.out("""
lda ${arrayVar}_lsb+$index
clc
adc #<$value
sta ${arrayVar}_lsb+$index
lda ${arrayVar}_msb+$index
adc #>$value
sta ${arrayVar}_msb+$index""")
}
}
"-" -> {
when {
value==0 -> {}
value==1 -> {
asmgen.out("""
lda ${arrayVar}_lsb+$index
bne +
dec ${arrayVar}_msb+$index
+ dec ${arrayVar}_lsb+$index""")
}
value in 1..0xff -> asmgen.out("""
lda ${arrayVar}_lsb+$index
sec
sbc #$value
sta ${arrayVar}_lsb+$index
bcs +
dec ${arrayVar}_msb+$index
+""")
value==0x0100 -> asmgen.out(" dec ${arrayVar}_msb+$index")
value==0x0200 -> asmgen.out(" dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index")
value==0x0300 -> asmgen.out(" dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index")
value==0x0400 -> asmgen.out(" dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index")
value and 255==0 -> asmgen.out(" lda ${arrayVar}_msb+$index | sec | sbc #>$value | sta ${arrayVar}_msb+$index")
else -> asmgen.out("""
lda ${arrayVar}_lsb+$index
sec
sbc #<$value
sta ${arrayVar}_lsb+$index
lda ${arrayVar}_msb+$index
sbc #>$value
sta ${arrayVar}_msb+$index""")
}
}
else -> TODO("in-place modify split-words array value for operator $operator")
}
} }
private fun inplacemodificationRegisterAXwithVariable(operator: String, variable: String, varDt: DataType): Boolean { private fun inplacemodificationRegisterAXwithVariable(operator: String, variable: String, varDt: DataType): Boolean {
@ -1767,40 +1699,46 @@ $shortcutLabel:""")
} }
} }
private fun inplacemodificationWordWithLiteralval(name: String, dt: DataType, operator: String, value: Int, block: PtBlock?) { private fun inplacemodificationWordWithLiteralval(name: String, dt: DataType, operator: String, value: Int, block: PtBlock?) {
// note: this contains special optimized cases because we know the exact value. Don't replace this with another routine. // note: this contains special optimized cases because we know the exact value. Don't replace this with another routine.
inplacemodificationSomeWordWithLiteralval(name, name + "+1", dt, operator, value, block)
}
private fun inplacemodificationSomeWordWithLiteralval(lsb: String, msb: String, dt: DataType, operator: String, value: Int, block: PtBlock?) {
when (operator) { when (operator) {
"+" -> { "+" -> {
when { when {
value==0 -> {} value==0 -> {}
value==1 -> { value==1 -> {
asmgen.out(""" asmgen.out("""
inc $name inc $lsb
bne + bne +
inc $name+1 inc $msb
+""") +""")
} }
value in 1..0xff -> asmgen.out(""" value in 1..0xff -> asmgen.out("""
lda $name lda $lsb
clc clc
adc #$value adc #$value
sta $name sta $lsb
bcc + bcc +
inc $name+1 inc $msb
+""") +""")
value==0x0100 -> asmgen.out(" inc $name+1") value==0x0100 -> asmgen.out(" inc $msb")
value==0x0200 -> asmgen.out(" inc $name+1 | inc $name+1") value==0x0200 -> asmgen.out(" inc $msb | inc $msb")
value==0x0300 -> asmgen.out(" inc $name+1 | inc $name+1 | inc $name+1") value==0x0300 -> asmgen.out(" inc $msb | inc $msb | inc $msb")
value==0x0400 -> asmgen.out(" inc $name+1 | inc $name+1 | inc $name+1 | inc $name+1") value==0x0400 -> asmgen.out(" inc $msb | inc $msb | inc $msb | inc $msb")
value and 255==0 -> asmgen.out(" lda $name+1 | clc | adc #>$value | sta $name+1") value and 255==0 -> asmgen.out(" lda $msb | clc | adc #>$value | sta $msb")
else -> asmgen.out(""" else -> asmgen.out("""
lda $name lda $lsb
clc clc
adc #<$value adc #<$value
sta $name sta $lsb
lda $name+1 lda $msb
adc #>$value adc #>$value
sta $name+1""") sta $msb""")
} }
} }
"-" -> { "-" -> {
@ -1808,44 +1746,44 @@ $shortcutLabel:""")
value==0 -> {} value==0 -> {}
value==1 -> { value==1 -> {
asmgen.out(""" asmgen.out("""
lda $name lda $lsb
bne + bne +
dec $name+1 dec $msb
+ dec $name""") + dec $lsb""")
} }
value in 1..0xff -> asmgen.out(""" value in 1..0xff -> asmgen.out("""
lda $name lda $lsb
sec sec
sbc #$value sbc #$value
sta $name sta $lsb
bcs + bcs +
dec $name+1 dec $msb
+""") +""")
value==0x0100 -> asmgen.out(" dec $name+1") value==0x0100 -> asmgen.out(" dec $msb")
value==0x0200 -> asmgen.out(" dec $name+1 | dec $name+1") value==0x0200 -> asmgen.out(" dec $msb | dec $msb")
value==0x0300 -> asmgen.out(" dec $name+1 | dec $name+1 | dec $name+1") value==0x0300 -> asmgen.out(" dec $msb | dec $msb | dec $msb")
value==0x0400 -> asmgen.out(" dec $name+1 | dec $name+1 | dec $name+1 | dec $name+1") value==0x0400 -> asmgen.out(" dec $msb | dec $msb | dec $msb | dec $msb")
value and 255==0 -> asmgen.out(" lda $name+1 | sec | sbc #>$value | sta $name+1") value and 255==0 -> asmgen.out(" lda $msb | sec | sbc #>$value | sta $msb")
else -> asmgen.out(""" else -> asmgen.out("""
lda $name lda $lsb
sec sec
sbc #<$value sbc #<$value
sta $name sta $lsb
lda $name+1 lda $msb
sbc #>$value sbc #>$value
sta $name+1""") sta $msb""")
} }
} }
"*" -> { "*" -> {
// the mul code works for both signed and unsigned // the mul code works for both signed and unsigned
if(value in asmgen.optimizedWordMultiplications) { if(value in asmgen.optimizedWordMultiplications) {
asmgen.out(" lda $name | ldy $name+1 | jsr math.mul_word_$value | sta $name | sty $name+1") asmgen.out(" lda $lsb | ldy $msb | jsr math.mul_word_$value | sta $lsb | sty $msb")
} else { } else {
if(block?.options?.veraFxMuls==true) if(block?.options?.veraFxMuls==true)
// cx16 verafx hardware mul // cx16 verafx hardware mul
asmgen.out(""" asmgen.out("""
lda $name lda $lsb
ldy $name+1 ldy $msb
sta cx16.r0 sta cx16.r0
sty cx16.r0+1 sty cx16.r0+1
lda #<$value lda #<$value
@ -1853,19 +1791,19 @@ $shortcutLabel:""")
sta cx16.r1 sta cx16.r1
sty cx16.r1+1 sty cx16.r1+1
jsr verafx.muls jsr verafx.muls
sta $name sta $lsb
sty $name+1""") sty $msb""")
else else
asmgen.out(""" asmgen.out("""
lda $name lda $lsb
sta math.multiply_words.multiplier sta math.multiply_words.multiplier
lda $name+1 lda $msb
sta math.multiply_words.multiplier+1 sta math.multiply_words.multiplier+1
lda #<$value lda #<$value
ldy #>$value ldy #>$value
jsr math.multiply_words jsr math.multiply_words
sta $name sta $lsb
sty $name+1""") sty $msb""")
} }
} }
"/" -> { "/" -> {
@ -1873,28 +1811,28 @@ $shortcutLabel:""")
throw AssemblyError("division by zero") throw AssemblyError("division by zero")
if(dt==DataType.WORD) { if(dt==DataType.WORD) {
asmgen.out(""" asmgen.out("""
lda $name lda $lsb
ldy $name+1 ldy $msb
sta P8ZP_SCRATCH_W1 sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1 sty P8ZP_SCRATCH_W1+1
lda #<$value lda #<$value
ldy #>$value ldy #>$value
jsr math.divmod_w_asm jsr math.divmod_w_asm
sta $name sta $lsb
sty $name+1 sty $msb
""") """)
} }
else { else {
asmgen.out(""" asmgen.out("""
lda $name lda $lsb
ldy $name+1 ldy $msb
sta P8ZP_SCRATCH_W1 sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1 sty P8ZP_SCRATCH_W1+1
lda #<$value lda #<$value
ldy #>$value ldy #>$value
jsr math.divmod_uw_asm jsr math.divmod_uw_asm
sta $name sta $lsb
sty $name+1 sty $msb
""") """)
} }
} }
@ -1904,8 +1842,8 @@ $shortcutLabel:""")
if(dt==DataType.WORD) if(dt==DataType.WORD)
throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead") throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
asmgen.out(""" asmgen.out("""
lda $name lda $lsb
ldy $name+1 ldy $msb
sta P8ZP_SCRATCH_W1 sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1 sty P8ZP_SCRATCH_W1+1
lda #<$value lda #<$value
@ -1913,33 +1851,33 @@ $shortcutLabel:""")
jsr math.divmod_uw_asm jsr math.divmod_uw_asm
lda P8ZP_SCRATCH_W2 lda P8ZP_SCRATCH_W2
ldy P8ZP_SCRATCH_W2+1 ldy P8ZP_SCRATCH_W2+1
sta $name sta $lsb
sty $name+1 sty $msb
""") """)
} }
"<<" -> { "<<" -> {
when { when {
value>=16 -> { value>=16 -> {
if(asmgen.isTargetCpu(CpuType.CPU65c02)) if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz $name | stz $name+1") asmgen.out(" stz $lsb | stz $msb")
else else
asmgen.out(" lda #0 | sta $name | sta $name+1") asmgen.out(" lda #0 | sta $lsb | sta $msb")
} }
value==8 -> { value==8 -> {
asmgen.out(" lda $name | sta $name+1") asmgen.out(" lda $lsb | sta $msb")
if(asmgen.isTargetCpu(CpuType.CPU65c02)) if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz $name") asmgen.out(" stz $lsb")
else else
asmgen.out(" lda #0 | sta $name") asmgen.out(" lda #0 | sta $lsb")
} }
value>3 -> asmgen.out(""" value>3 -> asmgen.out("""
ldy #$value ldy #$value
- asl $name - asl $lsb
rol $name+1 rol $msb
dey dey
bne - bne -
""") """)
else -> repeat(value) { asmgen.out(" asl $name | rol $name+1") } else -> repeat(value) { asmgen.out(" asl $lsb | rol $msb") }
} }
} }
">>" -> { ">>" -> {
@ -1948,54 +1886,54 @@ $shortcutLabel:""")
when { when {
value>=16 -> { value>=16 -> {
if(asmgen.isTargetCpu(CpuType.CPU65c02)) if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz $name | stz $name+1") asmgen.out(" stz $lsb | stz $msb")
else else
asmgen.out(" lda #0 | sta $name | sta $name+1") asmgen.out(" lda #0 | sta $lsb | sta $msb")
} }
value==8 -> { value==8 -> {
asmgen.out(" lda $name+1 | sta $name") asmgen.out(" lda $msb | sta $lsb")
if(asmgen.isTargetCpu(CpuType.CPU65c02)) if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz $name+1") asmgen.out(" stz $msb")
else else
asmgen.out(" lda #0 | sta $name+1") asmgen.out(" lda #0 | sta $msb")
} }
value>2 -> asmgen.out(""" value>2 -> asmgen.out("""
ldy #$value ldy #$value
- lsr $name+1 - lsr $msb
ror $name ror $lsb
dey dey
bne -""") bne -""")
else -> repeat(value) { asmgen.out(" lsr $name+1 | ror $name")} else -> repeat(value) { asmgen.out(" lsr $msb | ror $lsb")}
} }
} else { } else {
when { when {
value>=16 -> asmgen.out(""" value>=16 -> asmgen.out("""
lda $name+1 lda $msb
bmi + bmi +
lda #0 lda #0
beq ++ beq ++
+ lda #-1 + lda #-1
+ sta $name + sta $lsb
sta $name+1""") sta $msb""")
value==8 -> asmgen.out(""" value==8 -> asmgen.out("""
lda $name+1 lda $msb
sta $name sta $lsb
bmi + bmi +
lda #0 lda #0
- sta $name+1 - sta $msb
beq ++ beq ++
+ lda #-1 + lda #-1
sta $name+1 sta $msb
+""") +""")
value>2 -> asmgen.out(""" value>2 -> asmgen.out("""
ldy #$value ldy #$value
- lda $name+1 - lda $msb
asl a asl a
ror $name+1 ror $msb
ror $name ror $lsb
dey dey
bne -""") bne -""")
else -> repeat(value) { asmgen.out(" lda $name+1 | asl a | ror $name+1 | ror $name") } else -> repeat(value) { asmgen.out(" lda $msb | asl a | ror $msb | ror $lsb") }
} }
} }
} }
@ -2004,165 +1942,165 @@ $shortcutLabel:""")
when { when {
value == 0 -> { value == 0 -> {
if(asmgen.isTargetCpu(CpuType.CPU65c02)) if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz $name | stz $name+1") asmgen.out(" stz $lsb | stz $msb")
else else
asmgen.out(" lda #0 | sta $name | sta $name+1") asmgen.out(" lda #0 | sta $lsb | sta $msb")
} }
value == 0x00ff -> { value == 0x00ff -> {
if(asmgen.isTargetCpu(CpuType.CPU65c02)) if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz $name+1") asmgen.out(" stz $msb")
else else
asmgen.out(" lda #0 | sta $name+1") asmgen.out(" lda #0 | sta $msb")
} }
value == 0xff00 -> { value == 0xff00 -> {
if(asmgen.isTargetCpu(CpuType.CPU65c02)) if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz $name") asmgen.out(" stz $lsb")
else else
asmgen.out(" lda #0 | sta $name") asmgen.out(" lda #0 | sta $lsb")
} }
value and 255 == 0 -> { value and 255 == 0 -> {
if(asmgen.isTargetCpu(CpuType.CPU65c02)) if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz $name") asmgen.out(" stz $lsb")
else else
asmgen.out(" lda #0 | sta $name") asmgen.out(" lda #0 | sta $lsb")
asmgen.out(" lda $name+1 | and #>$value | sta $name+1") asmgen.out(" lda $msb | and #>$value | sta $msb")
} }
value < 0x0100 -> { value < 0x0100 -> {
immediateAndInplace(name, value) immediateAndInplace(lsb, value)
if(asmgen.isTargetCpu(CpuType.CPU65c02)) if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz $name+1") asmgen.out(" stz $msb")
else else
asmgen.out(" lda #0 | sta $name+1") asmgen.out(" lda #0 | sta $msb")
} }
else -> asmgen.out(" lda $name | and #<$value | sta $name | lda $name+1 | and #>$value | sta $name+1") else -> asmgen.out(" lda $lsb | and #<$value | sta $lsb | lda $msb | and #>$value | sta $msb")
} }
} }
"|" -> { "|" -> {
when { when {
value == 0 -> {} value == 0 -> {}
value and 255 == 0 -> asmgen.out(" lda $name+1 | ora #>$value | sta $name+1") value and 255 == 0 -> asmgen.out(" lda $msb | ora #>$value | sta $msb")
value < 0x0100 -> immediateOrInplace(name, value) value < 0x0100 -> immediateOrInplace(lsb, value)
else -> asmgen.out(" lda $name | ora #<$value | sta $name | lda $name+1 | ora #>$value | sta $name+1") else -> asmgen.out(" lda $lsb | ora #<$value | sta $lsb | lda $msb | ora #>$value | sta $msb")
} }
} }
"^" -> { "^" -> {
when { when {
value == 0 -> {} value == 0 -> {}
value and 255 == 0 -> asmgen.out(" lda $name+1 | eor #>$value | sta $name+1") value and 255 == 0 -> asmgen.out(" lda $msb | eor #>$value | sta $msb")
value < 0x0100 -> asmgen.out(" lda $name | eor #$value | sta $name") value < 0x0100 -> asmgen.out(" lda $lsb | eor #$value | sta $lsb")
else -> asmgen.out(" lda $name | eor #<$value | sta $name | lda $name+1 | eor #>$value | sta $name+1") else -> asmgen.out(" lda $lsb | eor #<$value | sta $lsb | lda $msb | eor #>$value | sta $msb")
} }
} }
"==" -> { "==" -> {
asmgen.out(""" asmgen.out("""
lda $name lda $lsb
cmp #<$value cmp #<$value
bne + bne +
lda $name+1 lda $msb
cmp #>$value cmp #>$value
bne + bne +
lda #1 lda #1
bne ++ bne ++
+ lda #0 + lda #0
+ sta $name + sta $lsb
lda #0 lda #0
sta $name+1""") sta $msb""")
} }
"!=" -> { "!=" -> {
asmgen.out(""" asmgen.out("""
lda $name lda $lsb
cmp #<$value cmp #<$value
bne + bne +
lda $name+1 lda $msb
cmp #>$value cmp #>$value
bne + bne +
lda #0 lda #0
beq ++ beq ++
+ lda #1 + lda #1
+ sta $name + sta $lsb
lda #0 lda #0
sta $name+1""") sta $msb""")
} }
"<" -> { "<" -> {
if(dt==DataType.UWORD) { if(dt==DataType.UWORD) {
asmgen.out(""" asmgen.out("""
lda $name+1 lda $msb
cmp #>$value cmp #>$value
bcc ++ bcc ++
bne + bne +
lda $name lda $lsb
cmp #<$value cmp #<$value
bcc ++ bcc ++
+ lda #0 ; false + lda #0 ; false
sta $name sta $lsb
sta $name+1 sta $msb
beq ++ beq ++
+ lda #1 ; true + lda #1 ; true
sta $name sta $lsb
lda #0 lda #0
sta $name+1 sta $msb
+""") +""")
} }
else { else {
// signed // signed
asmgen.out(""" asmgen.out("""
lda $name lda $lsb
cmp #<$value cmp #<$value
lda $name+1 lda $msb
sbc #>$value sbc #>$value
bvc + bvc +
eor #$80 eor #$80
+ bmi + + bmi +
lda #0 lda #0
sta $name sta $lsb
sta $name+1 sta $msb
beq ++ beq ++
+ lda #1 ; true + lda #1 ; true
sta $name sta $lsb
lda #0 lda #0
sta $name+1 sta $msb
+""") +""")
} }
} }
"<=" -> { "<=" -> {
if(dt==DataType.UWORD) { if(dt==DataType.UWORD) {
asmgen.out(""" asmgen.out("""
lda $name+1 lda $msb
cmp #>$value cmp #>$value
beq + beq +
bcc ++ bcc ++
- lda #0 ; false - lda #0 ; false
sta $name sta $lsb
sta $name+1 sta $msb
beq +++ beq +++
+ lda $name ; next + lda $lsb ; next
cmp #<$value cmp #<$value
bcc + bcc +
bne - bne -
+ lda #1 ; true + lda #1 ; true
sta $name sta $lsb
lda #0 lda #0
sta $name+1 sta $msb
+""") +""")
} }
else { else {
// signed // signed
asmgen.out(""" asmgen.out("""
lda #<$value lda #<$value
cmp $name cmp $lsb
lda #>$value lda #>$value
sbc $name+1 sbc $msb
bvc + bvc +
eor #$80 eor #$80
+ bpl + + bpl +
lda #0 lda #0
sta $name sta $lsb
sta $name+1 sta $msb
beq ++ beq ++
+ lda #1 + lda #1
sta $name sta $lsb
lda #0 lda #0
sta $name+1 sta $msb
+""") +""")
} }
} }
@ -2171,40 +2109,40 @@ $shortcutLabel:""")
if(dt==DataType.UWORD) { if(dt==DataType.UWORD) {
asmgen.out(""" asmgen.out("""
lda #>$value lda #>$value
cmp $name+1 cmp $msb
bcc ++ bcc ++
bne + bne +
lda #<$value lda #<$value
cmp $name cmp $lsb
bcc ++ bcc ++
+ lda #0 ; false + lda #0 ; false
sta $name sta $lsb
sta $name+1 sta $msb
beq ++ beq ++
+ lda #1 ; true + lda #1 ; true
sta $name sta $lsb
lda #0 lda #0
sta $name+1 sta $msb
+""") +""")
} }
else { else {
// signed // signed
asmgen.out(""" asmgen.out("""
lda #<$value lda #<$value
cmp $name cmp $lsb
lda #>$value lda #>$value
sbc $name+1 sbc $msb
bvc + bvc +
eor #$80 eor #$80
+ bmi + + bmi +
lda #0 lda #0
sta $name sta $lsb
sta $name+1 sta $msb
beq ++ beq ++
+ lda #1 ; true + lda #1 ; true
sta $name sta $lsb
lda #0 lda #0
sta $name+1 sta $msb
+""") +""")
} }
} }
@ -2213,41 +2151,41 @@ $shortcutLabel:""")
if(dt==DataType.UWORD) { if(dt==DataType.UWORD) {
asmgen.out(""" asmgen.out("""
lda #>$value lda #>$value
cmp $name+1 cmp $msb
beq + beq +
bcc ++ bcc ++
- lda #0 ; false - lda #0 ; false
sta $name sta $lsb
sta $name+1 sta $msb
beq +++ beq +++
+ lda #<$value ; next + lda #<$value ; next
cmp $name cmp $lsb
bcc + bcc +
bne - bne -
+ lda #1 ; true + lda #1 ; true
sta $name sta $lsb
lda #0 lda #0
sta $name+1 sta $msb
+""") +""")
} }
else { else {
// signed // signed
asmgen.out(""" asmgen.out("""
lda $name lda $lsb
cmp #<$value cmp #<$value
lda $name+1 lda $msb
sbc #>$value sbc #>$value
bvc + bvc +
eor #$80 eor #$80
+ bpl + + bpl +
lda #0 lda #0
sta $name sta $lsb
sta $name+1 sta $msb
beq ++ beq ++
+ lda #1 + lda #1
sta $name sta $lsb
lda #0 lda #0
sta $name+1 sta $msb
+""") +""")
} }
} }

View File

@ -1,9 +1,6 @@
TODO TODO
==== ====
make bitshift2.p8 runnable on VM
bitshift2.p8 has many errors (was ok on 10.2 before bool merge)
... ...
@ -12,6 +9,7 @@ Future Things and Ideas
Compiler: Compiler:
- IR: add TEST instruction to test memory content and set N/Z flags, without affecting any register. Replace all LOADM+CMPI #0 / LOAD #0+LOADM+CMP+BRANCH by this instruction - IR: add TEST instruction to test memory content and set N/Z flags, without affecting any register. Replace all LOADM+CMPI #0 / LOAD #0+LOADM+CMP+BRANCH by this instruction
- IR: implement missing operators in AssignmentGen (array shifts etc)
- can we support signed % (remainder) somehow? - can we support signed % (remainder) somehow?
- instead of copy-pasting inline asmsubs, make them into a 64tass macro and use that instead. - instead of copy-pasting inline asmsubs, make them into a 64tass macro and use that instead.
that will allow them to be reused from custom user written assembly code as well. that will allow them to be reused from custom user written assembly code as well.

View File

@ -3,23 +3,25 @@
%option no_sysinit %option no_sysinit
main { main {
bool @shared var1, var2
bool[2] barray = [false, true]
ubyte success
sub start() { sub start() {
no_else() uword[3] uwarray = [1111,2222,3333]
} uword[3] @split uwarray_s = [1111,2222,3333]
ubyte[3] array = [11,22,33]
sub no_else() { rol(array[1])
txt.print("bool no_else: ") array[1] <<=1
success=0 ror(array[1])
array[1] >>=1
var1=true rol(uwarray[1])
var2=false uwarray[1] <<=1
ror(uwarray[1])
uwarray[1] >>=1
if var1!=var2 rol(uwarray_s[1])
txt.print("yes") uwarray_s[1] *=3
ror(uwarray_s[1])
uwarray_s[1] *=3
} }
} }