new ifelse codegen

This commit is contained in:
Irmen de Jong 2024-02-15 23:41:35 +01:00
parent 7d8cdcbfea
commit 577333f2c4
7 changed files with 408 additions and 175 deletions

View File

@ -235,7 +235,7 @@ class AsmGen6502Internal (
private val anyExprGen = AnyExprAsmGen(this) private val anyExprGen = AnyExprAsmGen(this)
private val assignmentAsmGen = AssignmentAsmGen(program, this, anyExprGen, allocator) private val assignmentAsmGen = AssignmentAsmGen(program, this, anyExprGen, allocator)
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen) private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
private val ifElseAsmgen = IfElseAsmGen(program, this) private val ifElseAsmgen = IfElseAsmGen(program, this, assignmentAsmGen)
fun compileToAssembly(): IAssemblyProgram? { fun compileToAssembly(): IAssemblyProgram? {

View File

@ -2,137 +2,180 @@ package prog8.codegen.cpu6502
import prog8.code.ast.* import prog8.code.ast.*
import prog8.code.core.* import prog8.code.core.*
import prog8.codegen.cpu6502.assignment.AssignmentAsmGen
internal class IfElseAsmGen(private val program: PtProgram, private val asmgen: AsmGen6502Internal) { internal class IfElseAsmGen(private val program: PtProgram,
private val asmgen: AsmGen6502Internal,
private val assignmentAsmGen: AssignmentAsmGen) {
fun translate(stmt: PtIfElse) { fun translate(stmt: PtIfElse) {
require(stmt.condition.type== DataType.BOOL) require(stmt.condition.type== DataType.BOOL)
if(stmt.ifScope.children.singleOrNull() is PtJump) { val jumpAfterIf = stmt.ifScope.children.singleOrNull() as? PtJump
translateIfWithOnlyJump(stmt)
return
}
val afterIfLabel = asmgen.makeLabel("afterif") if(stmt.condition is PtIdentifier ||
stmt.condition is PtFunctionCall ||
fun translateIfElseBodies(elseBranchInstr: String) { stmt.condition is PtBuiltinFunctionCall ||
if(stmt.hasElse()) { stmt.condition is PtContainmentCheck)
// if and else blocks return fallbackTranslate(stmt, false) // the fallback code for these is optimal, so no warning.
val elseLabel = asmgen.makeLabel("else")
asmgen.out(" $elseBranchInstr $elseLabel")
asmgen.translate(stmt.ifScope)
asmgen.jmp(afterIfLabel, false)
asmgen.out(elseLabel)
asmgen.translate(stmt.elseScope)
} else {
// no else block
asmgen.out(" $elseBranchInstr $afterIfLabel")
asmgen.translate(stmt.ifScope)
}
asmgen.out(afterIfLabel)
}
val compareCond = stmt.condition as? PtBinaryExpression val compareCond = stmt.condition as? PtBinaryExpression
if(compareCond!=null) { if(compareCond!=null) {
if((compareCond.right as? PtNumber)?.number==0.0 && compareCond.operator in arrayOf("==", "!=")) { return when(compareCond.right.type) {
if (compareCond.right.type in ByteDatatypesWithBoolean) { in ByteDatatypesWithBoolean -> translateIfByte(stmt, compareCond, jumpAfterIf)
// equality comparison with 0 TODO temporary optimization in WordDatatypes -> translateIfWord(stmt, compareCond, jumpAfterIf)
val elseBranch = if (compareCond.operator == "==") "bne" else "beq" DataType.FLOAT -> translateIfFloat(stmt, compareCond, jumpAfterIf)
asmgen.assignExpressionToRegister(compareCond.left, RegisterOrPair.A, false) else -> throw AssemblyError("weird dt")
translateIfElseBodies(elseBranch)
return
}
} else {
// TODO optimize if X comparison Y general case (also with 0 as a special case)
} }
} }
val prefixCond = stmt.condition as? PtPrefix val prefixCond = stmt.condition as? PtPrefix
if(prefixCond?.operator=="not") { if(prefixCond?.operator=="not") {
asmgen.assignExpressionToRegister(prefixCond.value, RegisterOrPair.A, false) assignConditionValueToRegisterAndTest(prefixCond.value)
translateIfElseBodies("bne") // inverted condition, just swap the branches return if(jumpAfterIf!=null)
} else { translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
asmgen.assignExpressionToRegister(stmt.condition, RegisterOrPair.A, false) else
translateIfElseBodies("beq") translateIfElseBodies("bne", stmt)
}
// TODO more optimized ifs
println("(if with special condition... ${stmt.condition})")
fallbackTranslate(stmt)
}
private fun assignConditionValueToRegisterAndTest(condition: PtExpression) {
asmgen.assignExpressionToRegister(condition, RegisterOrPair.A, false)
when(condition) {
is PtNumber,
is PtBool,
is PtIdentifier,
is PtMachineRegister,
is PtArrayIndexer,
is PtPrefix,
is PtBinaryExpression -> { /* no cmp necessary the lda has been done just prior */ }
else -> asmgen.out(" cmp #0")
} }
} }
private fun translateIfWithOnlyJump(stmt: PtIfElse) { private fun fallbackTranslate(stmt: PtIfElse, warning: Boolean=true) {
val jump = stmt.ifScope.children.single() as PtJump if(warning) println("WARN: FALLBACK IF: ${stmt.position}") // TODO no more of these
val compareCond = stmt.condition as? PtBinaryExpression val jumpAfterIf = stmt.ifScope.children.singleOrNull() as? PtJump
assignConditionValueToRegisterAndTest(stmt.condition)
if(jumpAfterIf!=null)
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("beq", stmt)
}
fun doJumpAndElse(branchInstr: String, falseBranch: String, jump: PtJump) { private fun translateIfElseBodies(elseBranchInstr: String, stmt: PtIfElse) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump) // comparison value is already in A
if(indirect) { val afterIfLabel = asmgen.makeLabel("afterif")
asmgen.out(""" if(stmt.hasElse()) {
// if and else blocks
val elseLabel = asmgen.makeLabel("else")
asmgen.out(" $elseBranchInstr $elseLabel")
asmgen.translate(stmt.ifScope)
asmgen.jmp(afterIfLabel, false)
asmgen.out(elseLabel)
asmgen.translate(stmt.elseScope)
} else {
// no else block
asmgen.out(" $elseBranchInstr $afterIfLabel")
asmgen.translate(stmt.ifScope)
}
asmgen.out(afterIfLabel)
}
private fun translateJumpElseBodies(branchInstr: String, falseBranch: String, jump: PtJump, elseBlock: PtNodeGroup) {
// comparison value is already in A
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
asmgen.out("""
$falseBranch + $falseBranch +
jmp ($asmLabel) jmp ($asmLabel)
+ """) +""")
} else { } else {
asmgen.out(" $branchInstr $asmLabel") asmgen.out(" $branchInstr $asmLabel")
}
if(stmt.hasElse())
asmgen.translate(stmt.elseScope)
} }
asmgen.translate(elseBlock)
if(compareCond!=null) {
if (compareCond.operator in arrayOf("==", "!=")) {
val compareNumber = compareCond.right as? PtNumber
when (compareCond.right.type) {
in ByteDatatypesWithBoolean -> {
asmgen.assignExpressionToRegister(compareCond.left, RegisterOrPair.A, false)
if(compareNumber==null || compareNumber.number!=0.0)
compareRegisterAwithByte(compareCond.right)
if(compareCond.operator=="==") {
// if X==something goto blah
doJumpAndElse("beq", "bne", jump)
return
} else {
// if X!=something goto blah
doJumpAndElse("bne", "brq", jump)
return
}
}
in WordDatatypes -> {
asmgen.assignExpressionToRegister(stmt.condition, RegisterOrPair.A, false)
doJumpAndElse("bne", "beq", jump)
return
// TODO: optimize word
// assignExpressionToRegister(compareCond.left, RegisterOrPair.AY, false)
// compareRegisterAYwithWord(compareCond.operator, compareCond.right, jump)
// if(compareCond.operator=="==") {
// // if X==something goto blah
// doJumpAndElse("beq", "bne", jump)
// return
// } else {
// // if X!=something goto blah
// doJumpAndElse("bne", "brq", jump)
// return
// }
}
DataType.FLOAT -> {
TODO()
}
else -> {
throw AssemblyError("weird dt")
}
}
}
}
asmgen.assignExpressionToRegister(stmt.condition, RegisterOrPair.A, false)
doJumpAndElse("bne", "beq", jump)
} }
private fun compareRegisterAwithByte(value: PtExpression) { private fun translateIfByte(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
fun cmpViaScratch() { val signed = condition.left.type in SignedDatatypes
if(!value.isSimple()) asmgen.out(" pha") val constValue = condition.right.asConstInteger()
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_REG", value.type) if(constValue==0) {
if(!value.isSimple()) asmgen.out(" pla") if(condition.operator=="==") {
asmgen.out(" cmp P8ZP_SCRATCH_REG") // 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)
}
} }
// TODO how is if X==pointeervar[99] translated? can use cmp indirect indexed when (condition.operator) {
"==" -> {
// if X==value
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
cmpAwithByteValue(condition.right)
return if(jumpAfterIf!=null)
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("bne", stmt)
}
"!=" -> {
// if X!=value
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
cmpAwithByteValue(condition.right)
return if(jumpAfterIf!=null)
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("beq", stmt)
}
"<" -> {
// TODO()
println("byte if <")
fallbackTranslate(stmt)
}
"<=" -> {
// TODO()
println("byte if <=")
fallbackTranslate(stmt)
}
">" -> {
// TODO()
println("byte if >")
fallbackTranslate(stmt)
}
">=" -> {
// TODO()
println("byte if >=")
fallbackTranslate(stmt)
}
else -> fallbackTranslate(stmt, false)
}
}
private fun cmpAwithByteValue(value: PtExpression) {
fun cmpViaScratch() {
if(assignmentAsmGen.directIntoY(value)) {
asmgen.assignExpressionToRegister(value, RegisterOrPair.Y, false)
asmgen.out(" sty P8ZP_SCRATCH_REG")
} else {
asmgen.out(" pha")
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_REG", value.type)
asmgen.out(" pla")
}
asmgen.out(" cmp P8ZP_SCRATCH_REG")
}
when(value) { when(value) {
is PtArrayIndexer -> { is PtArrayIndexer -> {
@ -140,8 +183,7 @@ internal class IfElseAsmGen(private val program: PtProgram, private val asmgen:
if(constIndex!=null) { if(constIndex!=null) {
val offset = constIndex * program.memsizer.memorySize(value.type) val offset = constIndex * program.memsizer.memorySize(value.type)
if(offset<256) { if(offset<256) {
asmgen.out(" ldy #$offset | cmp ${asmgen.asmVariableName(value.variable.name)},y") return asmgen.out(" ldy #$offset | cmp ${asmgen.asmVariableName(value.variable.name)},y")
return
} }
} }
cmpViaScratch() cmpViaScratch()
@ -167,4 +209,120 @@ internal class IfElseAsmGen(private val program: PtProgram, private val asmgen:
} }
} }
private fun translateIfWord(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
val signed = condition.left.type in SignedDatatypes
val constValue = condition.right.asConstInteger()
if(constValue==0) {
if(condition.operator=="==") {
// if X==0
// TODO even more optimized code by comparing lsb and msb separately
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.AY, signed)
asmgen.out(" sty P8ZP_SCRATCH_REG | ora P8ZP_SCRATCH_REG")
return if(jumpAfterIf!=null)
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("bne", stmt)
} else if(condition.operator=="!=") {
// if X!=0
// TODO even more optimized code by comparing lsb and msb separately
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.AY, signed)
asmgen.out(" sty P8ZP_SCRATCH_REG | ora P8ZP_SCRATCH_REG")
return if(jumpAfterIf!=null)
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("beq", stmt)
}
}
when(condition.operator) {
"==" -> {
// TODO
println("word if ==")
fallbackTranslate(stmt)
}
"!=" -> {
// TODO
println("word if !=")
fallbackTranslate(stmt)
}
"<" -> {
// TODO()
println("word if <")
fallbackTranslate(stmt)
}
"<=" -> {
// TODO()
println("word if <=")
fallbackTranslate(stmt)
}
">" -> {
// TODO()
println("word if >")
fallbackTranslate(stmt)
}
">=" -> {
// TODO()
println("word if >=")
fallbackTranslate(stmt)
}
else -> fallbackTranslate(stmt, false)
}
}
private fun translateIfFloat(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
val constValue = (condition.right as? PtNumber)?.number
if(constValue==0.0) {
if (condition.operator == "==") {
// if FL==0.0
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.FAC1, true)
asmgen.out(" jsr floats.SIGN | cmp #0")
return if (jumpAfterIf != null)
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("bne", stmt)
} else if(condition.operator=="!=") {
// if FL!=0.0
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.FAC1, true)
asmgen.out(" jsr floats.SIGN | cmp #0")
return if (jumpAfterIf != null)
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
else
translateIfElseBodies("beq", stmt)
}
}
when(condition.operator) {
"==" -> {
// TODO
println("float if ==")
fallbackTranslate(stmt)
}
"!=" -> {
// TODO
println("float if !=")
fallbackTranslate(stmt)
}
"<" -> {
// TODO()
println("float if <")
fallbackTranslate(stmt)
}
"<=" -> {
// TODO()
println("float if <=")
fallbackTranslate(stmt)
}
">" -> {
// TODO()
println("float if >")
fallbackTranslate(stmt)
}
">=" -> {
// TODO()
println("float if >=")
fallbackTranslate(stmt)
}
else -> fallbackTranslate(stmt, false)
}
}
} }

