fix codegen error for comparisons

This commit is contained in:
Irmen de Jong 2024-02-25 05:02:50 +01:00
parent 004048e5a7
commit 2a1fec2ed2
6 changed files with 660 additions and 1889 deletions

View File

@ -26,7 +26,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
val compareCond = stmt.condition as? PtBinaryExpression
if(compareCond!=null) {
return when(compareCond.right.type) {
in ByteDatatypesWithBoolean -> translateIfByte(stmt, compareCond, jumpAfterIf)
in ByteDatatypesWithBoolean -> translateIfByte(stmt, jumpAfterIf)
in WordDatatypes -> translateIfWord(stmt, compareCond, jumpAfterIf)
DataType.FLOAT -> translateIfFloat(stmt, compareCond, jumpAfterIf)
else -> throw AssemblyError("weird dt")
@ -106,32 +106,19 @@ internal class IfElseAsmGen(private val program: PtProgram,
asmgen.translate(elseBlock)
}
private fun translateIfByte(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
private fun translateIfByte(stmt: PtIfElse, jumpAfterIf: PtJump?) {
val condition = stmt.condition as PtBinaryExpression
val signed = condition.left.type in SignedDatatypes
val constValue = condition.right.asConstInteger()
if(constValue==0) {
if(condition.operator=="==") {
// if X==0
assignConditionValueToRegisterAndTest(condition.left)
return if(jumpAfterIf!=null)
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("bne", stmt)
} else if(condition.operator=="!=") {
// if X!=0
assignConditionValueToRegisterAndTest(condition.left)
return if(jumpAfterIf!=null)
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("beq", stmt)
}
return translateIfCompareWithZeroByte(stmt, signed, jumpAfterIf)
}
when (condition.operator) {
"==" -> {
// if X==value
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
cmpAwithByteValue(condition.right)
cmpAwithByteValue(condition.right, false)
return if(jumpAfterIf!=null)
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
else
@ -140,32 +127,33 @@ internal class IfElseAsmGen(private val program: PtProgram,
"!=" -> {
// if X!=value
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
cmpAwithByteValue(condition.right)
cmpAwithByteValue(condition.right, false)
return if(jumpAfterIf!=null)
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("beq", stmt)
}
"<" -> {
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
cmpAwithByteValue(condition.right)
"<" -> translateByteGreater(condition.right, condition.left, stmt, signed, jumpAfterIf)
"<=" -> {
// X<=Y -> Y>=X (reverse of >=)
asmgen.assignExpressionToRegister(condition.right, RegisterOrPair.A, signed)
cmpAwithByteValue(condition.left, false)
return if(signed) {
if(jumpAfterIf!=null)
translateJumpElseBodies("bmi", "bpl", jumpAfterIf, stmt.elseScope)
translateJumpElseBodies("bpl", "bmi", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("bpl", stmt)
translateIfElseBodies("bmi", stmt)
} else {
if(jumpAfterIf!=null)
translateJumpElseBodies("bcc", "bcs", jumpAfterIf, stmt.elseScope)
translateJumpElseBodies("bcs", "bcc", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("bcs", stmt)
translateIfElseBodies("bcc", stmt)
}
}
"<=" -> translateByteLessEqual(stmt, signed, jumpAfterIf)
">" -> translateByteGreater(stmt, signed, jumpAfterIf)
">" -> translateByteGreater(condition.left, condition.right, stmt, signed, jumpAfterIf)
">=" -> {
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
cmpAwithByteValue(condition.right)
cmpAwithByteValue(condition.right, false)
return if(signed) {
if(jumpAfterIf!=null)
translateJumpElseBodies("bpl", "bmi", jumpAfterIf, stmt.elseScope)
@ -182,7 +170,141 @@ internal class IfElseAsmGen(private val program: PtProgram,
}
}
private fun cmpAwithByteValue(value: PtExpression) {
private fun translateIfCompareWithZeroByte(stmt: PtIfElse, signed: Boolean, jumpAfterIf: PtJump?) {
// optimized code for byte comparisons with 0
val condition = stmt.condition as PtBinaryExpression
assignConditionValueToRegisterAndTest(condition.left)
when (condition.operator) {
"==" -> {
return if(jumpAfterIf!=null)
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("bne", stmt)
}
"!=" -> {
return if(jumpAfterIf!=null)
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("beq", stmt)
}
">" -> {
if(signed) {
return if (jumpAfterIf != null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
if(indirect) {
asmgen.out("""
bmi +
beq +
jmp ($asmLabel)
+""")
} else {
asmgen.out("""
beq +
bpl $asmLabel
+""")
}
asmgen.translate(stmt.elseScope)
}
else {
val afterIfLabel = asmgen.makeLabel("afterif")
if(stmt.hasElse()) {
// if and else blocks
val elseLabel = asmgen.makeLabel("else")
asmgen.out(" bmi $elseLabel | beq $elseLabel")
asmgen.translate(stmt.ifScope)
asmgen.jmp(afterIfLabel, false)
asmgen.out(elseLabel)
asmgen.translate(stmt.elseScope)
} else {
// no else block
asmgen.out(" bmi $afterIfLabel | beq $afterIfLabel")
asmgen.translate(stmt.ifScope)
}
asmgen.out(afterIfLabel)
}
} else {
return if (jumpAfterIf != null)
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("beq", stmt)
}
}
">=" -> {
if(signed) {
return if (jumpAfterIf != null)
translateJumpElseBodies("bpl", "bmi", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("bmi", stmt)
} else {
// always true for unsigned
asmgen.translate(stmt.ifScope)
}
}
"<" -> {
if(signed) {
return if (jumpAfterIf != null)
translateJumpElseBodies("bmi", "bpl", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("bpl", stmt)
} else {
// always false for unsigned
asmgen.translate(stmt.elseScope)
}
}
"<=" -> {
if(signed) {
// inverted '>'
return if (jumpAfterIf != null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
if(indirect) {
asmgen.out("""
bmi +
bne ++
+ jmp ($asmLabel)
+""")
} else {
asmgen.out("""
bmi $asmLabel
beq $asmLabel""")
}
asmgen.translate(stmt.elseScope)
}
else {
val afterIfLabel = asmgen.makeLabel("afterif")
if(stmt.hasElse()) {
// if and else blocks
val elseLabel = asmgen.makeLabel("else")
asmgen.out("""
beq +
bpl $elseLabel
+""")
asmgen.translate(stmt.ifScope)
asmgen.jmp(afterIfLabel, false)
asmgen.out(elseLabel)
asmgen.translate(stmt.elseScope)
} else {
// no else block
asmgen.out("""
beq +
bpl $afterIfLabel
+""")
asmgen.translate(stmt.ifScope)
}
asmgen.out(afterIfLabel)
}
} else {
return if(jumpAfterIf!=null)
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("bne", stmt)
}
}
else -> throw AssemblyError("weird operator")
}
}
private fun cmpAwithByteValue(value: PtExpression, useSbc: Boolean) {
val compare = if(useSbc) "sec | sbc" else "cmp"
fun cmpViaScratch() {
if(assignmentAsmGen.directIntoY(value)) {
asmgen.assignExpressionToRegister(value, RegisterOrPair.Y, false)
@ -192,7 +314,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_REG", value.type)
asmgen.out(" pla")
}
asmgen.out(" cmp P8ZP_SCRATCH_REG")
asmgen.out(" $compare P8ZP_SCRATCH_REG")
}
when(value) {
@ -201,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 | cmp ${asmgen.asmVariableName(value.variable.name)},y")
return asmgen.out(" ldy #$offset | $compare ${asmgen.asmVariableName(value.variable.name)},y")
}
}
cmpViaScratch()
@ -209,17 +331,17 @@ internal class IfElseAsmGen(private val program: PtProgram,
is PtMemoryByte -> {
val constAddr = value.address.asConstInteger()
if(constAddr!=null) {
asmgen.out(" cmp ${constAddr.toHex()}")
asmgen.out(" $compare ${constAddr.toHex()}")
} else {
cmpViaScratch()
}
}
is PtIdentifier -> {
asmgen.out(" cmp ${asmgen.asmVariableName(value.name)}")
asmgen.out(" $compare ${asmgen.asmVariableName(value.name)}")
}
is PtNumber -> {
if(value.number!=0.0)
asmgen.out(" cmp #${value.number.toInt()}")
asmgen.out(" $compare #${value.number.toInt()}")
}
else -> {
cmpViaScratch()
@ -227,129 +349,59 @@ internal class IfElseAsmGen(private val program: PtProgram,
}
}
private fun translateByteLessEqual(stmt: PtIfElse, signed: Boolean, jumpAfterIf: PtJump?) {
fun bodies(greaterBranches: Pair<String, String>, stmt: PtIfElse) {
// comparison value is already in A
val afterIfLabel = asmgen.makeLabel("afterif")
if(stmt.hasElse()) {
// if and else blocks
val elseLabel = asmgen.makeLabel("else")
asmgen.out("""
${greaterBranches.first} +
${greaterBranches.second} $elseLabel
private fun translateByteGreater(leftOperand: PtExpression, rightOperand: PtExpression, stmt: PtIfElse, signed: Boolean, jumpAfterIf: PtJump?) {
if(signed) {
// X>Y -> Y<X
asmgen.assignExpressionToRegister(rightOperand, RegisterOrPair.A, signed)
cmpAwithByteValue(leftOperand, true)
if(jumpAfterIf!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
if(indirect) {
// X>Y -> Y<X
asmgen.out("""
bvc +
eor #128
+ bpl +
jmp ($asmLabel)
+""")
asmgen.translate(stmt.ifScope)
asmgen.jmp(afterIfLabel, false)
asmgen.out(elseLabel)
} else {
asmgen.out("""
bvc +
eor #128
+ bmi $asmLabel""")
}
asmgen.translate(stmt.elseScope)
} else {
// no else block
asmgen.out("""
${greaterBranches.first} +
${greaterBranches.second} $afterIfLabel
+""")
asmgen.translate(stmt.ifScope)
}
asmgen.out(afterIfLabel)
}
fun bodies(
branches: Pair<String, String>,
greaterBranches: Pair<String, String>,
jump: PtJump,
elseBlock: PtNodeGroup
) {
// comparison value is already in A
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
asmgen.out("""
${greaterBranches.first} +
${greaterBranches.second} ++
+ jmp ($asmLabel)
+""")
} else {
asmgen.out(" ${branches.first} $asmLabel | ${branches.second} $asmLabel")
}
asmgen.translate(elseBlock)
}
val condition = stmt.condition as PtBinaryExpression
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
cmpAwithByteValue(condition.right)
if(signed) {
if(jumpAfterIf!=null) {
bodies("bmi" to "beq", "beq" to "bpl", jumpAfterIf, stmt.elseScope)
} else {
bodies("beq" to "bpl", stmt)
val afterIfLabel = asmgen.makeLabel("afterif")
if(stmt.hasElse()) {
// if and else blocks
val elseLabel = asmgen.makeLabel("else")
asmgen.out("""
bvc +
eor #128
+ bpl $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.translate(stmt.ifScope)
}
asmgen.out(afterIfLabel)
}
} else {
// X>Y -> Y<X
asmgen.assignExpressionToRegister(rightOperand, RegisterOrPair.A, signed)
cmpAwithByteValue(leftOperand, false)
if(jumpAfterIf!=null) {
bodies("bcc" to "beq", "beq" to "bcs", jumpAfterIf, stmt.elseScope)
translateJumpElseBodies("bcc", "bcs", jumpAfterIf, stmt.elseScope)
} else {
bodies("beq" to "bcs", stmt)
}
}
}
private fun translateByteGreater(stmt: PtIfElse, signed: Boolean, jumpAfterIf: PtJump?) {
fun bodies(lessEqBranches: Pair<String, String>, stmt: PtIfElse) {
// comparison value is already in A
val afterIfLabel = asmgen.makeLabel("afterif")
if(stmt.hasElse()) {
// if and else blocks
val elseLabel = asmgen.makeLabel("else")
asmgen.out(" ${lessEqBranches.first} $elseLabel | ${lessEqBranches.second} $elseLabel")
asmgen.translate(stmt.ifScope)
asmgen.jmp(afterIfLabel, false)
asmgen.out(elseLabel)
asmgen.translate(stmt.elseScope)
} else {
// no else block
asmgen.out(" ${lessEqBranches.first} $afterIfLabel | ${lessEqBranches.second} $afterIfLabel")
asmgen.translate(stmt.ifScope)
}
asmgen.out(afterIfLabel)
}
fun bodies(
branches: Pair<String, String>,
lessEqBranches: Pair<String, String>,
jump: PtJump,
elseBlock: PtNodeGroup
) {
// comparison value is already in A
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
asmgen.out("""
${lessEqBranches.first} +
${lessEqBranches.second} +
jmp ($asmLabel)
+""")
} else {
asmgen.out("""
${branches.first} +
${branches.second} $asmLabel
+""")
}
asmgen.translate(elseBlock)
}
val condition = stmt.condition as PtBinaryExpression
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
cmpAwithByteValue(condition.right)
if(signed) {
if(jumpAfterIf!=null) {
bodies("beq" to "bpl", "bmi" to "beq", jumpAfterIf, stmt.elseScope)
} else {
bodies("bmi" to "beq", stmt)
}
} else {
if(jumpAfterIf!=null) {
bodies("beq" to "bcs", "bcc" to "beq", jumpAfterIf, stmt.elseScope)
} else {
bodies("bcc" to "beq", stmt)
translateIfElseBodies("bcs", stmt)
}
}
}
@ -520,7 +572,7 @@ _jump jmp ($asmLabel)
if(right is PtIdentifier) {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed)
val variable = asmgen.asmVariableName(right)
return code("#<$variable", "#>$variable")
return code(variable, variable+"+1")
}
// TODO optimize for simple array value
@ -665,7 +717,7 @@ _jump jmp ($asmLabel)
if(right is PtIdentifier) {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed)
val variable = asmgen.asmVariableName(right)
return code("#<$variable", "#>$variable")
return code(variable, variable+"+1")
}
// TODO optimize for simple array value
@ -754,8 +806,8 @@ _jump jmp ($asmLabel)
sbc $valueMsb
ora P8ZP_SCRATCH_REG
beq +
bcc +
jmp ($asmLabel)
bcs ++
+ jmp ($asmLabel)
+""")
} else {
asmgen.out("""
@ -765,9 +817,8 @@ _jump jmp ($asmLabel)
tya
sbc $valueMsb
ora P8ZP_SCRATCH_REG
beq +
bcs $asmLabel
+""")
beq $asmLabel
bcc $asmLabel""")
}
} else {
val afterIfLabel = asmgen.makeLabel("afterif")
@ -782,7 +833,7 @@ _jump jmp ($asmLabel)
sbc $valueMsb
ora P8ZP_SCRATCH_REG
beq +
bcc $elseLabel
bcs $elseLabel
+""")
asmgen.translate(stmt.ifScope)
asmgen.jmp(afterIfLabel, false)
@ -798,7 +849,7 @@ _jump jmp ($asmLabel)
sbc $valueMsb
ora P8ZP_SCRATCH_REG
beq +
bcc $afterIfLabel
bcs $afterIfLabel
+""")
asmgen.translate(stmt.ifScope)
}
@ -816,7 +867,7 @@ _jump jmp ($asmLabel)
if(right is PtIdentifier) {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed)
val variable = asmgen.asmVariableName(right)
return code("#<$variable", "#>$variable")
return code(variable, variable+"+1")
}
// TODO optimize for simple array value
@ -838,7 +889,7 @@ _jump jmp ($asmLabel)
cmp $valueLsb
tya
sbc $valueMsb
bvc +
bvs +
eor #128
+ bpl +
jmp ($asmLabel)
@ -890,7 +941,7 @@ _jump jmp ($asmLabel)
cmp $valueLsb
tya
sbc $valueMsb
bcs +
bcc +
jmp ($asmLabel)
+""")
} else {
@ -937,7 +988,7 @@ _jump jmp ($asmLabel)
if(right is PtIdentifier) {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed)
val variable = asmgen.asmVariableName(right)
return code("#<$variable", "#>$variable")
return code(variable, variable+"+1")
}
// TODO optimize for simple array value

View File

@ -6,10 +6,10 @@ package prog8.buildversion
const val MAVEN_GROUP = "prog8"
const val MAVEN_NAME = "compiler"
const val VERSION = "10.2-BOOLEANS"
const val GIT_REVISION = 4485
const val GIT_SHA = "eddf97191959f87119c746d8833b71a247db661d"
const val GIT_DATE = "2024-02-15T23:58:56Z"
const val GIT_REVISION = 4512
const val GIT_SHA = "a977e3402faab7f2b63af7127fd628cbbdb8a7ad"
const val GIT_DATE = "2024-02-25T15:41:16Z"
const val GIT_BRANCH = "booleans"
const val BUILD_DATE = "2024-02-16T00:19:00Z"
const val BUILD_UNIX_TIME = 1708042740125L
const val BUILD_DATE = "2024-02-25T16:07:25Z"
const val BUILD_UNIX_TIME = 1708877245670L
const val DIRTY = 1

View File

@ -153,6 +153,11 @@ internal class AstChecker(private val program: Program,
if(!ifElse.condition.inferType(program).isBool)
errors.err("condition should be a boolean", ifElse.condition.position)
val constvalue = ifElse.condition.constValue(program)
if(constvalue!=null) {
errors.warn("condition is always ${constvalue.asBooleanValue}", ifElse.condition.position)
}
super.visit(ifElse)
}

View File

@ -54,53 +54,33 @@ main {{
}}
}}
sub fail_byte(uword idx, byte v1, byte v2) {{
sub fail_byte(uword idx) {{
txt.print(" **fail#")
txt.print_uw(idx)
txt.chrout(':')
txt.print_b(v1)
txt.chrout(',')
txt.print_b(v2)
txt.print(" **")
}}
sub fail_ubyte(uword idx, ubyte v1, ubyte v2) {{
sub fail_ubyte(uword idx) {{
txt.print(" **fail#")
txt.print_uw(idx)
txt.chrout(':')
txt.print_ub(v1)
txt.chrout(',')
txt.print_ub(v2)
txt.print(" **")
}}
sub fail_word(uword idx, word v1, word v2) {{
sub fail_word(uword idx) {{
txt.print(" **fail#")
txt.print_uw(idx)
txt.chrout(':')
txt.print_w(v1)
txt.chrout(',')
txt.print_w(v2)
txt.print(" **")
}}
sub fail_uword(uword idx, uword v1, uword v2) {{
sub fail_uword(uword idx) {{
txt.print(" **fail#")
txt.print_uw(idx)
txt.chrout(':')
txt.print_uw(v1)
txt.chrout(',')
txt.print_uw(v2)
txt.print(" **")
}}
sub fail_float(uword idx, float v1, float v2) {{
sub fail_float(uword idx) {{
txt.print(" **fail#")
txt.print_uw(idx)
txt.chrout(':')
floats.print(v1)
txt.chrout(',')
floats.print(v2)
txt.print(" **")
}}
@ -115,9 +95,9 @@ def tc(value):
testnumbers = {
"byte": [-100, 0, 100],
"byte": [-1, 0, 1],
"ubyte": [0, 1, 255],
"word": [tc(0xaabb), 0, 0x00aa, 0x7700, 0x7fff],
"word": [tc(0xaabb), -1, 0, 1, 0x00aa, 0x7700, 0x7fff],
"uword": [0, 1, 0x7700, 0xffff],
"float": [0.0, 1234.56]
}
@ -143,15 +123,18 @@ def make_test_number(datatype, comparison: C):
true_action2 = "success++"
true_action3 = "success++"
true_action4 = "success++"
fail_action4 = "cx16.r0L++"
else:
fail_index += 1
true_action1 = f"fail_{datatype}({fail_index},x,{value})"
true_action1 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action2 = f"fail_{datatype}({fail_index},x,{value})"
true_action2 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action3 = f"fail_{datatype}({fail_index},x,{value})"
true_action3 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action4 = f"fail_{datatype}({fail_index},x,{value})"
true_action4 = f"fail_{datatype}({fail_index})"
fail_action4 = "success++"
expected += 1
print(f""" ; direct jump
if x{comp}{value}
goto lbl{test_index}a
@ -173,7 +156,7 @@ skip{test_index}b:
if x{comp}{value}
{true_action4}
else
cx16.r0L++
{fail_action4}
""")
print(f" verify_success({expected})\n}}")
@ -189,8 +172,6 @@ def make_test_var(datatype, comparison: C):
for x in numbers:
print(f" x={x}")
for value in numbers:
if value == 0:
continue # 0 already tested separately
print(f" value={value}")
result = comparison.compare(x, value)
comp = comparison.operator
@ -201,15 +182,18 @@ def make_test_var(datatype, comparison: C):
true_action2 = "success++"
true_action3 = "success++"
true_action4 = "success++"
fail_action4 = "cx16.r0L++"
else:
fail_index += 1
true_action1 = f"fail_{datatype}({fail_index},x,value)"
true_action1 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action2 = f"fail_{datatype}({fail_index},x,value)"
true_action2 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action3 = f"fail_{datatype}({fail_index},x,value)"
true_action3 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action4 = f"fail_{datatype}({fail_index},x,value)"
true_action4 = f"fail_{datatype}({fail_index})"
fail_action4 = "success++"
expected += 1
print(f""" ; direct jump
if x{comp}value
goto lbl{test_index}a
@ -231,7 +215,7 @@ skip{test_index}b:
if x{comp}value
{true_action4}
else
cx16.r0L++
{fail_action4}
""")
print(f" verify_success({expected})\n}}")
@ -248,8 +232,6 @@ def make_test_array(datatype, comparison: C):
for x in numbers:
print(f" x={x}")
for value in numbers:
if value == 0:
continue # 0 already tested separately
print(f" values[1]={value}")
result = comparison.compare(x, value)
comp = comparison.operator
@ -260,15 +242,18 @@ def make_test_array(datatype, comparison: C):
true_action2 = "success++"
true_action3 = "success++"
true_action4 = "success++"
fail_action4 = "cx16.r0L++"
else:
fail_index += 1
true_action1 = f"fail_{datatype}({fail_index},x,{value})"
true_action1 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action2 = f"fail_{datatype}({fail_index},x,{value})"
true_action2 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action3 = f"fail_{datatype}({fail_index},x,{value})"
true_action3 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action4 = f"fail_{datatype}({fail_index},x,{value})"
true_action4 = f"fail_{datatype}({fail_index})"
fail_action4 = "success++"
expected += 1
print(f""" ; direct jump
if x{comp}values[1]
goto lbl{test_index}a
@ -290,7 +275,7 @@ skip{test_index}b:
if x{comp}values[1]
{true_action4}
else
cx16.r0L++
{fail_action4}
""")
print(f" verify_success({expected})\n}}")
@ -310,8 +295,6 @@ def make_test_expr(datatype, comparison: C):
for x in numbers:
print(f" x={x}")
for value in numbers:
if value == 0:
continue # 0 already tested separately
if datatype=="byte":
expr = f"cx16.r4sL+{value}-cx16.r5sL"
elif datatype=="ubyte":
@ -331,15 +314,18 @@ def make_test_expr(datatype, comparison: C):
true_action2 = "success++"
true_action3 = "success++"
true_action4 = "success++"
fail_action4 = "cx16.r0L++"
else:
fail_index += 1
true_action1 = f"fail_{datatype}({fail_index},x,{value})"
true_action1 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action2 = f"fail_{datatype}({fail_index},x,{value})"
true_action2 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action3 = f"fail_{datatype}({fail_index},x,{value})"
true_action3 = f"fail_{datatype}({fail_index})"
fail_index += 1
true_action4 = f"fail_{datatype}({fail_index},x,{value})"
true_action4 = f"fail_{datatype}({fail_index})"
fail_action4 = "success++"
expected += 1
print(f""" ; direct jump
if x{comp}{expr}
goto lbl{test_index}a
@ -361,7 +347,7 @@ skip{test_index}b:
if x{comp}{expr}
{true_action4}
else
cx16.r0L++
{fail_action4}
""")
print(f" verify_success({expected})\n}}")

View File

@ -1,36 +1,32 @@
TODO
====
add tests for comparison that do an assignment rather than an if.
fix ifelse codegens:
byte >= (all 4 paths)
byte > (all 4 paths)
byte <= (all 4 paths)
byte < (all 4 paths)
uword >= (all 4 paths)
uword > (var and array)
uword <= (all 4 paths)
uword < (var)
word >= (all 4 paths)
word > (var, array)
word <= (var)
word < (var)
verify ifelse codegens to be shortest code: (some are using too many scratch vars?)
uword >=
uword >
uword <=
uword <
word >=
word >
word <=
word <
improve code size for "wordGreaterValue" et al.
plasma is a bit larger
floatparse is a bit larger
testgfx2 is a bit larger
amiga is a bit larger
halloween is 1 byte larger
rockrunner is bigger than on 10.1
paint is slightly bigger than on 10.1
chess is bigger than on 10.1
imageviewer is a lot bigger
shell is a couple of bytes bigger
rockrunner is a lot bigger still than on 10.1
paint is bigger than on 10.1
cx16/testmonogfx is broken
cx16/amiga is broken
assembler is broken
imageviewer is broken
paint flood fill is broken
rockrunner load caveset list is broken
medemo and dsdemo are broken
add tests for comparison that do an assignment rather than an if
assign to variable, and barray[indexvar], test if they're both correct
(bb = value > -100 --> contains a beq +++ that shouldn't be there??)
@ -72,7 +68,7 @@ ok ok efficient code for assignment float comparisons against a value
ok ok efficient code for if_cc conditional expressions
ok ok while boolean should produce identical code as while integer!=0 and code should be efficient
ok ok while not boolvar -> can we get rid of the cmp? (6502 only?)
ok FAIL testmonogfx works
ok ok testmonogfx works
ok . check program sizes vs. master branch
===== ====== =======

File diff suppressed because it is too large Load Diff