fix word+/-byte errors if byte was unsigned

This commit is contained in:
Irmen de Jong 2020-09-27 20:23:42 +02:00
parent 988459f744
commit e828c013e6
3 changed files with 421 additions and 79 deletions

View File

@ -642,14 +642,15 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
// TODO use these + and - optimizations in the expressionAsmGenerator as well. // TODO use these + and - optimizations in the expressionAsmGenerator as well.
"+" -> { "+" -> {
when { when {
value<0x0100 -> asmgen.out(""" value==0 -> {}
value in 1..0xff -> asmgen.out("""
lda $name lda $name
clc clc
adc #$value adc #$value
sta $name sta $name
bcc + bcc +
inc $name+1 inc $name+1
+ """) +""")
value==0x0100 -> asmgen.out(" inc $name+1") value==0x0100 -> asmgen.out(" inc $name+1")
value==0x0200 -> asmgen.out(" inc $name+1 | inc $name+1") value==0x0200 -> asmgen.out(" inc $name+1 | inc $name+1")
value==0x0300 -> asmgen.out(" inc $name+1 | inc $name+1 | inc $name+1") value==0x0300 -> asmgen.out(" inc $name+1 | inc $name+1 | inc $name+1")
@ -666,14 +667,15 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
} }
"-" -> { "-" -> {
when { when {
value<0x0100 -> asmgen.out(""" value==0 -> {}
value in 1..0xff -> asmgen.out("""
lda $name lda $name
sec sec
sbc #$value sbc #$value
sta $name sta $name
bcs + bcs +
dec $name+1 dec $name+1
+ """) +""")
value==0x0100 -> asmgen.out(" dec $name+1") value==0x0100 -> asmgen.out(" dec $name+1")
value==0x0200 -> asmgen.out(" dec $name+1 | dec $name+1") value==0x0200 -> asmgen.out(" dec $name+1 | dec $name+1")
value==0x0300 -> asmgen.out(" dec $name+1 | dec $name+1 | dec $name+1") value==0x0300 -> asmgen.out(" dec $name+1 | dec $name+1 | dec $name+1")
@ -841,32 +843,52 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
when (operator) { when (operator) {
// note: ** (power) operator requires floats. // note: ** (power) operator requires floats.
"+" -> { "+" -> {
asmgen.out(""" if(valueDt==DataType.UBYTE)
ldy #0 asmgen.out("""
lda $otherName lda $name
bpl + clc
dey ; sign extend adc $otherName
+ clc sta $name
adc $name bcc +
sta $name inc $name+1
tya +""")
adc $name+1 else
sta $name+1""") asmgen.out("""
ldy #0
lda $otherName
bpl +
dey ; sign extend
+ clc
adc $name
sta $name
tya
adc $name+1
sta $name+1""")
} }
"-" -> { "-" -> {
asmgen.out(""" if(valueDt==DataType.UBYTE)
ldy #0 asmgen.out("""
lda $otherName lda $name
bpl + sec
dey ; sign extend sbc $otherName
+ sty P8ZP_SCRATCH_B1 sta $name
lda $name bcc +
sec dec $name+1
sbc $otherName +""")
sta $name else
lda $name+1 asmgen.out("""
sbc P8ZP_SCRATCH_B1 ldy #0
sta $name+1""") lda $otherName
bpl +
dey ; sign extend
+ sty P8ZP_SCRATCH_B1
lda $name
sec
sbc $otherName
sta $name
lda $name+1
sbc P8ZP_SCRATCH_B1
sta $name+1""")
} }
"*" -> { "*" -> {
asmgen.out(""" asmgen.out("""
@ -882,8 +904,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
lda math.multiply_words.result+1 lda math.multiply_words.result+1
sta $name+1""") sta $name+1""")
} }
"/" -> TODO("div wordvar/bytevar") "/" -> TODO("div (u)wordvar/bytevar")
"%" -> TODO("word remainder bytevar") "%" -> TODO("(u)word remainder bytevar")
"<<" -> { "<<" -> {
asmgen.out(""" asmgen.out("""
ldy $otherName ldy $otherName
@ -911,9 +933,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
bne -""") bne -""")
} }
} }
"&" -> TODO("bitand wordvar bytevar") "&" -> TODO("bitand (u)wordvar bytevar")
"^" -> TODO("bitxor wordvar bytevar") "^" -> TODO("bitxor (u)wordvar bytevar")
"|" -> TODO("bitor wordvar bytevar") "|" -> TODO("bitor (u)wordvar bytevar")
else -> throw AssemblyError("invalid operator for in-place modification $operator") else -> throw AssemblyError("invalid operator for in-place modification $operator")
} }
} }
@ -1009,36 +1031,56 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
when (operator) { when (operator) {
// note: ** (power) operator requires floats. // note: ** (power) operator requires floats.
"+" -> { "+" -> {
asmgen.out(""" if(valueDt==DataType.UBYTE)
ldy #0 asmgen.out("""
lda P8ESTACK_LO+1,x lda $name
bpl + clc
dey ; sign extend adc P8ESTACK_LO+1,x
+ clc sta $name
adc $name bcc +
sta $name inc $name+1
tya +""")
adc $name+1 else
sta $name+1""") asmgen.out("""
ldy #0
lda P8ESTACK_LO+1,x
bpl +
dey ; sign extend
+ clc
adc $name
sta $name
tya
adc $name+1
sta $name+1""")
} }
"-" -> { "-" -> {
asmgen.out(""" if(valueDt==DataType.UBYTE)
ldy #0 asmgen.out("""
lda P8ESTACK_LO+1,x lda $name
bpl + sec
dey ; sign extend sbc P8ESTACK_LO+1,x
+ sty P8ZP_SCRATCH_B1 sta $name
lda $name bcc +
sec dec $name+1
sbc P8ESTACK_LO+1,x +""")
sta $name else
lda $name+1 asmgen.out("""
sbc P8ZP_SCRATCH_B1 ldy #0
sta $name+1""") lda P8ESTACK_LO+1,x
bpl +
dey ; sign extend
+ sty P8ZP_SCRATCH_B1
lda $name
sec
sbc P8ESTACK_LO+1,x
sta $name
lda $name+1
sbc P8ZP_SCRATCH_B1
sta $name+1""")
} }
"*" -> TODO("mul word byte") "*" -> TODO("mul (u)word (u)byte")
"/" -> TODO("div word byte") "/" -> TODO("div (u)word (u)byte")
"%" -> TODO("word remainder byte") "%" -> TODO("(u)word remainder (u)byte")
"<<" -> { "<<" -> {
asmgen.translateExpression(value) asmgen.translateExpression(value)
asmgen.out(""" asmgen.out("""
@ -1077,9 +1119,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
+""") +""")
} }
} }
"&" -> TODO("bitand word byte") "&" -> TODO("bitand (u)word (u)byte")
"^" -> TODO("bitxor word byte") "^" -> TODO("bitxor (u)word (u)byte")
"|" -> TODO("bitor word byte") "|" -> TODO("bitor (u)word (u)byte")
else -> throw AssemblyError("invalid operator for in-place modification $operator") else -> throw AssemblyError("invalid operator for in-place modification $operator")
} }
} }

