fix compiler error on float comparison expressions

This commit is contained in:
Irmen de Jong 2023-08-11 23:41:19 +02:00
parent 5fffd35ec1
commit 584be44743
3 changed files with 62 additions and 57 deletions

View File

@ -16,14 +16,16 @@ internal class AssignmentAsmGen(private val program: PtProgram,
fun translate(assignment: PtAssignment) { fun translate(assignment: PtAssignment) {
val target = AsmAssignTarget.fromAstAssignment(assignment.target, assignment.definingISub(), asmgen) val target = AsmAssignTarget.fromAstAssignment(assignment.target, assignment.definingISub(), asmgen)
val source = AsmAssignSource.fromAstSource(assignment.value, program, asmgen).adjustSignedUnsigned(target) val source = AsmAssignSource.fromAstSource(assignment.value, program, asmgen).adjustSignedUnsigned(target)
val assign = AsmAssignment(source, target, program.memsizer, assignment.position) val pos = if(assignment.position !== Position.DUMMY) assignment.position else if(assignment.target.position !== Position.DUMMY) assignment.target.position else assignment.value.position
val assign = AsmAssignment(source, target, program.memsizer, pos)
translateNormalAssignment(assign, assignment.definingISub()) translateNormalAssignment(assign, assignment.definingISub())
} }
fun translate(augmentedAssign: PtAugmentedAssign) { fun translate(augmentedAssign: PtAugmentedAssign) {
val target = AsmAssignTarget.fromAstAssignment(augmentedAssign.target, augmentedAssign.definingISub(), asmgen) val target = AsmAssignTarget.fromAstAssignment(augmentedAssign.target, augmentedAssign.definingISub(), asmgen)
val source = AsmAssignSource.fromAstSource(augmentedAssign.value, program, asmgen).adjustSignedUnsigned(target) val source = AsmAssignSource.fromAstSource(augmentedAssign.value, program, asmgen).adjustSignedUnsigned(target)
val assign = AsmAugmentedAssignment(source, augmentedAssign.operator, target, program.memsizer, augmentedAssign.position) val pos = if(augmentedAssign.position !== Position.DUMMY) augmentedAssign.position else if(augmentedAssign.target.position !== Position.DUMMY) augmentedAssign.target.position else augmentedAssign.value.position
val assign = AsmAugmentedAssignment(source, augmentedAssign.operator, target, program.memsizer, pos)
augmentableAsmGen.translate(assign, augmentedAssign.definingISub()) augmentableAsmGen.translate(assign, augmentedAssign.definingISub())
} }
@ -369,7 +371,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
is PtBinaryExpression -> { is PtBinaryExpression -> {
if(!attemptAssignOptimizedBinexpr(value, assign)) { if(!attemptAssignOptimizedBinexpr(value, assign)) {
// TOO BAD: the expression was too complex to translate into assembly. // TOO BAD: the expression was too complex to translate into assembly.
throw AssemblyError("Expression is too complex to translate into assembly. Split it up into several separate statements, introduce a temporary variable, or otherwise rewrite it. Location: ${assign.position}") val pos = if(value.position!==Position.DUMMY) value.position else assign.position
throw AssemblyError("Expression is too complex to translate into assembly. Split it up into several separate statements, introduce a temporary variable, or otherwise rewrite it. Location: $pos")
} }
} }
else -> throw AssemblyError("weird assignment value type $value") else -> throw AssemblyError("weird assignment value type $value")
@ -410,66 +413,65 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean { private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
if(expr.operator in ComparisonOperators) { val translatedOk = when (expr.operator) {
if(expr.right.asConstInteger() == 0) { in ComparisonOperators -> optimizedComparison(expr, assign)
if(expr.operator == "==" || expr.operator=="!=") { in setOf("&", "|", "^", "and", "or", "xor") -> optimizedLogicalOrBitwiseExpr(expr, assign.target)
when(assign.target.datatype) { "==", "!=" -> optimizedEqualityExpr(expr, assign.target)
in ByteDatatypes -> if(attemptAssignToByteCompareZero(expr, assign)) return true "+", "-" -> optimizedPlusMinExpr(expr, assign.target)
else -> { "<<", ">>" -> optimizedBitshiftExpr(expr, assign.target)
// do nothing, this is handled by a type cast. "*" -> optimizedMultiplyExpr(expr, assign.target)
} "/" -> optimizedDivideExpr(expr, assign.target)
"%" -> optimizedRemainderExpr(expr, assign.target)
else -> false
}
return if(translatedOk)
true
else
anyExprGen.assignAnyExpressionUsingStack(expr, assign)
}
private fun optimizedComparison(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
if(expr.right.asConstInteger() == 0) {
if(expr.operator == "==" || expr.operator=="!=") {
when(assign.target.datatype) {
in ByteDatatypes -> if(attemptAssignToByteCompareZero(expr, assign)) return true
else -> {
// do nothing, this is handled by a type cast.
} }
} }
} }
if(expr.left.type in ByteDatatypes && expr.right.type in ByteDatatypes) {
if(assignOptimizedComparisonBytes(expr, assign))
return true
} else if(expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
if(assignOptimizedComparisonWords(expr, assign))
return true
}
val origTarget = assign.target.origAstTarget
if(origTarget!=null) {
assignConstantByte(assign.target, 0)
val assignTrue = PtNodeGroup()
val assignment = PtAssignment(assign.position)
assignment.add(origTarget)
assignment.add(PtNumber.fromBoolean(true, assign.position))
assignTrue.add(assignment)
val assignFalse = PtNodeGroup()
val ifelse = PtIfElse(assign.position)
val exprClone = PtBinaryExpression(expr.operator, expr.type, expr.position)
expr.children.forEach { exprClone.children.add(it) } // doesn't seem to need a deep clone
ifelse.add(exprClone)
ifelse.add(assignTrue)
ifelse.add(assignFalse)
ifelse.parent = expr.parent
asmgen.translate(ifelse)
return true
}
} }
if(expr.type !in IntegerDatatypes) if(expr.left.type in ByteDatatypes && expr.right.type in ByteDatatypes) {
return anyExprGen.assignAnyExpressionUsingStack(expr, assign) if(assignOptimizedComparisonBytes(expr, assign))
return true
} else if(expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
if(assignOptimizedComparisonWords(expr, assign))
return true
}
if(expr.operator in setOf("&", "|", "^", "and", "or", "xor")) val origTarget = assign.target.origAstTarget
return optimizedLogicalOrBitwiseExpr(expr, assign.target) if(origTarget!=null) {
if(expr.operator == "==" || expr.operator == "!=") assignConstantByte(assign.target, 0)
return optimizedEqualityExpr(expr, assign.target) val assignTrue = PtNodeGroup()
if(expr.operator=="+" || expr.operator=="-") val assignment = PtAssignment(assign.position)
return optimizedPlusMinExpr(expr, assign.target) assignment.add(origTarget)
if(expr.operator=="<<" || expr.operator==">>") assignment.add(PtNumber.fromBoolean(true, assign.position))
return optimizedBitshiftExpr(expr, assign.target) assignTrue.add(assignment)
if(expr.operator=="*") val assignFalse = PtNodeGroup()
return optimizedMultiplyExpr(expr, assign.target) val ifelse = PtIfElse(assign.position)
if(expr.operator=="/") val exprClone = PtBinaryExpression(expr.operator, expr.type, expr.position)
return optimizedDivideExpr(expr, assign.target) expr.children.forEach { exprClone.children.add(it) } // doesn't seem to need a deep clone
if(expr.operator=="%") ifelse.add(exprClone)
return optimizedRemainderExpr(expr, assign.target) ifelse.add(assignTrue)
ifelse.add(assignFalse)
ifelse.parent = expr.parent
asmgen.translate(ifelse)
return true
}
return anyExprGen.assignAnyExpressionUsingStack(expr, assign) return false
} }
private fun optimizedRemainderExpr(expr: PtBinaryExpression, target: AsmAssignTarget): Boolean { private fun optimizedRemainderExpr(expr: PtBinaryExpression, target: AsmAssignTarget): Boolean {

View File

@ -9,7 +9,7 @@ test: clean generate test_prgs
generate: generate:
python make_tests.py python make_tests.py
p8compile -noopt -target cx16 *.p8 >/dev/null p8compile -target cx16 *.p8 >/dev/null
test_prgs: test_prgs:
x16emu -run -prg more_compares.prg x16emu -run -prg more_compares.prg

View File

@ -1,6 +1,9 @@
TODO TODO
==== ====
- fix bug introduced by 017ef8a837077c339993004da9b4ccf5c8ca7b13 (> and/or <= change in AssignmentAsmGen byteLessEquals/byteGreater
Bug manifests in prog8 where 2nd row of aliens jerks too far to the right after a short while.
- [on branch:] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... - [on branch:] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction - IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
- IR: reduce amount of CMP/CMPI after instructions that set the status bits correctly (LOADs? INC? etc), but only after setting the status bits is verified! - IR: reduce amount of CMP/CMPI after instructions that set the status bits correctly (LOADs? INC? etc), but only after setting the status bits is verified!