mirror of
https://github.com/irmen/prog8.git
synced 2026-10-22 05:02:58 +00:00
fix wrong result for short-circuit boolean and/or on the virtual target
This commit is contained in:
1 parent
99ff5768c5
commit
5e83c44300
4 files changed
+129
-8
No files matched your search
@@ -1561,6 +1561,26 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit the branch that decides if the short-circuit evaluation of a boolean `or`/`and` has to
|
||||
* skip its right hand side: [branchWhenZeroTrue] selects if the branch is taken when the left
|
||||
* hand side value in the register is zero (false) instead of when it is non-zero (true).
|
||||
* The status bits have to be set from that register first, because only CMP/CMPI/SGN/BITTST do
|
||||
* that on targets that don't honor CpuType.statusBitsOnMultiByteOps, and the value can also come
|
||||
* straight from a load or a register move.
|
||||
*/
|
||||
private fun addShortCircuitBranch(result: MutableList<IRCodeChunkBase>, leftTr: ExpressionCodeResult, shortcutLabel: String, branchWhenZeroTrue: Boolean) {
|
||||
val lastInstr = leftTr.chunks.lastOrNull()?.instructions?.lastOrNull()
|
||||
val skipCmpi = codeGen.options.compTarget.cpu.statusBitsOnMultiByteOps
|
||||
&& lastInstr != null
|
||||
&& lastInstr.opcode in OpcodesThatSetStatusbits
|
||||
if (!skipCmpi) {
|
||||
addInstr(result, IRInstructions.compareImmediate(IRDataType.BYTE, leftTr.resultReg, 0), null)
|
||||
}
|
||||
val branchOpcode = if (branchWhenZeroTrue) Opcode.BSTEQ else Opcode.BSTNE
|
||||
addInstr(result, IRInstructions.branch(branchOpcode, codeLabel(shortcutLabel)), null)
|
||||
}
|
||||
|
||||
private fun operatorAnd(binExpr: PtBinaryExpression, vmDt: IRDataType, bitwise: Boolean): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(!bitwise && !binExpr.right.isSimple()) {
|
||||
@@ -1568,7 +1588,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, leftTr.resultReg, -1)
|
||||
val shortcutLabel = codeGen.createLabelName()
|
||||
addInstr(result, IRInstructions.branch(Opcode.BSTEQ, codeLabel(shortcutLabel)), null)
|
||||
addShortCircuitBranch(result, leftTr, shortcutLabel, branchWhenZeroTrue = true)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
addToResult(result, rightTr, leftTr.resultReg, -1)
|
||||
result += IRCodeChunk(shortcutLabel, null)
|
||||
@@ -1602,7 +1622,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, leftTr.resultReg, -1)
|
||||
val shortcutLabel = codeGen.createLabelName()
|
||||
addInstr(result, IRInstructions.branch(Opcode.BSTNE, codeLabel(shortcutLabel)), null)
|
||||
addShortCircuitBranch(result, leftTr, shortcutLabel, branchWhenZeroTrue = false)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
addToResult(result, rightTr, leftTr.resultReg, -1)
|
||||
result += IRCodeChunk(shortcutLabel, null)
|
||||
|
||||
Reference in new issue
Block a user