added immediate value vm arithmetic instructions because these are so common

This commit is contained in:
Irmen de Jong
2022-07-12 15:15:28 +02:00
parent 840331347b
commit 314398ba4c
7 changed files with 287 additions and 86 deletions

View File

@@ -349,14 +349,10 @@ class CodeGen(internal val program: PtProgram,
code += VmCodeInstruction(Opcode.DEC, dt, reg1=reg)
}
else -> {
val valueReg = vmRegisters.nextFree()
if(value>0) {
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value= value)
code += VmCodeInstruction(Opcode.ADD, dt, reg1 = reg, reg2 = valueReg)
}
else {
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value= -value)
code += VmCodeInstruction(Opcode.SUB, dt, reg1 = reg, reg2 = valueReg)
code += if(value>0) {
VmCodeInstruction(Opcode.ADD, dt, reg1 = reg, value=value)
} else {
VmCodeInstruction(Opcode.SUB, dt, reg1 = reg, value=-value)
}
}
}
@@ -387,13 +383,13 @@ class CodeGen(internal val program: PtProgram,
if(value>0) {
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=value)
code += VmCodeInstruction(Opcode.ADD, dt, reg1 = valueReg, reg2 = operandReg)
code += VmCodeInstruction(Opcode.ADDR, dt, reg1 = valueReg, reg2 = operandReg)
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
}
else {
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=-value)
code += VmCodeInstruction(Opcode.SUB, dt, reg1 = valueReg, reg2 = operandReg)
code += VmCodeInstruction(Opcode.SUBR, dt, reg1 = valueReg, reg2 = operandReg)
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
}
}
@@ -405,12 +401,10 @@ class CodeGen(internal val program: PtProgram,
val code = VmCodeChunk()
if(factor==1f)
return code
if(factor==0f) {
code += VmCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = 0f)
code += if(factor==0f) {
VmCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = 0f)
} else {
val factorReg = vmRegisters.nextFreeFloat()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1=factorReg, fpValue = factor)
code += VmCodeInstruction(Opcode.MUL, VmDataType.FLOAT, fpReg1 = fpReg, fpReg2 = factorReg)
VmCodeInstruction(Opcode.MUL, VmDataType.FLOAT, fpReg1 = fpReg, fpValue=factor)
}
return code
}
@@ -446,13 +440,10 @@ class CodeGen(internal val program: PtProgram,
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += VmCodeInstruction(Opcode.LSLN, dt, reg1=reg, reg2=pow2reg)
} else {
if (factor == 0) {
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0)
}
else {
val factorReg = vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=factorReg, value= factor)
code += VmCodeInstruction(Opcode.MUL, dt, reg1=reg, reg2=factorReg)
code += if (factor == 0) {
VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0)
} else {
VmCodeInstruction(Opcode.MUL, dt, reg1=reg, value=factor)
}
}
return code
@@ -489,12 +480,10 @@ class CodeGen(internal val program: PtProgram,
val code = VmCodeChunk()
if(factor==1f)
return code
if(factor==0f) {
code += VmCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = Float.MAX_VALUE)
code += if(factor==0f) {
VmCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = Float.MAX_VALUE)
} else {
val factorReg = vmRegisters.nextFreeFloat()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1=factorReg, fpValue = factor)
code += VmCodeInstruction(Opcode.DIVS, VmDataType.FLOAT, fpReg1 = fpReg, fpReg2 = factorReg)
VmCodeInstruction(Opcode.DIVS, VmDataType.FLOAT, fpReg1 = fpReg, fpValue=factor)
}
return code
}
@@ -536,16 +525,13 @@ class CodeGen(internal val program: PtProgram,
else
VmCodeInstruction(Opcode.LSRN, dt, reg1=reg, reg2=pow2reg)
} else {
if (factor == 0) {
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
}
else {
val factorReg = vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=factorReg, value= factor)
code += if(signed)
VmCodeInstruction(Opcode.DIVS, dt, reg1=reg, reg2=factorReg)
code += if (factor == 0) {
VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
} else {
if(signed)
VmCodeInstruction(Opcode.DIVS, dt, reg1=reg, value=factor)
else
VmCodeInstruction(Opcode.DIV, dt, reg1=reg, reg2=factorReg)
VmCodeInstruction(Opcode.DIV, dt, reg1=reg, value=factor)
}
}
return code

