mirror of
https://github.com/irmen/prog8.git
synced 2024-11-16 22:09:56 +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) {
|
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 {
|
||||||
|
@ -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
|
||||||
|
@ -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!
|
||||||
|
Loading…
Reference in New Issue
Block a user