View File

@ -0,0 +1,315 @@
%import textio
%import syslib
%zeropage basicsafe
main {
sub start() {
repeat 25 {
txt.chrout('\n')
}
ubyte ub
byte bb
uword uwsum
word wsum
uwsum = 50000
ub=50
uwsum += ub
ub=250
uwsum += ub
if uwsum==50300
txt.print("1 ok\n")
else {
txt.print("1 fail:")
txt.print_uw(uwsum)
txt.chrout('\n')
}
wsum = -30000
bb = 100
wsum += bb
bb = -50
wsum += bb
if wsum==-29950
txt.print("2 ok\n")
else {
txt.print("2 fail:")
txt.print_w(wsum)
txt.chrout('\n')
}
uwsum = 50000
ub=50
uwsum -= ub
ub=250
uwsum -= ub
if uwsum==49700
txt.print("3 ok\n")
else {
txt.print("3 fail:")
txt.print_uw(uwsum)
txt.chrout('\n')
}
wsum = -30000
bb = 100
wsum -= bb
bb = -50
wsum -= bb
if wsum==-30050
txt.print("4 ok\n")
else
txt.print("4 fail\n")
uwsum = 50000
bb=50
uwsum += bb as uword
bb=-100
uwsum += bb as uword
if uwsum==49950
txt.print("5 ok\n")
else
txt.print("5 fail\n")
uwsum = 50000
bb=50
uwsum -= bb as uword
bb=100
uwsum -= bb as uword
if uwsum==49850
txt.print("6 ok\n")
else {
txt.print("6 fail:")
txt.print_uw(uwsum)
txt.chrout('\n')
}
wsum = -30000
ub = 50
wsum += ub
ub = 250
wsum += ub
if wsum==-29700
txt.print("7 ok\n")
else {
txt.print("7 fail:")
txt.print_w(wsum)
txt.chrout('\n')
}
wsum = -30000
ub = 50
wsum -= ub
ub = 250
wsum -= ub
if wsum==-30300
txt.print("8 ok\n")
else {
txt.print("8 fail:")
txt.print_w(wsum)
txt.chrout('\n')
}
txt.chrout('\n')
uwsum = 50000
ub=0
uwsum += (50+ub)
uwsum += (250+ub)
if uwsum==50300
txt.print("1b ok\n")
else {
txt.print("1b fail:")
txt.print_uw(uwsum)
txt.chrout('\n')
}
bb = 0
wsum = -30000
wsum += (100+bb)
wsum += (-50+bb)
if wsum==-29950
txt.print("2b ok\n")
else {
txt.print("2b fail:")
txt.print_w(wsum)
txt.chrout('\n')
}
uwsum = 50000
uwsum -= (50+ub)
uwsum -= (250+ub)
if uwsum==49700
txt.print("3b ok\n")
else {
txt.print("3b fail:")
txt.print_uw(uwsum)
txt.chrout('\n')
}
wsum = -30000
wsum -= (100+bb)
wsum -= (-50+bb)
if wsum==-30050
txt.print("4b ok\n")
else
txt.print("4b fail\n")
uwsum = 50000
uwsum += (50+bb) as uword
uwsum += (-100+bb) as uword
if uwsum==49950
txt.print("5b ok\n")
else
txt.print("5b fail\n")
uwsum = 50000
uwsum -= (50+bb) as uword
uwsum -= (100+bb) as uword
if uwsum==49850
txt.print("6b ok\n")
else {
txt.print("6b fail:")
txt.print_uw(uwsum)
txt.chrout('\n')
}
wsum = -30000
wsum += (50+ub)
wsum += (250+ub)
if wsum==-29700
txt.print("7b ok\n")
else {
txt.print("7b fail:")
txt.print_w(wsum)
txt.chrout('\n')
}
wsum = -30000
wsum -= (50+ub)
wsum -= (250+ub)
if wsum==-30300
txt.print("8b ok\n")
else {
txt.print("8b fail:")
txt.print_w(wsum)
txt.chrout('\n')
}
txt.chrout('\n')
uwsum = 50000
uwsum += 50
uwsum += 250
if uwsum==50300
txt.print("1c ok\n")
else {
txt.print("1c fail:")
txt.print_uw(uwsum)
txt.chrout('\n')
}
wsum = -30000
wsum += 100
wsum += -50
if wsum==-29950
txt.print("2c ok\n")
else {
txt.print("2c fail:")
txt.print_w(wsum)
txt.chrout('\n')
}
uwsum = 50000
uwsum -= 50
uwsum -= 250
if uwsum==49700
txt.print("3c ok\n")
else {
txt.print("3c fail:")
txt.print_uw(uwsum)
txt.chrout('\n')
}
wsum = -30000
wsum -= 100
wsum -= -50
if wsum==-30050
txt.print("4c ok\n")
else
txt.print("4c fail\n")
uwsum = 50000
uwsum += 50 as uword
uwsum += -100 as uword
if uwsum==49950
txt.print("5c ok\n")
else
txt.print("5c fail\n")
uwsum = 50000
uwsum -= 50 as uword
uwsum -= 100 as uword
if uwsum==49850
txt.print("6c ok\n")
else {
txt.print("6c fail:")
txt.print_uw(uwsum)
txt.chrout('\n')
}
wsum = -30000
wsum += 50
wsum += 250
if wsum==-29700
txt.print("7c ok\n")
else {
txt.print("7c fail:")
txt.print_w(wsum)
txt.chrout('\n')
}
wsum = -30000
wsum -= 50
wsum -= 250
if wsum==-30300
txt.print("8c ok\n")
else {
txt.print("8c fail:")
txt.print_w(wsum)
txt.chrout('\n')
}
}
}

View File

@ -6,22 +6,7 @@
main { main {
sub start() { sub start() {
withX(1)
withX(2)
withX(3)
withY(6)
withY(7)
withY(8)
} }
asmsub withX(ubyte foo @X) {
%asm {{
rts
}}
}
asmsub withY(ubyte foo @Y) {
%asm {{
rts
}}
}
} }