View File

@@ -516,9 +516,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
throw IllegalArgumentException("floating-point modulo not supported")
val code = VmCodeChunk()
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.MOD, vmDt, reg1=resultRegister, reg2=rightResultReg)
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += VmCodeInstruction(Opcode.MOD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
} else {
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.MODR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
return code
}
@@ -539,9 +544,9 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += translateExpression(binExpr.right, -1, rightResultFpReg)
code += if(signed)
VmCodeInstruction(Opcode.DIVS, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
VmCodeInstruction(Opcode.DIVSR, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
else
VmCodeInstruction(Opcode.DIV, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
VmCodeInstruction(Opcode.DIVR, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
}
} else {
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
@@ -550,12 +555,20 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += codeGen.divideByConst(vmDt, resultRegister, factor, signed)
} else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += if(signed)
VmCodeInstruction(Opcode.DIVS, vmDt, reg1=resultRegister, reg2=rightResultReg)
else
VmCodeInstruction(Opcode.DIV, vmDt, reg1=resultRegister, reg2=rightResultReg)
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += if (signed)
VmCodeInstruction(Opcode.DIVS, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
else
VmCodeInstruction(Opcode.DIV, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
} else {
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += if (signed)
VmCodeInstruction(Opcode.DIVSR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
else
VmCodeInstruction(Opcode.DIVR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
}
return code
@@ -609,7 +622,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += translateExpression(binExpr.right, -1, rightResultFpReg)
code += VmCodeInstruction(Opcode.MUL, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg)
code += VmCodeInstruction(Opcode.MULR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg)
}
} else {
if(constFactorLeft!=null && constFactorLeft.type!=DataType.FLOAT) {
@@ -624,7 +637,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.MUL, vmDt, reg1=resultRegister, reg2=rightResultReg)
code += VmCodeInstruction(Opcode.MULR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
return code
@@ -663,10 +676,15 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += VmCodeInstruction(Opcode.DEC, vmDt, fpReg1 = resultFpRegister)
}
else {
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += translateExpression(binExpr.right, -1, rightResultFpReg)
code += VmCodeInstruction(Opcode.SUB, vmDt, fpReg1=resultFpRegister, fpReg2=rightResultFpReg)
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += VmCodeInstruction(Opcode.SUB, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat())
} else {
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += translateExpression(binExpr.right, -1, rightResultFpReg)
code += VmCodeInstruction(Opcode.SUBR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg)
}
}
} else {
if((binExpr.right as? PtNumber)?.number==1.0) {
@@ -674,10 +692,15 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += VmCodeInstruction(Opcode.DEC, vmDt, reg1=resultRegister)
}
else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.SUB, vmDt, reg1=resultRegister, reg2=rightResultReg)
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += VmCodeInstruction(Opcode.SUB, vmDt, reg1 = resultRegister, value = (binExpr.right as PtNumber).number.toInt())
} else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.SUBR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
}
return code
@@ -719,10 +742,15 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += VmCodeInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister)
}
else {
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += translateExpression(binExpr.right, -1, rightResultFpReg)
code += VmCodeInstruction(Opcode.ADD, vmDt, fpReg1=resultFpRegister, fpReg2=rightResultFpReg)
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += VmCodeInstruction(Opcode.ADD, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat())
} else {
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += translateExpression(binExpr.right, -1, rightResultFpReg)
code += VmCodeInstruction(Opcode.ADDR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg)
}
}
} else {
if((binExpr.left as? PtNumber)?.number==1.0) {
@@ -734,10 +762,15 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister)
}
else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.ADD, vmDt, reg1=resultRegister, reg2=rightResultReg)
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += VmCodeInstruction(Opcode.ADD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
} else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.ADDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
}
return code

View File

@@ -109,7 +109,7 @@ bges reg1, reg2, location - jump to location in program given by l
}
private fun removeUselessArithmetic(block: VmCodeChunk, indexedInstructions: List<IndexedValue<Instruction>>): Boolean {
// TODO this is hard to solve atm because the values are loaded into registers first
// TODO this is hard to solve for the non-immediate instructions atm because the values are loaded into registers first
var changed = false
indexedInstructions.reversed().forEach { (idx, ins) ->
when (ins.opcode) {