View File

@ -568,7 +568,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
return true return true
} }
private fun directIntoY(expr: PtExpression): Boolean { internal fun directIntoY(expr: PtExpression): Boolean {
return when(expr) { return when(expr) {
is PtIdentifier -> true is PtIdentifier -> true
is PtMachineRegister -> true is PtMachineRegister -> true

View File

@ -556,7 +556,7 @@ asmsub mouse_config2(byte shape @A) clobbers (A, X, Y) {
asmsub mouse_pos() clobbers(X) -> ubyte @A { asmsub mouse_pos() clobbers(X) -> ubyte @A {
; -- short wrapper around mouse_get() kernal routine: ; -- short wrapper around mouse_get() kernal routine:
; -- gets the position of the mouse cursor in cx16.r0 and cx16.r1 (x/y coordinate), returns mouse button status. ; -- gets the position of the mouse cursor in cx16.r0 and cx16.r1 (x/y coordinate), returns mouse button status in A.
%asm {{ %asm {{
ldx #cx16.r0 ldx #cx16.r0
jmp cx16.mouse_get jmp cx16.mouse_get

View File

@ -5,11 +5,11 @@ package prog8.buildversion
*/ */
const val MAVEN_GROUP = "prog8" const val MAVEN_GROUP = "prog8"
const val MAVEN_NAME = "compiler" const val MAVEN_NAME = "compiler"
const val VERSION = "10.2-SNAPSHOT" const val VERSION = "10.2-BOOLEANS"
const val GIT_REVISION = 4459 const val GIT_REVISION = 4485
const val GIT_SHA = "a1f197d2ff2e23c84cac26efbda75ef3efb1f0aa" const val GIT_SHA = "eddf97191959f87119c746d8833b71a247db661d"
const val GIT_DATE = "2024-02-10T00:33:26Z" const val GIT_DATE = "2024-02-15T23:58:56Z"
const val GIT_BRANCH = "master" const val GIT_BRANCH = "booleans"
const val BUILD_DATE = "2024-02-10T00:33:30Z" const val BUILD_DATE = "2024-02-16T00:19:00Z"
const val BUILD_UNIX_TIME = 1707525210318L const val BUILD_UNIX_TIME = 1708042740125L
const val DIRTY = 0 const val DIRTY = 1

View File

@ -55,7 +55,6 @@ boolean trick to go from a compare >= value, to a bool
and #1 and #1
Chess: cannot click mouse to start. nothing happens.
Already broken in 10.0: textelite on c64, info on diso -> jams the cpu after printing Already broken in 10.0: textelite on c64, info on diso -> jams the cpu after printing
IR: add TEST instruction to test memory content and set N/Z flags, without affecting any register. IR: add TEST instruction to test memory content and set N/Z flags, without affecting any register.

View File

@ -8,6 +8,15 @@ main {
bool @shared staticbool2 bool @shared staticbool2
sub start() { sub start() {
cx16.mouse_config2(1) ; enable mouse cursor (sprite 0)
while cx16.mouse_pos()==0 {
cx16.r0L++
}
while cx16.mouse_pos()!=0 {
cx16.r0L++
}
; boolean_const_and_var(true) ; boolean_const_and_var(true)
; staticbool1 = boolean_arrays_and_return() ; staticbool1 = boolean_arrays_and_return()
; txt.print_ub(staticbool1 as ubyte) ; txt.print_ub(staticbool1 as ubyte)
@ -25,9 +34,11 @@ main {
; while_bool_efficient() ; while_bool_efficient()
; efficient_compare_0() ; efficient_compare_0()
; efficient_compare_99() ; efficient_compare_99()
; efficient_compare_var()
; efficient_assign_cmp_0() ; efficient_assign_cmp_0()
; efficient_assign_cmp_99() ; efficient_assign_cmp_99()
if_gotos() ; efficient_assign_cmp_var()
; if_gotos()
; if_code() ; if_code()
;;sys.exit(1) ;;sys.exit(1)
; while_equiv() ; while_equiv()
@ -52,16 +63,16 @@ main {
sub while_bool_efficient() { sub while_bool_efficient() {
while staticbool1 { while staticbool1 {
cx16.r0++ cx16.r0L++
} }
while not staticbool1 { while not staticbool1 {
cx16.r0++ cx16.r0L++
} }
while cx16.r0L==0 { while cx16.r0L==0 {
cx16.r0++ cx16.r0L++
} }
while cx16.r0L!=0 { while cx16.r0L!=0 {
cx16.r0++ cx16.r0L++
} }
} }
@ -95,29 +106,49 @@ main {
bb2 = fl!=99.0 bb2 = fl!=99.0
} }
sub efficient_assign_cmp_var() {
ubyte @shared ub
uword @shared uw
float @shared fl
bool @shared bb1, bb2
float @shared fval
bb1 = ub==cx16.r0L
bb2 = ub!=cx16.r0L
bb1 = uw==cx16.r0
bb2 = uw!=cx16.r0
bb1 = fl==0.0
bb2 = fl!=0.0
bb1 = fl==fval
bb2 = fl!=fval
bb1 = bb2==uw[cx16.r0L]
bb2 = bb1!=uw[cx16.r1L]
}
sub efficient_compare_0() { sub efficient_compare_0() {
ubyte @shared ub ubyte @shared ub
uword @shared uw uword @shared uw
float @shared fl float @shared fl
if ub==0 if ub==0
cx16.r0++ cx16.r0L++
if uw==0 if uw==0
cx16.r0++ cx16.r0L++
if fl==0 if fl==0
cx16.r0++ cx16.r0L++
if ub!=0 if ub!=0
cx16.r0++ cx16.r0L++
else else
cx16.r1++ cx16.r1L++
if uw!=0 if uw!=0
cx16.r0++ cx16.r0L++
else else
cx16.r1++ cx16.r1L++
if fl!=0 if fl!=0
cx16.r0++ cx16.r0L++
else else
cx16.r1++ cx16.r1L++
} }
sub efficient_compare_99() { sub efficient_compare_99() {
@ -126,23 +157,63 @@ main {
float @shared fl float @shared fl
if ub==99 if ub==99
cx16.r0++ cx16.r0L++
if uw==99 if uw==99
cx16.r0++ cx16.r0L++
if fl==99.99 if fl==99.99
cx16.r0++ cx16.r0L++
if ub!=99 if ub!=99
cx16.r0++ cx16.r0L++
else else
cx16.r1++ cx16.r1L++
if uw!=99 if uw!=99
cx16.r0++ cx16.r0L++
else else
cx16.r1++ cx16.r1L++
if fl!=99.99 if fl!=99.99
cx16.r0++ cx16.r0L++
else else
cx16.r1++ cx16.r1L++
}
sub efficient_compare_var() {
ubyte @shared ub
uword @shared uw
float @shared fl
float @shared fval
if ub==cx16.r0L
cx16.r0L++
if uw==cx16.r0
cx16.r0L++
if fl==fval
cx16.r0L++
if fl==0.0
cx16.r0L++
if ub!=cx16.r0L
cx16.r0L++
else
cx16.r1L++
if uw!=cx16.r0
cx16.r0L++
else
cx16.r1L++
if fl!=fval
cx16.r0L++
else
cx16.r1L++
if fl!=0.0
cx16.r0L++
else
cx16.r1L++
if ub==uw[cx16.r0L]
cx16.r0L++
if ub!=uw[cx16.r0L]
cx16.r0L++
if staticbool2 or staticbool1
cx16.r0L++
} }
sub logical_operand_swap() { sub logical_operand_swap() {
@ -264,29 +335,29 @@ main {
; ;
; sub while_until_int_errors() { ; sub while_until_int_errors() {
;; while staticbool1==42 { ;; while staticbool1==42 {
;; cx16.r0++ ;; cx16.r0L++
;; } ;; }
;; ;;
;; do { ;; do {
;; cx16.r0++ ;; cx16.r0L++
;; } until staticbool1==42 ;; } until staticbool1==42
; ;
; ubyte @shared ub1 ; ubyte @shared ub1
; ;
; while not ub1 { ; while not ub1 {
; cx16.r0++ ; cx16.r0L++
; } ; }
; ;
; while intfunc() { ; while intfunc() {
; cx16.r0++ ; cx16.r0L++
; } ; }
; ;
; while not intfunc() { ; while not intfunc() {
; cx16.r0++ ; cx16.r0L++
; } ; }
; ;
;; while not cx16.mouse_pos() { ;; while not cx16.mouse_pos() {
;; cx16.r0++ ;; cx16.r0L++
;; } ;; }
; } ; }
@ -295,16 +366,16 @@ main {
bool @shared bb bool @shared bb
while bb { while bb {
cx16.r0++ cx16.r0L++
} }
while ub!=0 { while ub!=0 {
cx16.r0++ cx16.r0L++
} }
while not bb { while not bb {
cx16.r0++ cx16.r0L++
} }
while ub==0 { while ub==0 {
cx16.r0++ cx16.r0L++
} }
} }
@ -340,7 +411,7 @@ main {
sub bools_in_array_assigns_inplace() { sub bools_in_array_assigns_inplace() {
bool[] ba = [true, false, true] bool[] ba = [true, false, true]
cx16.r0++ cx16.r0L++
ba[1] = ba[1] xor staticbool2 ba[1] = ba[1] xor staticbool2
ba[2] = staticbool2 xor ba[2] ba[2] = staticbool2 xor ba[2]
ba[1] = ba[1] and staticbool2 ba[1] = ba[1] and staticbool2
@ -374,32 +445,37 @@ main {
if_cc if_cc
goto label goto label
else else
cx16.r0++ cx16.r0L++
if_cs if_cs
goto label goto label
else else
cx16.r0++ cx16.r0L++
if ub==0
goto label
if ub!=0
goto label
if not ub==99 if not ub==99
goto label goto label
if ub==0 if ub==0
goto label goto label
else
cx16.r0++
if ub!=0 if ub!=0
goto label goto label
else
cx16.r0++
if not ub==98 if not ub==98
goto label goto label
else else
cx16.r0++ cx16.r0L++
if ub==0
goto label
else
cx16.r0L++
if ub!=0
goto label
else
cx16.r0L++
if staticbool1
goto label
if not staticbool2
goto label
label: label:
} }
@ -407,28 +483,28 @@ main {
ubyte @shared ub ubyte @shared ub
bool @shared bb bool @shared bb
if ub==0 if ub==0
cx16.r0++ cx16.r0L++
if ub!=0 if ub!=0
cx16.r0++ cx16.r0L++
if bb if bb
cx16.r0++ cx16.r0L++
if not bb if not bb
cx16.r0++ cx16.r0L++
if ub==0 if ub==0
cx16.r0++ cx16.r0L++
else else
cx16.r0-- cx16.r0--
if ub!=0 if ub!=0
cx16.r0++ cx16.r0L++
else else
cx16.r0-- cx16.r0--
if bb if bb
cx16.r0++ cx16.r0L++
else else
cx16.r0-- cx16.r0--
if not bb if not bb
cx16.r0++ cx16.r0L++
else else
cx16.r0-- cx16.r0--
} }
@ -438,6 +514,6 @@ main {
} }
sub voidfuncub(ubyte arg) { sub voidfuncub(ubyte arg) {
cx16.r0++ cx16.r0L++
} }
} }