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