mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
finalize short-circuit eval in IR codegen
This commit is contained in:
parent
265e7aefbf
commit
89cc7e5fa9
@ -83,8 +83,10 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
"*=" -> expressionEval.operatorMultiplyInplace(null, symbol, targetDt, value)
|
"*=" -> expressionEval.operatorMultiplyInplace(null, symbol, targetDt, value)
|
||||||
"/=" -> expressionEval.operatorDivideInplace(null, symbol, targetDt, value.type in SignedDatatypes, value)
|
"/=" -> expressionEval.operatorDivideInplace(null, symbol, targetDt, value.type in SignedDatatypes, value)
|
||||||
"|=" -> expressionEval.operatorOrInplace(null, symbol, targetDt, value)
|
"|=" -> expressionEval.operatorOrInplace(null, symbol, targetDt, value)
|
||||||
|
"or=" -> expressionEval.operatorLogicalOrInplace(null, symbol, targetDt, value)
|
||||||
"&=" -> expressionEval.operatorAndInplace(null, symbol, targetDt, value)
|
"&=" -> expressionEval.operatorAndInplace(null, symbol, targetDt, value)
|
||||||
"^=" -> expressionEval.operatorXorInplace(null, symbol, targetDt, value)
|
"and=" -> expressionEval.operatorLogicalAndInplace(null, symbol, targetDt, value)
|
||||||
|
"^=", "xor=" -> expressionEval.operatorXorInplace(null, symbol, targetDt, value)
|
||||||
"<<=" -> expressionEval.operatorShiftLeftInplace(null, symbol, targetDt, value)
|
"<<=" -> expressionEval.operatorShiftLeftInplace(null, symbol, targetDt, value)
|
||||||
">>=" -> expressionEval.operatorShiftRightInplace(null, symbol, targetDt, value.type in SignedDatatypes, value)
|
">>=" -> expressionEval.operatorShiftRightInplace(null, symbol, targetDt, value.type in SignedDatatypes, value)
|
||||||
"%=" -> expressionEval.operatorModuloInplace(null, symbol, targetDt, value)
|
"%=" -> expressionEval.operatorModuloInplace(null, symbol, targetDt, value)
|
||||||
|
@ -995,8 +995,38 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
addInstr(result, if(knownAddress!=null)
|
addInstr(result, if(knownAddress!=null)
|
||||||
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, address = knownAddress)
|
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, address = knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
|
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, labelSymbol = symbol),null)
|
||||||
,null)
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun operatorLogicalAndInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks {
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val tr = translateExpression(operand)
|
||||||
|
if(codeGen.options.shortCircuit && !operand.isSimple()) {
|
||||||
|
// short-circuit LEFT and RIGHT --> if LEFT then RIGHT else LEFT (== if !LEFT then LEFT else RIGHT)
|
||||||
|
val inplaceReg = codeGen.registers.nextFree()
|
||||||
|
val shortcutLabel = codeGen.createLabelName()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += if(knownAddress!=null)
|
||||||
|
IRInstruction(Opcode.LOADM, vmDt, reg1=inplaceReg, address = knownAddress)
|
||||||
|
else
|
||||||
|
IRInstruction(Opcode.LOADM, vmDt, reg1=inplaceReg, labelSymbol = symbol)
|
||||||
|
it += IRInstruction(Opcode.BSTEQ, labelSymbol = shortcutLabel)
|
||||||
|
}
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
addInstr(result, if(knownAddress!=null)
|
||||||
|
IRInstruction(Opcode.STOREM, vmDt, reg1=tr.resultReg, address = knownAddress)
|
||||||
|
else
|
||||||
|
IRInstruction(Opcode.STOREM, vmDt, reg1=tr.resultReg, labelSymbol = symbol), null)
|
||||||
|
result += IRCodeChunk(shortcutLabel, null)
|
||||||
|
} else {
|
||||||
|
// normal evaluation
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
addInstr(result, if(knownAddress!=null)
|
||||||
|
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, address = knownAddress)
|
||||||
|
else
|
||||||
|
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, labelSymbol = symbol),null)
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,8 +1037,37 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
addInstr(result, if(knownAddress!=null)
|
addInstr(result, if(knownAddress!=null)
|
||||||
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, address = knownAddress)
|
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, address = knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
|
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, labelSymbol = symbol), null)
|
||||||
, null)
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun operatorLogicalOrInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks {
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val tr = translateExpression(operand)
|
||||||
|
if(codeGen.options.shortCircuit && !operand.isSimple()) {
|
||||||
|
// short-circuit LEFT or RIGHT --> if LEFT then LEFT else RIGHT
|
||||||
|
val inplaceReg = codeGen.registers.nextFree()
|
||||||
|
val shortcutLabel = codeGen.createLabelName()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += if(knownAddress!=null)
|
||||||
|
IRInstruction(Opcode.LOADM, vmDt, reg1=inplaceReg, address = knownAddress)
|
||||||
|
else
|
||||||
|
IRInstruction(Opcode.LOADM, vmDt, reg1=inplaceReg, labelSymbol = symbol)
|
||||||
|
it += IRInstruction(Opcode.BSTNE, labelSymbol = shortcutLabel)
|
||||||
|
}
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
addInstr(result, if(knownAddress!=null)
|
||||||
|
IRInstruction(Opcode.STOREM, vmDt, reg1=tr.resultReg, address = knownAddress)
|
||||||
|
else
|
||||||
|
IRInstruction(Opcode.STOREM, vmDt, reg1=tr.resultReg, labelSymbol = symbol), null)
|
||||||
|
result += IRCodeChunk(shortcutLabel, null)
|
||||||
|
} else {
|
||||||
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
addInstr(result, if(knownAddress!=null)
|
||||||
|
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, address = knownAddress)
|
||||||
|
else
|
||||||
|
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, labelSymbol = symbol), null)
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,12 +2,6 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- [on branch: shortcircuit] complete McCarthy evaluation. This may also reduce code size perhaps for things like if a>4 or a<2 ....
|
|
||||||
- note: shortcircuit only on logical boolean expressions (and,or) not on bitwise (&,|)
|
|
||||||
- vm ircodegen (PARTIALLY DONE!)
|
|
||||||
- in 6502 codegen (see vm's ExpressionGen operatorAnd / operatorOr)
|
|
||||||
- remove debug println's
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user