mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 19:31:36 +00:00
fix compiler error on float comparison expressions
This commit is contained in:
parent
5fffd35ec1
commit
584be44743
@ -16,14 +16,16 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
fun translate(assignment: PtAssignment) {
|
||||
val target = AsmAssignTarget.fromAstAssignment(assignment.target, assignment.definingISub(), asmgen)
|
||||
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())
|
||||
}
|
||||
|
||||
fun translate(augmentedAssign: PtAugmentedAssign) {
|
||||
val target = AsmAssignTarget.fromAstAssignment(augmentedAssign.target, augmentedAssign.definingISub(), asmgen)
|
||||
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())
|
||||
}
|
||||
|
||||
@ -369,7 +371,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
is PtBinaryExpression -> {
|
||||
if(!attemptAssignOptimizedBinexpr(value, assign)) {
|
||||
// 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")
|
||||
@ -410,66 +413,65 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||
if(expr.operator in ComparisonOperators) {
|
||||
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.
|
||||
}
|
||||
val translatedOk = when (expr.operator) {
|
||||
in ComparisonOperators -> optimizedComparison(expr, assign)
|
||||
in setOf("&", "|", "^", "and", "or", "xor") -> optimizedLogicalOrBitwiseExpr(expr, assign.target)
|
||||
"==", "!=" -> optimizedEqualityExpr(expr, assign.target)
|
||||
"+", "-" -> optimizedPlusMinExpr(expr, assign.target)
|
||||
"<<", ">>" -> optimizedBitshiftExpr(expr, assign.target)
|
||||
"*" -> 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)
|
||||
return anyExprGen.assignAnyExpressionUsingStack(expr, assign)
|
||||
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
|
||||
}
|
||||
|
||||
if(expr.operator in setOf("&", "|", "^", "and", "or", "xor"))
|
||||
return optimizedLogicalOrBitwiseExpr(expr, assign.target)
|
||||
if(expr.operator == "==" || expr.operator == "!=")
|
||||
return optimizedEqualityExpr(expr, assign.target)
|
||||
if(expr.operator=="+" || expr.operator=="-")
|
||||
return optimizedPlusMinExpr(expr, assign.target)
|
||||
if(expr.operator=="<<" || expr.operator==">>")
|
||||
return optimizedBitshiftExpr(expr, assign.target)
|
||||
if(expr.operator=="*")
|
||||
return optimizedMultiplyExpr(expr, assign.target)
|
||||
if(expr.operator=="/")
|
||||
return optimizedDivideExpr(expr, assign.target)
|
||||
if(expr.operator=="%")
|
||||
return optimizedRemainderExpr(expr, assign.target)
|
||||
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
|
||||
}
|
||||
|
||||
return anyExprGen.assignAnyExpressionUsingStack(expr, assign)
|
||||
return false
|
||||
}
|
||||
|
||||
private fun optimizedRemainderExpr(expr: PtBinaryExpression, target: AsmAssignTarget): Boolean {
|
||||
|
@ -9,7 +9,7 @@ test: clean generate test_prgs
|
||||
|
||||
generate:
|
||||
python make_tests.py
|
||||
p8compile -noopt -target cx16 *.p8 >/dev/null
|
||||
p8compile -target cx16 *.p8 >/dev/null
|
||||
|
||||
test_prgs:
|
||||
x16emu -run -prg more_compares.prg
|
||||
|
@ -1,6 +1,9 @@
|
||||
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 ....
|
||||
- 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!
|
||||
|
Loading…
Reference in New Issue
Block a user