mirror of
https://github.com/irmen/prog8.git
synced 2026-04-20 11:17:01 +00:00
more Rpn optimizations
This commit is contained in:
@@ -898,6 +898,7 @@ class IRCodeGen(
|
||||
|
||||
private fun translate(ifElse: PtIfElse): IRCodeChunks {
|
||||
val condition = ifElse.condition
|
||||
val goto = ifElse.ifScope.children.firstOrNull() as? PtJump
|
||||
when (condition) {
|
||||
is PtBinaryExpression -> {
|
||||
if(condition.operator !in ComparisonOperators)
|
||||
@@ -905,7 +906,6 @@ class IRCodeGen(
|
||||
|
||||
val signed = condition.left.type in SignedDatatypes
|
||||
val irDtLeft = irType(condition.left.type)
|
||||
val goto = ifElse.ifScope.children.firstOrNull() as? PtJump
|
||||
return when {
|
||||
goto!=null && ifElse.elseScope.children.isEmpty() -> translateIfFollowedByJustGoto(ifElse, goto, irDtLeft, signed)
|
||||
constValue(condition.right) == 0.0 -> translateIfElseZeroComparison(ifElse, irDtLeft, signed)
|
||||
@@ -913,52 +913,92 @@ class IRCodeGen(
|
||||
}
|
||||
}
|
||||
is PtRpn -> {
|
||||
TODO("RPN ifelse (intermediate codegen) $condition")
|
||||
val (left, oper, right) = condition.finalOperation()
|
||||
if(oper.operator !in ComparisonOperators)
|
||||
throw AssemblyError("if condition should only be a binary comparison expression")
|
||||
|
||||
val signed = oper.leftType in SignedDatatypes
|
||||
val irDtLeft = irType(oper.leftType)
|
||||
return when {
|
||||
goto!=null && ifElse.elseScope.children.isEmpty() -> translateIfFollowedByJustGotoRPN(ifElse, goto, irDtLeft, signed)
|
||||
constValue(right as PtExpression) == 0.0 -> translateIfElseZeroComparisonRPN(ifElse, irDtLeft, signed)
|
||||
else -> translateIfElseNonZeroComparisonRPN(ifElse, irDtLeft, signed)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
TODO("weird condition node: $condition")
|
||||
throw AssemblyError("weird condition node: $condition")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateIfFollowedByJustGotoRPN(ifElse: PtIfElse, goto: PtJump, irDtLeft: IRDataType, signed: Boolean): MutableList<IRCodeChunkBase> {
|
||||
TODO("RPN translateIfFollowedByJustGotoRPN")
|
||||
}
|
||||
|
||||
private fun translateIfElseZeroComparisonRPN(ifElse: PtIfElse, irDtLeft: IRDataType, signed: Boolean): IRCodeChunks {
|
||||
TODO("RPN translateIfElseZeroComparisonRPN")
|
||||
}
|
||||
|
||||
private fun translateIfElseNonZeroComparisonRPN(ifElse: PtIfElse, irDtLeft: IRDataType, signed: Boolean): IRCodeChunks {
|
||||
TODO("RPN translateIfElseNonZeroComparisonRPN")
|
||||
}
|
||||
|
||||
private fun translateIfFollowedByJustGoto(ifElse: PtIfElse, goto: PtJump, irDtLeft: IRDataType, signed: Boolean): MutableList<IRCodeChunkBase> {
|
||||
if(program.binaryExpressionsAreRPN) {
|
||||
TODO ("RPN (intermediate codegen)")
|
||||
require(!program.binaryExpressionsAreRPN)
|
||||
val condition = ifElse.condition as PtBinaryExpression
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if (irDtLeft == IRDataType.FLOAT) {
|
||||
val leftTr = expressionEval.translateExpression(condition.left)
|
||||
addToResult(result, leftTr, -1, leftTr.resultFpReg)
|
||||
val rightTr = expressionEval.translateExpression(condition.right)
|
||||
addToResult(result, rightTr, -1, rightTr.resultFpReg)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val compResultReg = registers.nextFree()
|
||||
it += IRInstruction(
|
||||
Opcode.FCOMP,
|
||||
IRDataType.FLOAT,
|
||||
reg1 = compResultReg,
|
||||
fpReg1 = leftTr.resultFpReg,
|
||||
fpReg2 = rightTr.resultFpReg
|
||||
)
|
||||
val gotoOpcode = when (condition.operator) {
|
||||
"==" -> Opcode.BZ
|
||||
"!=" -> Opcode.BNZ
|
||||
"<" -> Opcode.BLEZS
|
||||
">" -> Opcode.BGEZS
|
||||
"<=" -> Opcode.BLZS
|
||||
">=" -> Opcode.BGZS
|
||||
else -> throw AssemblyError("weird operator")
|
||||
}
|
||||
it += if (goto.address != null)
|
||||
IRInstruction(
|
||||
gotoOpcode,
|
||||
IRDataType.BYTE,
|
||||
reg1 = compResultReg,
|
||||
value = goto.address?.toInt()
|
||||
)
|
||||
else if (goto.generatedLabel != null)
|
||||
IRInstruction(
|
||||
gotoOpcode,
|
||||
IRDataType.BYTE,
|
||||
reg1 = compResultReg,
|
||||
labelSymbol = goto.generatedLabel
|
||||
)
|
||||
else
|
||||
IRInstruction(
|
||||
gotoOpcode,
|
||||
IRDataType.BYTE,
|
||||
reg1 = compResultReg,
|
||||
labelSymbol = goto.identifier!!.name
|
||||
)
|
||||
}
|
||||
return result
|
||||
} else {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val condition = ifElse.condition as PtBinaryExpression
|
||||
if(irDtLeft==IRDataType.FLOAT) {
|
||||
val leftTr = expressionEval.translateExpression(condition.left)
|
||||
addToResult(result, leftTr, -1, leftTr.resultFpReg)
|
||||
val rightTr = expressionEval.translateExpression(condition.right)
|
||||
addToResult(result, rightTr, -1, rightTr.resultFpReg)
|
||||
result += IRCodeChunk(null,null).also {
|
||||
val compResultReg = registers.nextFree()
|
||||
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg)
|
||||
val gotoOpcode = when (condition.operator) {
|
||||
"==" -> Opcode.BZ
|
||||
"!=" -> Opcode.BNZ
|
||||
"<" -> Opcode.BLEZS
|
||||
">" -> Opcode.BGEZS
|
||||
"<=" -> Opcode.BLZS
|
||||
">=" -> Opcode.BGZS
|
||||
else -> throw AssemblyError("weird operator")
|
||||
}
|
||||
it += if (goto.address != null)
|
||||
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, value = goto.address?.toInt())
|
||||
else if (goto.generatedLabel != null)
|
||||
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, labelSymbol = goto.generatedLabel)
|
||||
else
|
||||
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, labelSymbol = goto.identifier!!.name)
|
||||
}
|
||||
return result
|
||||
} else {
|
||||
val rightConst = condition.right.asConstInteger()
|
||||
return if(rightConst==0)
|
||||
ifZeroIntThenJump(result, ifElse, signed, irDtLeft, goto)
|
||||
else {
|
||||
ifNonZeroIntThenJump(result, ifElse, signed, irDtLeft, goto)
|
||||
}
|
||||
val rightConst = condition.right.asConstInteger()
|
||||
return if (rightConst == 0)
|
||||
ifZeroIntThenJump(result, ifElse, signed, irDtLeft, goto)
|
||||
else {
|
||||
ifNonZeroIntThenJump(result, ifElse, signed, irDtLeft, goto)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user