diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 5e3dd0031..c26142c9a 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -406,6 +406,7 @@ class AsmGen6502Internal ( internal val tempVarsCounters = mutableMapOf( + DataType.BOOL to 0, DataType.BYTE to 0, DataType.UBYTE to 0, DataType.WORD to 0, @@ -767,80 +768,23 @@ class AsmGen6502Internal ( } private fun translate(stmt: PtIfElse) { - val condition = stmt.condition as? PtBinaryExpression - if(condition!=null) { - requireComparisonExpression(condition) // IfStatement: condition must be of form 'x ' - if (stmt.elseScope.children.isEmpty()) { - val jump = stmt.ifScope.children.singleOrNull() - if (jump is PtJump) { - translateCompareAndJumpIfTrue(condition, jump) - } else { - val endLabel = makeLabel("if_end") - translateCompareOrJumpIfFalse(condition, endLabel) - translate(stmt.ifScope) - out(endLabel) - } - } else { - // both true and else parts - val elseLabel = makeLabel("if_else") - val endLabel = makeLabel("if_end") - translateCompareOrJumpIfFalse(condition, elseLabel) - translate(stmt.ifScope) - jmp(endLabel) - out(elseLabel) - translate(stmt.elseScope) - out(endLabel) - } + require(stmt.condition.type==DataType.BOOL) + assignExpressionToRegister(stmt.condition, RegisterOrPair.A, false) + val afterIfLabel = makeLabel("if") + if(stmt.children.size>1) { + // if and else blocks + val elseLabel = makeLabel("else") + out(" beq $elseLabel") + translate(stmt.ifScope) + jmp(afterIfLabel, false) + out(elseLabel) + translate(stmt.elseScope) } else { - // condition is a simple expression "if X" --> "if X!=0" - val zero = PtNumber(DataType.UBYTE,0.0, stmt.position) - val leftConst = stmt.condition as? PtNumber - if (stmt.elseScope.children.isEmpty()) { - val jump = stmt.ifScope.children.singleOrNull() - if (jump is PtJump) { - // jump somewhere if X!=0 - val label = when { - jump.identifier!=null -> asmSymbolName(jump.identifier!!) - jump.address!=null -> jump.address!!.toHex() - else -> throw AssemblyError("weird jump") - } - when(stmt.condition.type) { - in WordDatatypes -> translateWordEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, label) - in ByteDatatypesWithBoolean -> translateByteEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, label) - else -> throw AssemblyError("weird condition dt") - } - } else { - // skip the true block (=jump to end label) if X==0 - val endLabel = makeLabel("if_end") - when(stmt.condition.type) { - in WordDatatypes -> translateWordNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, endLabel) - in ByteDatatypesWithBoolean -> translateByteNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, endLabel) - else -> throw AssemblyError("weird condition dt") - } - translate(stmt.ifScope) - out(endLabel) - } - } else { - // both true and else parts - val elseLabel = makeLabel("if_else") - val endLabel = makeLabel("if_end") - when(stmt.condition.type) { - in WordDatatypes -> translateWordNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, elseLabel) - in ByteDatatypesWithBoolean -> translateByteNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, elseLabel) - else -> throw AssemblyError("weird condition dt") - } - translate(stmt.ifScope) - jmp(endLabel) - out(elseLabel) - translate(stmt.elseScope) - out(endLabel) - } + // no else block + out(" beq $afterIfLabel") + translate(stmt.ifScope) } - } - - private fun requireComparisonExpression(condition: PtExpression) { - if (!(condition is PtBinaryExpression && condition.operator in ComparisonOperators)) - throw AssemblyError("expected boolean comparison expression") + out(afterIfLabel) } private fun translate(stmt: PtRepeatLoop) { @@ -1340,996 +1284,6 @@ $repeatLabel""") return node.definingSub()?.parameters?.singleOrNull { it.name===name } } - private fun translateCompareAndJumpIfTrue(expr: PtBinaryExpression, jump: PtJump) { - if(expr.operator !in ComparisonOperators) - throw AssemblyError("must be comparison expression") - - // invert the comparison, so we can reuse the JumpIfFalse code generation routines - val invertedComparisonOperator = invertedComparisonOperator(expr.operator) - ?: throw AssemblyError("can't invert comparison ${expr.operator} $expr") - - val left = expr.left - val right = expr.right - val rightConstVal = right as? PtNumber - - val label = when { - jump.identifier!=null -> asmSymbolName(jump.identifier!!) - jump.address!=null -> jump.address!!.toHex() - else -> throw AssemblyError("weird jump") - } - if (rightConstVal!=null && rightConstVal.number == 0.0) { - testZeroOrJumpElsewhere(left, invertedComparisonOperator, label) - } - else { - val leftConstVal = left as? PtNumber - testNonzeroComparisonOrJumpElsewhere(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal) - } - } - - private fun translateCompareOrJumpIfFalse(expr: PtBinaryExpression, jumpIfFalseLabel: String) { - val left = expr.left - val right = expr.right - val operator = expr.operator - val leftConstVal = left as? PtNumber - val rightConstVal = right as? PtNumber - - if (rightConstVal!=null && rightConstVal.number == 0.0) - testZeroOrJumpElsewhere(left, operator, jumpIfFalseLabel) - else - testNonzeroComparisonOrJumpElsewhere(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal) - } - - private fun testZeroOrJumpElsewhere( - left: PtExpression, - operator: String, - jumpIfFalseLabel: String - ) { - val dt = left.type - if(dt in IntegerDatatypesWithBoolean && left is PtIdentifier) - return testVariableZeroOrJumpElsewhere(left, dt, operator, jumpIfFalseLabel) - - when(dt) { - DataType.BOOL, DataType.UBYTE, DataType.UWORD -> { - if(operator=="<") { - out(" jmp $jumpIfFalseLabel") - return - } else if(operator==">=") { - return - } - if(dt==DataType.UBYTE || dt==DataType.BOOL) { - assignExpressionToRegister(left, RegisterOrPair.A, false) - if (left is PtFunctionCall && !left.isSimple()) - out(" cmp #0") - } else { - assignExpressionToRegister(left, RegisterOrPair.AY, false) - out(" sty P8ZP_SCRATCH_B1 | ora P8ZP_SCRATCH_B1") - } - when (operator) { - "==" -> out(" bne $jumpIfFalseLabel") - "!=" -> out(" beq $jumpIfFalseLabel") - ">" -> out(" beq $jumpIfFalseLabel") - "<=" -> out(" bne $jumpIfFalseLabel") - else -> throw AssemblyError("invalid comparison operator $operator") - } - } - DataType.BYTE -> { - assignExpressionToRegister(left, RegisterOrPair.A, true) - if (left is PtFunctionCall && !left.isSimple()) - out(" cmp #0") - when (operator) { - "==" -> out(" bne $jumpIfFalseLabel") - "!=" -> out(" beq $jumpIfFalseLabel") - ">" -> out(" beq $jumpIfFalseLabel | bmi $jumpIfFalseLabel") - "<" -> out(" bpl $jumpIfFalseLabel") - ">=" -> out(" bmi $jumpIfFalseLabel") - "<=" -> out(""" - beq + - bpl $jumpIfFalseLabel - + """) - else -> throw AssemblyError("invalid comparison operator $operator") - } - } - DataType.WORD -> { - assignExpressionToRegister(left, RegisterOrPair.AY, true) - when (operator) { - "==" -> out(" bne $jumpIfFalseLabel | cpy #0 | bne $jumpIfFalseLabel") - "!=" -> out(" sty P8ZP_SCRATCH_B1 | ora P8ZP_SCRATCH_B1 | beq $jumpIfFalseLabel") - ">" -> out(""" - cpy #0 - bmi $jumpIfFalseLabel - bne + - cmp #0 - beq $jumpIfFalseLabel - + """) - "<" -> out(" cpy #0 | bpl $jumpIfFalseLabel") - ">=" -> out(" cpy #0 | bmi $jumpIfFalseLabel") - "<=" -> out(""" - cpy #0 - bmi + - bne $jumpIfFalseLabel - cmp #0 - bne $jumpIfFalseLabel - + """) - else -> throw AssemblyError("invalid comparison operator $operator") - } - } - DataType.FLOAT -> { - assignExpressionToRegister(left, RegisterOrPair.FAC1) - out(" jsr floats.SIGN") // SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive - when (operator) { - "==" -> out(" bne $jumpIfFalseLabel") - "!=" -> out(" beq $jumpIfFalseLabel") - ">" -> out(" bmi $jumpIfFalseLabel | beq $jumpIfFalseLabel") - "<" -> out(" bpl $jumpIfFalseLabel") - ">=" -> out(" bmi $jumpIfFalseLabel") - "<=" -> out(" cmp #1 | beq $jumpIfFalseLabel") - else -> throw AssemblyError("invalid comparison operator $operator") - } - } - else -> { - throw AssemblyError("invalid dt") - } - } - } - - private fun testVariableZeroOrJumpElsewhere(variable: PtIdentifier, dt: DataType, operator: String, jumpIfFalseLabel: String) { - // optimized code if the expression is just an identifier (variable) - val varname = asmVariableName(variable) - when(dt) { - DataType.UBYTE, DataType.BOOL -> when(operator) { - "==" -> out(" lda $varname | bne $jumpIfFalseLabel") - "!=" -> out(" lda $varname | beq $jumpIfFalseLabel") - ">" -> out(" lda $varname | beq $jumpIfFalseLabel") - "<" -> out(" bra $jumpIfFalseLabel") - ">=" -> {} - "<=" -> out(" lda $varname | bne $jumpIfFalseLabel") - else -> throw AssemblyError("invalid operator") - } - DataType.BYTE -> when(operator) { - "==" -> out(" lda $varname | bne $jumpIfFalseLabel") - "!=" -> out(" lda $varname | beq $jumpIfFalseLabel") - ">" -> out(" lda $varname | beq $jumpIfFalseLabel | bmi $jumpIfFalseLabel") - "<" -> out(" lda $varname | bpl $jumpIfFalseLabel") - ">=" -> out(" lda $varname | bmi $jumpIfFalseLabel") - "<=" -> out(""" - lda $varname - beq + - bpl $jumpIfFalseLabel - + """) - else -> throw AssemblyError("invalid operator") - } - DataType.UWORD -> when(operator) { - "==" -> out(" lda $varname | ora $varname+1 | bne $jumpIfFalseLabel") - "!=" -> out(" lda $varname | ora $varname+1 | beq $jumpIfFalseLabel") - ">" -> out(" lda $varname | ora $varname+1 | beq $jumpIfFalseLabel") - "<" -> out(" bra $jumpIfFalseLabel") - ">=" -> {} - "<=" -> out(" lda $varname | ora $varname+1 | bne $jumpIfFalseLabel") - else -> throw AssemblyError("invalid operator") - } - DataType.WORD -> when (operator) { - "==" -> out(" lda $varname | bne $jumpIfFalseLabel | lda $varname+1 | bne $jumpIfFalseLabel") - "!=" -> out(" lda $varname | ora $varname+1 | beq $jumpIfFalseLabel") - ">" -> out(""" - lda $varname+1 - bmi $jumpIfFalseLabel - bne + - lda $varname - beq $jumpIfFalseLabel - + """) - "<" -> out(" lda $varname+1 | bpl $jumpIfFalseLabel") - ">=" -> out(" lda $varname+1 | bmi $jumpIfFalseLabel") - "<=" -> out(""" - lda $varname+1 - bmi + - bne $jumpIfFalseLabel - lda $varname - bne $jumpIfFalseLabel - + """) - else -> throw AssemblyError("invalid comparison operator $operator") - } - else -> throw AssemblyError("invalid dt") - } - } - - internal fun testNonzeroComparisonOrJumpElsewhere( - left: PtExpression, - operator: String, - right: PtExpression, - jumpIfFalseLabel: String, - leftConstVal: PtNumber?, - rightConstVal: PtNumber? - ) { - val dt = left.type - - when (operator) { - "==" -> { - when (dt) { - in ByteDatatypesWithBoolean -> translateByteEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - in WordDatatypes -> translateWordEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.FLOAT -> translateFloatEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.STR -> translateStringEqualsOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel) - else -> throw AssemblyError("weird operand datatype") - } - } - "!=" -> { - when (dt) { - in ByteDatatypesWithBoolean -> translateByteNotEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - in WordDatatypes -> translateWordNotEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.FLOAT -> translateFloatNotEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.STR -> translateStringNotEqualsOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel) - else -> throw AssemblyError("weird operand datatype") - } - } - "<" -> { - when(dt) { - DataType.UBYTE -> translateUbyteLessOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.BYTE -> translateByteLessOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.UWORD -> translateUwordLessOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.WORD -> translateWordLessOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.FLOAT -> translateFloatLessOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.STR -> translateStringLessOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel) - else -> throw AssemblyError("weird operand datatype") - } - } - "<=" -> { - when(dt) { - DataType.UBYTE -> translateUbyteLessOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.BYTE -> translateByteLessOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.UWORD -> translateUwordLessOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.WORD -> translateWordLessOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.FLOAT -> translateFloatLessOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.STR -> translateStringLessOrEqualOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel) - else -> throw AssemblyError("weird operand datatype") - } - } - ">" -> { - when(dt) { - DataType.UBYTE -> translateUbyteGreaterOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.BYTE -> translateByteGreaterOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.UWORD -> translateUwordGreaterOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.WORD -> translateWordGreaterOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.FLOAT -> translateFloatGreaterOrJumpElsewhere(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.STR -> translateStringGreaterOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel) - else -> throw AssemblyError("weird operand datatype") - } - } - ">=" -> { - when(dt) { - DataType.UBYTE -> translateUbyteGreaterOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.BYTE -> translateByteGreaterOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.UWORD -> translateUwordGreaterOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.WORD -> translateWordGreaterOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.FLOAT -> translateFloatGreaterOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) - DataType.STR -> translateStringGreaterOrEqualOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel) - else -> throw AssemblyError("weird operand datatype") - } - } - } - } - - private fun translateFloatLessOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - if(leftConstVal!=null && rightConstVal!=null) { - throw AssemblyError("const-compare should have been optimized away") - } - else if(leftConstVal!=null && right is PtIdentifier) { - throw AssemblyError("const-compare should have been optimized to have const as right operand") - } - else if(left is PtIdentifier && rightConstVal!=null) { - val leftName = asmVariableName(left) - val rightName = allocator.getFloatAsmConst(rightConstVal.number) - out(""" - lda #<$rightName - ldy #>$rightName - sta P8ZP_SCRATCH_W2 - sty P8ZP_SCRATCH_W2+1 - lda #<$leftName - ldy #>$leftName - jsr floats.vars_less_f - beq $jumpIfFalseLabel""") - } - else if(left is PtIdentifier && right is PtIdentifier) { - val leftName = asmVariableName(left) - val rightName = asmVariableName(right) - out(""" - lda #<$rightName - ldy #>$rightName - sta P8ZP_SCRATCH_W2 - sty P8ZP_SCRATCH_W2+1 - lda #<$leftName - ldy #>$leftName - jsr floats.vars_less_f - beq $jumpIfFalseLabel""") - } else { - val subroutine = left.definingSub()!! - subroutineExtra(subroutine).usedFloatEvalResultVar1 = true - assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT) - assignExpressionToRegister(left, RegisterOrPair.FAC1) - out(""" - lda #<$subroutineFloatEvalResultVar1 - ldy #>$subroutineFloatEvalResultVar1 - jsr floats.var_fac1_less_f - beq $jumpIfFalseLabel""") - } - } - - private fun translateFloatLessOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - if(leftConstVal!=null && rightConstVal!=null) { - throw AssemblyError("const-compare should have been optimized away") - } - else if(leftConstVal!=null && right is PtIdentifier) { - throw AssemblyError("const-compare should have been optimized to have const as right operand") - } - else if(left is PtIdentifier && rightConstVal!=null) { - val leftName = asmVariableName(left) - val rightName = allocator.getFloatAsmConst(rightConstVal.number) - out(""" - lda #<$rightName - ldy #>$rightName - sta P8ZP_SCRATCH_W2 - sty P8ZP_SCRATCH_W2+1 - lda #<$leftName - ldy #>$leftName - jsr floats.vars_lesseq_f - beq $jumpIfFalseLabel""") - } - else if(left is PtIdentifier && right is PtIdentifier) { - val leftName = asmVariableName(left) - val rightName = asmVariableName(right) - out(""" - lda #<$rightName - ldy #>$rightName - sta P8ZP_SCRATCH_W2 - sty P8ZP_SCRATCH_W2+1 - lda #<$leftName - ldy #>$leftName - jsr floats.vars_lesseq_f - beq $jumpIfFalseLabel""") - } else { - val subroutine = left.definingSub()!! - subroutineExtra(subroutine).usedFloatEvalResultVar1 = true - assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT) - assignExpressionToRegister(left, RegisterOrPair.FAC1) - out(""" - lda #<$subroutineFloatEvalResultVar1 - ldy #>$subroutineFloatEvalResultVar1 - jsr floats.var_fac1_lesseq_f - beq $jumpIfFalseLabel""") - } - } - - private fun translateFloatGreaterOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - if(leftConstVal!=null && rightConstVal!=null) { - throw AssemblyError("const-compare should have been optimized away") - } - else if(left is PtIdentifier && rightConstVal!=null) { - val leftName = asmVariableName(left) - val rightName = allocator.getFloatAsmConst(rightConstVal.number) - out(""" - lda #<$leftName - ldy #>$leftName - sta P8ZP_SCRATCH_W2 - sty P8ZP_SCRATCH_W2+1 - lda #<$rightName - ldy #>$rightName - jsr floats.vars_less_f - beq $jumpIfFalseLabel""") - } - else if(leftConstVal!=null && right is PtIdentifier) { - throw AssemblyError("const-compare should have been optimized to have const as right operand") - } - else if(left is PtIdentifier && right is PtIdentifier) { - val leftName = asmVariableName(left) - val rightName = asmVariableName(right) - out(""" - lda #<$leftName - ldy #>$leftName - sta P8ZP_SCRATCH_W2 - sty P8ZP_SCRATCH_W2+1 - lda #<$rightName - ldy #>$rightName - jsr floats.vars_less_f - beq $jumpIfFalseLabel""") - } else { - val subroutine = left.definingSub()!! - subroutineExtra(subroutine).usedFloatEvalResultVar1 = true - assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT) - assignExpressionToRegister(left, RegisterOrPair.FAC1) - out(""" - lda #<$subroutineFloatEvalResultVar1 - ldy #>$subroutineFloatEvalResultVar1 - jsr floats.var_fac1_greater_f - beq $jumpIfFalseLabel""") - } - } - - private fun translateFloatGreaterOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - if(leftConstVal!=null && rightConstVal!=null) { - throw AssemblyError("const-compare should have been optimized away") - } - else if(left is PtIdentifier && rightConstVal!=null) { - val leftName = asmVariableName(left) - val rightName = allocator.getFloatAsmConst(rightConstVal.number) - out(""" - lda #<$leftName - ldy #>$leftName - sta P8ZP_SCRATCH_W2 - sty P8ZP_SCRATCH_W2+1 - lda #<$rightName - ldy #>$rightName - jsr floats.vars_lesseq_f - beq $jumpIfFalseLabel""") - } - else if(leftConstVal!=null && right is PtIdentifier) { - throw AssemblyError("const-compare should have been optimized to have const as right operand") - } - else if(left is PtIdentifier && right is PtIdentifier) { - val leftName = asmVariableName(left) - val rightName = asmVariableName(right) - out(""" - lda #<$leftName - ldy #>$leftName - sta P8ZP_SCRATCH_W2 - sty P8ZP_SCRATCH_W2+1 - lda #<$rightName - ldy #>$rightName - jsr floats.vars_lesseq_f - beq $jumpIfFalseLabel""") - } else { - val subroutine = left.definingSub()!! - subroutineExtra(subroutine).usedFloatEvalResultVar1 = true - assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT) - assignExpressionToRegister(left, RegisterOrPair.FAC1) - out(""" - lda #<$subroutineFloatEvalResultVar1 - ldy #>$subroutineFloatEvalResultVar1 - jsr floats.var_fac1_greatereq_f - beq $jumpIfFalseLabel""") - } - } - - private fun translateUbyteLessOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(cmpOperand: String) { - out(" cmp $cmpOperand | bcs $jumpIfFalseLabel") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal>=leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - return if(rightConstVal.number.toInt()!=0) { - assignExpressionToRegister(left, RegisterOrPair.A) - code("#${rightConstVal.number.toInt()}") - } - else - jmp(jumpIfFalseLabel) - } - else if (left is PtMemoryByte) { - return if(rightConstVal.number.toInt()!=0) { - translateDirectMemReadExpressionToRegA(left) - code("#${rightConstVal.number.toInt()}") - } - else - jmp(jumpIfFalseLabel) - } - } - } - - if(byteJumpForSimpleRightOperand(left, right, ::code)) - return - - assignByteOperandsToAAndVar(left, right, "P8ZP_SCRATCH_B1") - return code("P8ZP_SCRATCH_B1") - } - - private fun translateByteLessOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(sbcOperand: String) { - out(""" - sec - sbc $sbcOperand - bvc + - eor #$80 -+ bpl $jumpIfFalseLabel""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal>=leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - assignExpressionToRegister(left, RegisterOrPair.A) - return if(rightConstVal.number.toInt()!=0) - code("#${rightConstVal.number}") - else - out(" bpl $jumpIfFalseLabel") - } - } - } - - if(byteJumpForSimpleRightOperand(left, right, ::code)) - return - - assignByteOperandsToAAndVar(left, right, "P8ZP_SCRATCH_B1") - return code("P8ZP_SCRATCH_B1") - } - - private fun translateUwordLessOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(msbCpyOperand: String, lsbCmpOperand: String) { - out(""" - cpy $msbCpyOperand - bcc + - bne $jumpIfFalseLabel - cmp $lsbCmpOperand - bcs $jumpIfFalseLabel -+""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal>=leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - return if(rightConstVal.number.toInt()!=0) { - assignExpressionToRegister(left, RegisterOrPair.AY) - code("#>${rightConstVal.number.toInt()}", "#<${rightConstVal.number.toInt()}") - } - else - jmp(jumpIfFalseLabel) - } - } - } - - if(wordJumpForSimpleRightOperands(left, right, ::code)) - return - - assignWordOperandsToAYAndVar(left, right, "P8ZP_SCRATCH_W2") - return out(" jsr prog8_lib.reg_less_uw | beq $jumpIfFalseLabel") - } - - private fun translateWordLessOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(msbCpyOperand: String, lsbCmpOperand: String) { - out(""" - cmp $lsbCmpOperand - tya - sbc $msbCpyOperand - bvc + - eor #$80 -+ bpl $jumpIfFalseLabel""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal>=leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - return if(rightConstVal.number.toInt()!=0) { - assignExpressionToRegister(left, RegisterOrPair.AY) - code("#>${rightConstVal.number.toInt()}", "#<${rightConstVal.number.toInt()}") - } - else { - val name = asmVariableName(left) - out(" lda $name+1 | bpl $jumpIfFalseLabel") - } - } - } - } - - if(wordJumpForSimpleRightOperands(left, right, ::code)) - return - - assignWordOperandsToAYAndVar(left, right, "P8ZP_SCRATCH_W2") - return out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel") - } - - private fun translateUbyteGreaterOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(cmpOperand: String) { - out(""" - cmp $cmpOperand - bcc $jumpIfFalseLabel - beq $jumpIfFalseLabel""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal<=leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - assignExpressionToRegister(left, RegisterOrPair.A) - return if(rightConstVal.number.toInt()!=0) - code("#${rightConstVal.number.toInt()}") - else - out(" beq $jumpIfFalseLabel") - } - else if (left is PtMemoryByte) { - translateDirectMemReadExpressionToRegA(left) - return if(rightConstVal.number.toInt()!=0) - code("#${rightConstVal.number.toInt()}") - else - out(" beq $jumpIfFalseLabel") - } - } - } - - if(byteJumpForSimpleRightOperand(left, right, ::code)) - return - - assignByteOperandsToAAndVar(left, right, "P8ZP_SCRATCH_B1") - return code("P8ZP_SCRATCH_B1") - } - - private fun translateByteGreaterOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(sbcOperand: String) { - out(""" - clc - sbc $sbcOperand - bvc + - eor #$80 -+ bpl + - bmi $jumpIfFalseLabel -+""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal<=leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - assignExpressionToRegister(left, RegisterOrPair.A) - return if(rightConstVal.number.toInt()!=0) - code("#${rightConstVal.number}") - else - out(" bmi $jumpIfFalseLabel | beq $jumpIfFalseLabel") - } - } - } - - if(byteJumpForSimpleRightOperand(left, right, ::code)) - return - - assignByteOperandsToAAndVar(left, right, "P8ZP_SCRATCH_B1") - return code("P8ZP_SCRATCH_B1") - } - - private fun translateUwordGreaterOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(msbCpyOperand: String, lsbCmpOperand: String) { - out(""" - cpy $msbCpyOperand - bcc $jumpIfFalseLabel - bne + - cmp $lsbCmpOperand - bcc $jumpIfFalseLabel -+ beq $jumpIfFalseLabel -""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal<=leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - return if(rightConstVal.number.toInt()!=0) { - assignExpressionToRegister(left, RegisterOrPair.AY) - code("#>${rightConstVal.number.toInt()}", "#<${rightConstVal.number.toInt()}") - } - else { - val name = asmVariableName(left) - out(""" - lda $name - ora $name+1 - beq $jumpIfFalseLabel""") - } - } - } - } - - if(wordJumpForSimpleRightOperands(left, right, ::code)) - return - - assignWordOperandsToAYAndVar(left, right, "P8ZP_SCRATCH_W2") - return code("P8ZP_SCRATCH_W2+1", "P8ZP_SCRATCH_W2") - } - - private fun translateWordGreaterOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(msbCmpOperand: String, lsbCmpOperand: String) { - out(""" - cmp $lsbCmpOperand - tya - sbc $msbCmpOperand - bvc + - eor #$80 -+ bpl $jumpIfFalseLabel""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal<=leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - return if(rightConstVal.number.toInt()!=0) { - assignExpressionToRegister(right, RegisterOrPair.AY) - val varname = asmVariableName(left) - code("$varname+1", varname) - } - else { - val name = asmVariableName(left) - out(""" - lda $name+1 - bmi $jumpIfFalseLabel - lda $name - beq $jumpIfFalseLabel""") - } - } - } - } - - if(wordJumpForSimpleLeftOperand(left, right, ::code)) - return - - assignWordOperandsToAYAndVar(right, left, "P8ZP_SCRATCH_W2") - return out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel") - } - - private fun translateUbyteLessOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(cmpOperand: String) { - out(""" - cmp $cmpOperand - beq + - bcs $jumpIfFalseLabel -+""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal>leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - assignExpressionToRegister(left, RegisterOrPair.A) - return if(rightConstVal.number.toInt()!=0) - code("#${rightConstVal.number.toInt()}") - else - out(" bne $jumpIfFalseLabel") - } - else if (left is PtMemoryByte) { - translateDirectMemReadExpressionToRegA(left) - return if(rightConstVal.number.toInt()!=0) - code("#${rightConstVal.number.toInt()}") - else - out(" bne $jumpIfFalseLabel") - } - } - } - - if(byteJumpForSimpleRightOperand(left, right, ::code)) - return - - assignByteOperandsToAAndVar(left, right, "P8ZP_SCRATCH_B1") - return code("P8ZP_SCRATCH_B1") - } - - private fun translateByteLessOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - fun code(sbcOperand: String) { - out(""" - clc - sbc $sbcOperand - bvc + - eor #$80 -+ bpl $jumpIfFalseLabel""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal>leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - assignExpressionToRegister(left, RegisterOrPair.A) - return if(rightConstVal.number.toInt()!=0) - code("#${rightConstVal.number}") - else - out(""" - beq + - bpl $jumpIfFalseLabel -+""") - } - } - } - - if(byteJumpForSimpleRightOperand(left, right, ::code)) - return - - assignByteOperandsToAAndVar(left, right, "P8ZP_SCRATCH_B1") - return code("P8ZP_SCRATCH_B1") - } - - private fun translateUwordLessOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(msbCpyOperand: String, lsbCmpOperand: String) { - out(""" - cpy $msbCpyOperand - beq + - bcc ++ - bcs $jumpIfFalseLabel -+ cmp $lsbCmpOperand - bcc + - beq + - bne $jumpIfFalseLabel -+""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal>leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - return if(rightConstVal.number.toInt()!=0) { - assignExpressionToRegister(left, RegisterOrPair.AY) - code("#>${rightConstVal.number.toInt()}", "#<${rightConstVal.number.toInt()}") - } - else { - val name = asmVariableName(left) - out(""" - lda $name - ora $name+1 - bne $jumpIfFalseLabel""") - } - } - } - } - - if(wordJumpForSimpleRightOperands(left, right, ::code)) - return - - assignWordOperandsToAYAndVar(left, right, "P8ZP_SCRATCH_W2") - return out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel") - } - - private fun translateWordLessOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(leftName: String) { - out(""" - cmp $leftName - tya - sbc $leftName+1 - bvc + - eor #$80 -+ bmi $jumpIfFalseLabel -""") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal>leftConstVal) - jmp(jumpIfFalseLabel) - return - } else { - if (left is PtIdentifier) { - return if(rightConstVal.number.toInt()!=0) { - assignExpressionToRegister(right, RegisterOrPair.AY) - code(asmVariableName(left)) - } - else { - val name = asmVariableName(left) - out(""" - lda $name+1 - bmi + - bne $jumpIfFalseLabel - lda $name - bne $jumpIfFalseLabel -+""") - } - } - } - } - - if(left is PtIdentifier) { - assignExpressionToRegister(right, RegisterOrPair.AY) - return code(asmVariableName(left)) - } - - assignWordOperandsToAYAndVar(right, left, "P8ZP_SCRATCH_W2") - return out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel") - } - - private fun translateUbyteGreaterOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) { - - fun code(cmpOperand: String) { - out(" cmp $cmpOperand | bcc $jumpIfFalseLabel") - } - - if(rightConstVal!=null) { - if(leftConstVal!=null) { - if(rightConstVal= value, to a bool 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 + IR: add TEST instruction to test memory content and set N/Z flags, without affecting any register. replace all LOADM+CMPI #0 / LOAD #0+LOADM+CMP+BRANCH by this instruction