mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
tweak to byte compares
This commit is contained in:
parent
2a1fec2ed2
commit
bc2ede76bf
@ -133,7 +133,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
|
||||
else
|
||||
translateIfElseBodies("beq", stmt)
|
||||
}
|
||||
"<" -> translateByteGreater(condition.right, condition.left, stmt, signed, jumpAfterIf)
|
||||
"<" -> translateByteLess(stmt, signed, jumpAfterIf)
|
||||
"<=" -> {
|
||||
// X<=Y -> Y>=X (reverse of >=)
|
||||
asmgen.assignExpressionToRegister(condition.right, RegisterOrPair.A, signed)
|
||||
@ -150,7 +150,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
|
||||
translateIfElseBodies("bcc", stmt)
|
||||
}
|
||||
}
|
||||
">" -> translateByteGreater(condition.left, condition.right, stmt, signed, jumpAfterIf)
|
||||
">" -> translateByteGreater(stmt, signed, jumpAfterIf)
|
||||
">=" -> {
|
||||
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
|
||||
cmpAwithByteValue(condition.right, false)
|
||||
@ -323,7 +323,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
|
||||
if(constIndex!=null) {
|
||||
val offset = constIndex * program.memsizer.memorySize(value.type)
|
||||
if(offset<256) {
|
||||
return asmgen.out(" ldy #$offset | $compare ${asmgen.asmVariableName(value.variable.name)},y")
|
||||
return asmgen.out(" ldy #$offset | $compare ${asmgen.asmVariableName(value.variable)},y")
|
||||
}
|
||||
}
|
||||
cmpViaScratch()
|
||||
@ -337,7 +337,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
is PtIdentifier -> {
|
||||
asmgen.out(" $compare ${asmgen.asmVariableName(value.name)}")
|
||||
asmgen.out(" $compare ${asmgen.asmVariableName(value)}")
|
||||
}
|
||||
is PtNumber -> {
|
||||
if(value.number!=0.0)
|
||||
@ -349,26 +349,50 @@ internal class IfElseAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateByteGreater(leftOperand: PtExpression, rightOperand: PtExpression, stmt: PtIfElse, signed: Boolean, jumpAfterIf: PtJump?) {
|
||||
private fun translateByteLess(stmt: PtIfElse, signed: Boolean, jumpAfterIf: PtJump?) {
|
||||
val condition = stmt.condition as PtBinaryExpression
|
||||
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
|
||||
cmpAwithByteValue(condition.right, false)
|
||||
if(signed) {
|
||||
// X>Y -> Y<X
|
||||
asmgen.assignExpressionToRegister(rightOperand, RegisterOrPair.A, signed)
|
||||
cmpAwithByteValue(leftOperand, true)
|
||||
if(jumpAfterIf!=null)
|
||||
translateJumpElseBodies("bmi", "bpl", jumpAfterIf, stmt.elseScope)
|
||||
else
|
||||
translateIfElseBodies("bpl", stmt)
|
||||
} else {
|
||||
if(jumpAfterIf!=null)
|
||||
translateJumpElseBodies("bcc", "bcs", jumpAfterIf, stmt.elseScope)
|
||||
else
|
||||
translateIfElseBodies("bcs", stmt)
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateByteGreater(stmt: PtIfElse, signed: Boolean, jumpAfterIf: PtJump?) {
|
||||
val condition = stmt.condition as PtBinaryExpression
|
||||
if(signed) {
|
||||
// TODO if compared to a number, a more optimized routine is possible (X>=Y+1)
|
||||
// X>Y --> Y<X
|
||||
asmgen.assignExpressionToRegister(condition.right, RegisterOrPair.A, signed)
|
||||
cmpAwithByteValue(condition.left, true)
|
||||
if (jumpAfterIf != null)
|
||||
translateJumpElseBodies("bmi", "bpl", jumpAfterIf, stmt.elseScope)
|
||||
else
|
||||
translateIfElseBodies("bpl", stmt)
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
|
||||
cmpAwithByteValue(condition.right, false)
|
||||
if(jumpAfterIf!=null) {
|
||||
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
|
||||
if(indirect) {
|
||||
// X>Y -> Y<X
|
||||
asmgen.out("""
|
||||
bvc +
|
||||
eor #128
|
||||
+ bpl +
|
||||
bcc +
|
||||
beq +
|
||||
jmp ($asmLabel)
|
||||
+""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
bvc +
|
||||
eor #128
|
||||
+ bmi $asmLabel""")
|
||||
beq +
|
||||
bcs $asmLabel
|
||||
+""")
|
||||
}
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
@ -376,33 +400,18 @@ internal class IfElseAsmGen(private val program: PtProgram,
|
||||
if(stmt.hasElse()) {
|
||||
// if and else blocks
|
||||
val elseLabel = asmgen.makeLabel("else")
|
||||
asmgen.out("""
|
||||
bvc +
|
||||
eor #128
|
||||
+ bpl $elseLabel""")
|
||||
asmgen.out(" bcc $elseLabel | beq $elseLabel")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
asmgen.jmp(afterIfLabel, false)
|
||||
asmgen.out(elseLabel)
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
// no else block
|
||||
asmgen.out("""
|
||||
bvc +
|
||||
eor #128
|
||||
+ bpl $afterIfLabel""")
|
||||
asmgen.out(" bcc $afterIfLabel | beq $afterIfLabel")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
}
|
||||
asmgen.out(afterIfLabel)
|
||||
}
|
||||
} else {
|
||||
// X>Y -> Y<X
|
||||
asmgen.assignExpressionToRegister(rightOperand, RegisterOrPair.A, signed)
|
||||
cmpAwithByteValue(leftOperand, false)
|
||||
if(jumpAfterIf!=null) {
|
||||
translateJumpElseBodies("bcc", "bcs", jumpAfterIf, stmt.elseScope)
|
||||
} else {
|
||||
translateIfElseBodies("bcs", stmt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,13 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
fix large code for while wptr!=&buffer
|
||||
|
||||
explore possible optimizations when comparing to a constant number:
|
||||
X < N --> X<=N-1
|
||||
X > N --> X>=N+1 etc etc some yield shorter code!!
|
||||
|
||||
|
||||
verify ifelse codegens to be shortest code: (some are using too many scratch vars?)
|
||||
uword >=
|
||||
uword >
|
||||
@ -12,7 +19,6 @@ word <=
|
||||
word <
|
||||
|
||||
|
||||
plasma is a bit larger
|
||||
floatparse is a bit larger
|
||||
testgfx2 is a bit larger
|
||||
amiga is a bit larger
|
||||
|
419
examples/test.p8
419
examples/test.p8
@ -1,397 +1,48 @@
|
||||
|
||||
%import math
|
||||
%import textio
|
||||
%import floats
|
||||
%import test_stack
|
||||
%zeropage dontuse
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
ubyte success = 0
|
||||
str datatype = "uword"
|
||||
uword @shared comparison
|
||||
|
||||
sub start() {
|
||||
txt.print("\ngreater-equal tests for: ")
|
||||
txt.print(datatype)
|
||||
txt.nl()
|
||||
test_stack.test()
|
||||
txt.print("\n>=number: ")
|
||||
test_cmp_number()
|
||||
/*
|
||||
txt.print("\n>=var: ")
|
||||
test_cmp_var()
|
||||
txt.print("\n>=array[]: ")
|
||||
test_cmp_array()
|
||||
txt.print("\n>=expr: ")
|
||||
test_cmp_expr()
|
||||
*/
|
||||
test_stack.test()
|
||||
uword @shared wptr
|
||||
str buffer=" "
|
||||
|
||||
; TODO: these generate LARGE code
|
||||
while wptr!=&buffer
|
||||
cx16.r0L++
|
||||
while wptr==&buffer
|
||||
cx16.r0L++
|
||||
|
||||
; ... these are fine:
|
||||
while wptr!=cx16.r0
|
||||
cx16.r0L++
|
||||
while wptr==cx16.r0
|
||||
cx16.r0L++
|
||||
|
||||
|
||||
if ub() > 5
|
||||
cx16.r0L++
|
||||
|
||||
if ub() < 5
|
||||
cx16.r0L++
|
||||
|
||||
if sb() > 5
|
||||
cx16.r0L++
|
||||
|
||||
if sb() < 5
|
||||
cx16.r0L++
|
||||
|
||||
}
|
||||
|
||||
sub verify_success(ubyte expected) {
|
||||
if success==expected {
|
||||
txt.print_ub(success)
|
||||
txt.print(" successes ok")
|
||||
} else {
|
||||
txt.print(" **failed** ")
|
||||
txt.print_ub(success)
|
||||
txt.print(" success, expected ")
|
||||
txt.print_ub(expected)
|
||||
}
|
||||
sub ub() -> ubyte {
|
||||
cx16.r0++
|
||||
return cx16.r0L
|
||||
}
|
||||
|
||||
sub fail_byte(uword idx) {
|
||||
txt.print(" **fail#")
|
||||
txt.print_uw(idx)
|
||||
txt.print(" **")
|
||||
sub sb() -> byte {
|
||||
cx16.r0++
|
||||
return cx16.r0sL
|
||||
}
|
||||
|
||||
sub fail_ubyte(uword idx) {
|
||||
txt.print(" **fail#")
|
||||
txt.print_uw(idx)
|
||||
txt.print(" **")
|
||||
}
|
||||
|
||||
sub fail_word(uword idx) {
|
||||
txt.print(" **fail#")
|
||||
txt.print_uw(idx)
|
||||
txt.print(" **")
|
||||
}
|
||||
|
||||
sub fail_uword(uword idx) {
|
||||
txt.print(" **fail#")
|
||||
txt.print_uw(idx)
|
||||
txt.print(" **")
|
||||
}
|
||||
|
||||
sub fail_float(uword idx) {
|
||||
txt.print(" **fail#")
|
||||
txt.print_uw(idx)
|
||||
txt.print(" **")
|
||||
}
|
||||
|
||||
|
||||
sub test_cmp_number() {
|
||||
uword @shared x = 65500
|
||||
if x>=65500
|
||||
goto lbl4a
|
||||
goto skip4a
|
||||
lbl4a: txt.print("should see this!\n")
|
||||
skip4a:
|
||||
}
|
||||
|
||||
/*
|
||||
sub test_cmp_var() {
|
||||
uword @shared x, value
|
||||
success = 0
|
||||
x=0
|
||||
value=0
|
||||
; direct jump
|
||||
if x>=value
|
||||
goto lbl1a
|
||||
goto skip1a
|
||||
lbl1a: success++
|
||||
skip1a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl1b
|
||||
if x>=value
|
||||
goto cx16.r3
|
||||
goto skip1b
|
||||
lbl1b: success++
|
||||
skip1b:
|
||||
; no else
|
||||
if x>=value
|
||||
success++
|
||||
|
||||
; with else
|
||||
if x>=value
|
||||
success++
|
||||
else
|
||||
cx16.r0L++
|
||||
|
||||
value=65535
|
||||
; direct jump
|
||||
if x>=value
|
||||
goto lbl2a
|
||||
goto skip2a
|
||||
lbl2a: fail_uword(5)
|
||||
skip2a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl2b
|
||||
if x>=value
|
||||
goto cx16.r3
|
||||
goto skip2b
|
||||
lbl2b: fail_uword(6)
|
||||
skip2b:
|
||||
; no else
|
||||
if x>=value
|
||||
fail_uword(7)
|
||||
|
||||
; with else
|
||||
if x>=value
|
||||
fail_uword(8)
|
||||
else
|
||||
success++
|
||||
|
||||
x=65535
|
||||
value=0
|
||||
; direct jump
|
||||
if x>=value
|
||||
goto lbl3a
|
||||
goto skip3a
|
||||
lbl3a: success++
|
||||
skip3a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl3b
|
||||
if x>=value
|
||||
goto cx16.r3
|
||||
goto skip3b
|
||||
lbl3b: success++
|
||||
skip3b:
|
||||
; no else
|
||||
if x>=value
|
||||
success++
|
||||
|
||||
; with else
|
||||
if x>=value
|
||||
success++
|
||||
else
|
||||
cx16.r0L++
|
||||
|
||||
value=65535
|
||||
; direct jump
|
||||
if x>=value
|
||||
goto lbl4a
|
||||
goto skip4a
|
||||
lbl4a: success++
|
||||
skip4a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl4b
|
||||
if x>=value
|
||||
goto cx16.r3
|
||||
goto skip4b
|
||||
lbl4b: success++
|
||||
skip4b:
|
||||
; no else
|
||||
if x>=value
|
||||
success++
|
||||
|
||||
; with else
|
||||
if x>=value
|
||||
success++
|
||||
else
|
||||
cx16.r0L++
|
||||
|
||||
verify_success(13)
|
||||
}
|
||||
sub test_cmp_array() {
|
||||
uword @shared x
|
||||
uword[] values = [0, 0]
|
||||
success = 0
|
||||
x=0
|
||||
values[1]=0
|
||||
; direct jump
|
||||
if x>=values[1]
|
||||
goto lbl1a
|
||||
goto skip1a
|
||||
lbl1a: success++
|
||||
skip1a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl1b
|
||||
if x>=values[1]
|
||||
goto cx16.r3
|
||||
goto skip1b
|
||||
lbl1b: success++
|
||||
skip1b:
|
||||
; no else
|
||||
if x>=values[1]
|
||||
success++
|
||||
|
||||
; with else
|
||||
if x>=values[1]
|
||||
success++
|
||||
else
|
||||
cx16.r0L++
|
||||
|
||||
values[1]=65535
|
||||
; direct jump
|
||||
if x>=values[1]
|
||||
goto lbl2a
|
||||
goto skip2a
|
||||
lbl2a: fail_uword(9)
|
||||
skip2a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl2b
|
||||
if x>=values[1]
|
||||
goto cx16.r3
|
||||
goto skip2b
|
||||
lbl2b: fail_uword(10)
|
||||
skip2b:
|
||||
; no else
|
||||
if x>=values[1]
|
||||
fail_uword(11)
|
||||
|
||||
; with else
|
||||
if x>=values[1]
|
||||
fail_uword(12)
|
||||
else
|
||||
success++
|
||||
|
||||
x=65535
|
||||
values[1]=0
|
||||
; direct jump
|
||||
if x>=values[1]
|
||||
goto lbl3a
|
||||
goto skip3a
|
||||
lbl3a: success++
|
||||
skip3a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl3b
|
||||
if x>=values[1]
|
||||
goto cx16.r3
|
||||
goto skip3b
|
||||
lbl3b: success++
|
||||
skip3b:
|
||||
; no else
|
||||
if x>=values[1]
|
||||
success++
|
||||
|
||||
; with else
|
||||
if x>=values[1]
|
||||
success++
|
||||
else
|
||||
cx16.r0L++
|
||||
|
||||
values[1]=65535
|
||||
; direct jump
|
||||
if x>=values[1]
|
||||
goto lbl4a
|
||||
goto skip4a
|
||||
lbl4a: success++
|
||||
skip4a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl4b
|
||||
if x>=values[1]
|
||||
goto cx16.r3
|
||||
goto skip4b
|
||||
lbl4b: success++
|
||||
skip4b:
|
||||
; no else
|
||||
if x>=values[1]
|
||||
success++
|
||||
|
||||
; with else
|
||||
if x>=values[1]
|
||||
success++
|
||||
else
|
||||
cx16.r0L++
|
||||
|
||||
verify_success(13)
|
||||
}
|
||||
sub test_cmp_expr() {
|
||||
uword @shared x
|
||||
cx16.r4 = 1
|
||||
cx16.r5 = 1
|
||||
float @shared f4 = 1.0
|
||||
float @shared f5 = 1.0
|
||||
success = 0
|
||||
x=0
|
||||
; direct jump
|
||||
if x>=cx16.r4+0-cx16.r5
|
||||
goto lbl1a
|
||||
goto skip1a
|
||||
lbl1a: success++
|
||||
skip1a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl1b
|
||||
if x>=cx16.r4+0-cx16.r5
|
||||
goto cx16.r3
|
||||
goto skip1b
|
||||
lbl1b: success++
|
||||
skip1b:
|
||||
; no else
|
||||
if x>=cx16.r4+0-cx16.r5
|
||||
success++
|
||||
|
||||
; with else
|
||||
if x>=cx16.r4+0-cx16.r5
|
||||
success++
|
||||
else
|
||||
cx16.r0L++
|
||||
|
||||
; direct jump
|
||||
if x>=cx16.r4+65535-cx16.r5
|
||||
goto lbl2a
|
||||
goto skip2a
|
||||
lbl2a: fail_uword(13)
|
||||
skip2a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl2b
|
||||
if x>=cx16.r4+65535-cx16.r5
|
||||
goto cx16.r3
|
||||
goto skip2b
|
||||
lbl2b: fail_uword(14)
|
||||
skip2b:
|
||||
; no else
|
||||
if x>=cx16.r4+65535-cx16.r5
|
||||
fail_uword(15)
|
||||
|
||||
; with else
|
||||
if x>=cx16.r4+65535-cx16.r5
|
||||
fail_uword(16)
|
||||
else
|
||||
success++
|
||||
|
||||
x=65535
|
||||
; direct jump
|
||||
if x>=cx16.r4+0-cx16.r5
|
||||
goto lbl3a
|
||||
goto skip3a
|
||||
lbl3a: success++
|
||||
skip3a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl3b
|
||||
if x>=cx16.r4+0-cx16.r5
|
||||
goto cx16.r3
|
||||
goto skip3b
|
||||
lbl3b: success++
|
||||
skip3b:
|
||||
; no else
|
||||
if x>=cx16.r4+0-cx16.r5
|
||||
success++
|
||||
|
||||
; with else
|
||||
if x>=cx16.r4+0-cx16.r5
|
||||
success++
|
||||
else
|
||||
cx16.r0L++
|
||||
|
||||
; direct jump
|
||||
if x>=cx16.r4+65535-cx16.r5
|
||||
goto lbl4a
|
||||
goto skip4a
|
||||
lbl4a: success++
|
||||
skip4a:
|
||||
; indirect jump
|
||||
cx16.r3 = &lbl4b
|
||||
if x>=cx16.r4+65535-cx16.r5
|
||||
goto cx16.r3
|
||||
goto skip4b
|
||||
lbl4b: success++
|
||||
skip4b:
|
||||
; no else
|
||||
if x>=cx16.r4+65535-cx16.r5
|
||||
success++
|
||||
|
||||
; with else
|
||||
if x>=cx16.r4+65535-cx16.r5
|
||||
success++
|
||||
else
|
||||
cx16.r0L++
|
||||
|
||||
verify_success(13)
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user