vm: use shift-one instructions in codegen

This commit is contained in:
Irmen de Jong
2022-05-11 15:50:51 +02:00
parent 14e36f1362
commit bacba629a5
5 changed files with 79 additions and 70 deletions
@@ -762,4 +762,6 @@ class CodeGen(internal val program: PtProgram,
builtinFuncGen.translate(call, resultRegister)
internal fun isZero(expression: PtExpression): Boolean = expression is PtNumber && expression.number==0.0
internal fun isOne(expression: PtExpression): Boolean = expression is PtNumber && expression.number==1.0
}
@@ -363,24 +363,33 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
private fun operatorShiftRight(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, signed: Boolean): VmCodeChunk {
val code = VmCodeChunk()
// TODO if shift is 1, use ASR/LSR instruction instead of multishift
val leftResultReg = codeGen.vmRegisters.nextFree()
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, leftResultReg, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
val opc = if(signed) Opcode.ASRN else Opcode.LSRN
code += VmCodeInstruction(opc, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
if(codeGen.isOne(binExpr.right)) {
code += translateExpression(binExpr.left, resultRegister, -1)
val opc = if (signed) Opcode.ASR else Opcode.LSR
code += VmCodeInstruction(opc, vmDt, reg1 = resultRegister)
} else {
val leftResultReg = codeGen.vmRegisters.nextFree()
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, leftResultReg, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
val opc = if (signed) Opcode.ASRN else Opcode.LSRN
code += VmCodeInstruction(opc, vmDt, reg1 = resultRegister, reg2 = leftResultReg, reg3 = rightResultReg)
}
return code
}
private fun operatorShiftLeft(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk()
// TODO if shift is 1, use LSL instruction instead of multishift
val leftResultReg = codeGen.vmRegisters.nextFree()
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, leftResultReg, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
if(codeGen.isOne(binExpr.right)){
code += translateExpression(binExpr.left, resultRegister, -1)
code += VmCodeInstruction(Opcode.LSL, vmDt, reg1=resultRegister)
} else {
val leftResultReg = codeGen.vmRegisters.nextFree()
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, leftResultReg, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
}
return code
}