ir: consolidate IRCodeInstruction and Instruction

This commit is contained in:
Irmen de Jong 2022-09-26 19:46:44 +02:00
parent 0da117efd2
commit 4d6dcbd173
17 changed files with 624 additions and 649 deletions

View File

@ -6,7 +6,7 @@ import prog8.code.core.DataType
import prog8.code.core.Position
import prog8.code.core.SignedDatatypes
import prog8.intermediate.IRCodeChunk
import prog8.intermediate.IRCodeInstruction
import prog8.intermediate.IRInstruction
import prog8.intermediate.Opcode
import prog8.intermediate.VmDataType
@ -62,8 +62,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
else {
// read and write a (i/o) memory location to itself.
val tempReg = codeGen.vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, value = address)
code += IRCodeInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, value = address)
code += IRInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, value = address)
code += IRInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, value = address)
code
}
}
@ -85,8 +85,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
is PtBinaryExpression -> return inplaceBinexpr(value.operator, value.right, vmDt, value.type in SignedDatatypes, null, symbol, origAssign)
is PtMemoryByte -> {
val tempReg = codeGen.vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, labelSymbol = symbol)
code += IRCodeInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, labelSymbol = symbol)
code += IRInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, labelSymbol = symbol)
code += IRInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, labelSymbol = symbol)
return code
}
else -> return fallbackAssign(origAssign)
@ -145,18 +145,18 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
"+" -> { }
"-" -> {
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.NEGM, vmDt, value = knownAddress)
IRInstruction(Opcode.NEGM, vmDt, value = knownAddress)
else
IRCodeInstruction(Opcode.NEGM, vmDt, labelSymbol = addressSymbol)
IRInstruction(Opcode.NEGM, vmDt, labelSymbol = addressSymbol)
}
"~" -> {
val regMask = codeGen.vmRegisters.nextFree()
val mask = if(vmDt==VmDataType.BYTE) 0x00ff else 0xffff
code += IRCodeInstruction(Opcode.LOAD, vmDt, reg1=regMask, value = mask)
code += IRInstruction(Opcode.LOAD, vmDt, reg1=regMask, value = mask)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.XORM, vmDt, reg1=regMask, value = knownAddress)
IRInstruction(Opcode.XORM, vmDt, reg1=regMask, value = knownAddress)
else
IRCodeInstruction(Opcode.XORM, vmDt, reg1=regMask, labelSymbol = addressSymbol)
IRInstruction(Opcode.XORM, vmDt, reg1=regMask, labelSymbol = addressSymbol)
}
else -> throw AssemblyError("weird prefix operator")
}
@ -192,12 +192,12 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
if(ident!=null) {
val symbol = ident.targetName.joinToString(".")
code += if(zero) {
IRCodeInstruction(Opcode.STOREZM, vmDt, labelSymbol = symbol)
IRInstruction(Opcode.STOREZM, vmDt, labelSymbol = symbol)
} else {
if (vmDt == VmDataType.FLOAT)
IRCodeInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = symbol)
IRInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = symbol)
else
IRCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = symbol)
IRInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = symbol)
}
}
else if(array!=null) {
@ -215,9 +215,9 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
if(zero) {
// there's no STOREZIX instruction
resultRegister = codeGen.vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=0)
code += IRInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=0)
}
code += IRCodeInstruction(Opcode.STOREIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = variable)
code += IRInstruction(Opcode.STOREIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = variable)
return code
}
@ -225,30 +225,30 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
if(zero) {
if(fixedIndex!=null) {
val offset = fixedIndex*itemsize
code += IRCodeInstruction(Opcode.STOREZM, vmDt, labelSymbol = "$variable+$offset")
code += IRInstruction(Opcode.STOREZM, vmDt, labelSymbol = "$variable+$offset")
} else {
val indexReg = codeGen.vmRegisters.nextFree()
code += loadIndexReg(array, itemsize, indexReg, array.position)
code += IRCodeInstruction(Opcode.STOREZX, vmDt, reg1=indexReg, labelSymbol = variable)
code += IRInstruction(Opcode.STOREZX, vmDt, reg1=indexReg, labelSymbol = variable)
}
} else {
if(vmDt== VmDataType.FLOAT) {
if(fixedIndex!=null) {
val offset = fixedIndex*itemsize
code += IRCodeInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = "$variable+$offset")
code += IRInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = "$variable+$offset")
} else {
val indexReg = codeGen.vmRegisters.nextFree()
code += loadIndexReg(array, itemsize, indexReg, array.position)
code += IRCodeInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variable)
code += IRInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variable)
}
} else {
if(fixedIndex!=null) {
val offset = fixedIndex*itemsize
code += IRCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = "$variable+$offset")
code += IRInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = "$variable+$offset")
} else {
val indexReg = codeGen.vmRegisters.nextFree()
code += loadIndexReg(array, itemsize, indexReg, array.position)
code += IRCodeInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variable)
code += IRInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variable)
}
}
}
@ -257,19 +257,19 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
require(vmDt== VmDataType.BYTE)
if(zero) {
if(memory.address is PtNumber) {
code += IRCodeInstruction(Opcode.STOREZM, vmDt, value=(memory.address as PtNumber).number.toInt())
code += IRInstruction(Opcode.STOREZM, vmDt, value=(memory.address as PtNumber).number.toInt())
} else {
val addressReg = codeGen.vmRegisters.nextFree()
code += expressionEval.translateExpression(memory.address, addressReg, -1)
code += IRCodeInstruction(Opcode.STOREZI, vmDt, reg1=addressReg)
code += IRInstruction(Opcode.STOREZI, vmDt, reg1=addressReg)
}
} else {
if(memory.address is PtNumber) {
code += IRCodeInstruction(Opcode.STOREM, vmDt, reg1=resultRegister, value=(memory.address as PtNumber).number.toInt())
code += IRInstruction(Opcode.STOREM, vmDt, reg1=resultRegister, value=(memory.address as PtNumber).number.toInt())
} else {
val addressReg = codeGen.vmRegisters.nextFree()
code += expressionEval.translateExpression(memory.address, addressReg, -1)
code += IRCodeInstruction(Opcode.STOREI, vmDt, reg1=resultRegister, reg2=addressReg)
code += IRInstruction(Opcode.STOREI, vmDt, reg1=resultRegister, reg2=addressReg)
}
}
}

View File

@ -55,7 +55,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val rightRegister = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args[0], leftRegister, -1)
code += exprGen.translateExpression(call.args[1], rightRegister, -1)
code += IRCodeInstruction(Opcode.CMP, codeGen.vmType(call.args[0].type), reg1=leftRegister, reg2=rightRegister)
code += IRInstruction(Opcode.CMP, codeGen.vmType(call.args[0].type), reg1=leftRegister, reg2=rightRegister)
return code
}
@ -73,10 +73,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
else -> throw IllegalArgumentException("weird type")
}
code += exprGen.translateExpression(call.args[0], 0, -1)
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1 = 1, value = array.length)
code += IRCodeInstruction(Opcode.SYSCALL, value = syscall.ordinal)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1 = 1, value = array.length)
code += IRInstruction(Opcode.SYSCALL, value = syscall.ordinal)
if (resultRegister != 0)
code += IRCodeInstruction(Opcode.LOADR, VmDataType.BYTE, reg1 = resultRegister, reg2 = 0)
code += IRInstruction(Opcode.LOADR, VmDataType.BYTE, reg1 = resultRegister, reg2 = 0)
return code
}
@ -94,10 +94,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
}
val code = IRCodeChunk(call.position)
code += exprGen.translateExpression(call.args[0], 0, -1)
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
code += IRCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
code += IRInstruction(Opcode.SYSCALL, value=syscall.ordinal)
if(resultRegister!=0)
code += IRCodeInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=resultRegister, reg2=0)
code += IRInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=resultRegister, reg2=0)
return code
}
@ -108,25 +108,25 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
code += exprGen.translateExpression(call.args[0], resultRegister, -1)
when (sourceDt) {
DataType.UBYTE -> {
code += IRCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister)
code += IRInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister)
}
DataType.BYTE -> {
val notNegativeLabel = codeGen.createLabelName()
val compareReg = codeGen.vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=compareReg, reg2=resultRegister)
code += IRCodeInstruction(Opcode.AND, VmDataType.BYTE, reg1=compareReg, value=0x80)
code += IRCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=compareReg, labelSymbol = notNegativeLabel)
code += IRCodeInstruction(Opcode.NEG, VmDataType.BYTE, reg1=resultRegister)
code += IRCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister)
code += IRInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=compareReg, reg2=resultRegister)
code += IRInstruction(Opcode.AND, VmDataType.BYTE, reg1=compareReg, value=0x80)
code += IRInstruction(Opcode.BZ, VmDataType.BYTE, reg1=compareReg, labelSymbol = notNegativeLabel)
code += IRInstruction(Opcode.NEG, VmDataType.BYTE, reg1=resultRegister)
code += IRInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister)
code += IRCodeLabel(notNegativeLabel)
}
DataType.WORD -> {
val notNegativeLabel = codeGen.createLabelName()
val compareReg = codeGen.vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOADR, VmDataType.WORD, reg1=compareReg, reg2=resultRegister)
code += IRCodeInstruction(Opcode.AND, VmDataType.WORD, reg1=compareReg, value=0x8000)
code += IRCodeInstruction(Opcode.BZ, VmDataType.WORD, reg1=compareReg, labelSymbol = notNegativeLabel)
code += IRCodeInstruction(Opcode.NEG, VmDataType.WORD, reg1=resultRegister)
code += IRInstruction(Opcode.LOADR, VmDataType.WORD, reg1=compareReg, reg2=resultRegister)
code += IRInstruction(Opcode.AND, VmDataType.WORD, reg1=compareReg, value=0x8000)
code += IRInstruction(Opcode.BZ, VmDataType.WORD, reg1=compareReg, labelSymbol = notNegativeLabel)
code += IRInstruction(Opcode.NEG, VmDataType.WORD, reg1=resultRegister)
code += IRCodeLabel(notNegativeLabel)
}
else -> throw AssemblyError("weird type")
@ -139,7 +139,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val code = IRCodeChunk(call.position)
val reg = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args.single(), reg, -1)
code += IRCodeInstruction(Opcode.SGN, codeGen.vmType(call.type), reg1=resultRegister, reg2=reg)
code += IRInstruction(Opcode.SGN, codeGen.vmType(call.type), reg1=resultRegister, reg2=reg)
return code
}
@ -147,14 +147,14 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val code = IRCodeChunk(call.position)
val reg = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args.single(), reg, -1)
code += IRCodeInstruction(Opcode.SQRT, VmDataType.WORD, reg1=resultRegister, reg2=reg)
code += IRInstruction(Opcode.SQRT, VmDataType.WORD, reg1=resultRegister, reg2=reg)
return code
}
private fun funcPop(call: PtBuiltinFunctionCall): IRCodeChunk {
val code = IRCodeChunk(call.position)
val reg = codeGen.vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.POP, VmDataType.BYTE, reg1=reg)
code += IRInstruction(Opcode.POP, VmDataType.BYTE, reg1=reg)
code += assignRegisterTo(call.args.single(), reg)
return code
}
@ -162,7 +162,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
private fun funcPopw(call: PtBuiltinFunctionCall): IRCodeChunk {
val code = IRCodeChunk(call.position)
val reg = codeGen.vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.POP, VmDataType.WORD, reg1=reg)
code += IRInstruction(Opcode.POP, VmDataType.WORD, reg1=reg)
code += assignRegisterTo(call.args.single(), reg)
return code
}
@ -171,7 +171,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val code = IRCodeChunk(call.position)
val reg = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args.single(), reg, -1)
code += IRCodeInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=reg)
code += IRInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=reg)
return code
}
@ -179,7 +179,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val code = IRCodeChunk(call.position)
val reg = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args.single(), reg, -1)
code += IRCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1=reg)
code += IRInstruction(Opcode.PUSH, VmDataType.WORD, reg1=reg)
return code
}
@ -195,8 +195,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
}
val code = IRCodeChunk(call.position)
code += exprGen.translateExpression(call.args[0], 0, -1)
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
code += IRCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
code += IRInstruction(Opcode.SYSCALL, value=syscall.ordinal)
return code
}
@ -215,8 +215,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
}
val code = IRCodeChunk(call.position)
code += exprGen.translateExpression(call.args[0], 0, -1)
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
code += IRCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
code += IRInstruction(Opcode.SYSCALL, value=syscall.ordinal)
return code
}
@ -225,7 +225,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val code = IRCodeChunk(call.position)
code += exprGen.translateExpression(call.args[0], msbReg, -1)
code += exprGen.translateExpression(call.args[1], resultRegister, -1)
code += IRCodeInstruction(Opcode.CONCAT, VmDataType.BYTE, reg1=resultRegister, reg2=msbReg)
code += IRInstruction(Opcode.CONCAT, VmDataType.BYTE, reg1=resultRegister, reg2=msbReg)
return code
}
@ -234,23 +234,23 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
if(codeGen.isZero(call.args[1])) {
if (call.args[0] is PtNumber) {
val address = (call.args[0] as PtNumber).number.toInt()
code += IRCodeInstruction(Opcode.STOREZM, VmDataType.WORD, value = address)
code += IRInstruction(Opcode.STOREZM, VmDataType.WORD, value = address)
} else {
val addressReg = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args[0], addressReg, -1)
code += IRCodeInstruction(Opcode.STOREZI, VmDataType.WORD, reg2 = addressReg)
code += IRInstruction(Opcode.STOREZI, VmDataType.WORD, reg2 = addressReg)
}
} else {
val valueReg = codeGen.vmRegisters.nextFree()
if (call.args[0] is PtNumber) {
val address = (call.args[0] as PtNumber).number.toInt()
code += exprGen.translateExpression(call.args[1], valueReg, -1)
code += IRCodeInstruction(Opcode.STOREM, VmDataType.WORD, reg1 = valueReg, value = address)
code += IRInstruction(Opcode.STOREM, VmDataType.WORD, reg1 = valueReg, value = address)
} else {
val addressReg = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args[0], addressReg, -1)
code += exprGen.translateExpression(call.args[1], valueReg, -1)
code += IRCodeInstruction(Opcode.STOREI, VmDataType.WORD, reg1 = valueReg, reg2 = addressReg)
code += IRInstruction(Opcode.STOREI, VmDataType.WORD, reg1 = valueReg, reg2 = addressReg)
}
}
return code
@ -261,23 +261,23 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
if(codeGen.isZero(call.args[1])) {
if (call.args[0] is PtNumber) {
val address = (call.args[0] as PtNumber).number.toInt()
code += IRCodeInstruction(Opcode.STOREZM, VmDataType.BYTE, value = address)
code += IRInstruction(Opcode.STOREZM, VmDataType.BYTE, value = address)
} else {
val addressReg = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args[0], addressReg, -1)
code += IRCodeInstruction(Opcode.STOREZI, VmDataType.BYTE, reg2 = addressReg)
code += IRInstruction(Opcode.STOREZI, VmDataType.BYTE, reg2 = addressReg)
}
} else {
val valueReg = codeGen.vmRegisters.nextFree()
if (call.args[0] is PtNumber) {
val address = (call.args[0] as PtNumber).number.toInt()
code += exprGen.translateExpression(call.args[1], valueReg, -1)
code += IRCodeInstruction(Opcode.STOREM, VmDataType.BYTE, reg1 = valueReg, value = address)
code += IRInstruction(Opcode.STOREM, VmDataType.BYTE, reg1 = valueReg, value = address)
} else {
val addressReg = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args[0], addressReg, -1)
code += exprGen.translateExpression(call.args[1], valueReg, -1)
code += IRCodeInstruction(Opcode.STOREI, VmDataType.BYTE, reg1 = valueReg, reg2 = addressReg)
code += IRInstruction(Opcode.STOREI, VmDataType.BYTE, reg1 = valueReg, reg2 = addressReg)
}
}
return code
@ -287,11 +287,11 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val code = IRCodeChunk(call.position)
if(call.args[0] is PtNumber) {
val address = (call.args[0] as PtNumber).number.toInt()
code += IRCodeInstruction(Opcode.LOADM, VmDataType.WORD, reg1 = resultRegister, value = address)
code += IRInstruction(Opcode.LOADM, VmDataType.WORD, reg1 = resultRegister, value = address)
} else {
val addressReg = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args.single(), addressReg, -1)
code += IRCodeInstruction(Opcode.LOADI, VmDataType.WORD, reg1 = resultRegister, reg2 = addressReg)
code += IRInstruction(Opcode.LOADI, VmDataType.WORD, reg1 = resultRegister, reg2 = addressReg)
}
return code
}
@ -300,24 +300,24 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val code = IRCodeChunk(call.position)
if(call.args[0] is PtNumber) {
val address = (call.args[0] as PtNumber).number.toInt()
code += IRCodeInstruction(Opcode.LOADM, VmDataType.BYTE, reg1 = resultRegister, value = address)
code += IRInstruction(Opcode.LOADM, VmDataType.BYTE, reg1 = resultRegister, value = address)
} else {
val addressReg = codeGen.vmRegisters.nextFree()
code += exprGen.translateExpression(call.args.single(), addressReg, -1)
code += IRCodeInstruction(Opcode.LOADI, VmDataType.BYTE, reg1 = resultRegister, reg2 = addressReg)
code += IRInstruction(Opcode.LOADI, VmDataType.BYTE, reg1 = resultRegister, reg2 = addressReg)
}
return code
}
private fun funcRnd(resultRegister: Int, position: Position): IRCodeChunk {
val code = IRCodeChunk(position)
code += IRCodeInstruction(Opcode.RND, VmDataType.BYTE, reg1=resultRegister)
code += IRInstruction(Opcode.RND, VmDataType.BYTE, reg1=resultRegister)
return code
}
private fun funcRndw(resultRegister: Int, position: Position): IRCodeChunk {
val code = IRCodeChunk(position)
code += IRCodeInstruction(Opcode.RND, VmDataType.WORD, reg1=resultRegister)
code += IRInstruction(Opcode.RND, VmDataType.WORD, reg1=resultRegister)
return code
}
@ -327,7 +327,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val align = (call.args[2] as PtNumber).number.toUInt()
val label = codeGen.addMemorySlab(name, size, align, call.position)
val code = IRCodeChunk(call.position)
code += IRCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=resultRegister, labelSymbol = label)
code += IRInstruction(Opcode.LOAD, VmDataType.WORD, reg1=resultRegister, labelSymbol = label)
return code
}
@ -341,7 +341,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
private fun funcMsb(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunk {
val code = IRCodeChunk(call.position)
code += exprGen.translateExpression(call.args.single(), resultRegister, -1)
code += IRCodeInstruction(Opcode.MSIG, VmDataType.BYTE, reg1 = resultRegister, reg2=resultRegister)
code += IRInstruction(Opcode.MSIG, VmDataType.BYTE, reg1 = resultRegister, reg2=resultRegister)
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
return code
}
@ -350,7 +350,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val vmDt = codeGen.vmType(call.args[0].type)
val code = IRCodeChunk(call.position)
code += exprGen.translateExpression(call.args[0], resultRegister, -1)
code += IRCodeInstruction(opcode, vmDt, reg1=resultRegister)
code += IRInstruction(opcode, vmDt, reg1=resultRegister)
code += assignRegisterTo(call.args[0], resultRegister)
return code
}

View File

@ -18,43 +18,43 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
is PtMachineRegister -> {
if(resultRegister!=expr.register) {
val vmDt = codeGen.vmType(expr.type)
code += IRCodeInstruction(Opcode.LOADR, vmDt, reg1=resultRegister, reg2=expr.register)
code += IRInstruction(Opcode.LOADR, vmDt, reg1=resultRegister, reg2=expr.register)
}
}
is PtNumber -> {
val vmDt = codeGen.vmType(expr.type)
code += if(vmDt==VmDataType.FLOAT)
IRCodeInstruction(Opcode.LOAD, vmDt, fpReg1 = resultFpRegister, fpValue = expr.number.toFloat())
IRInstruction(Opcode.LOAD, vmDt, fpReg1 = resultFpRegister, fpValue = expr.number.toFloat())
else
IRCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=expr.number.toInt())
IRInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=expr.number.toInt())
}
is PtIdentifier -> {
val vmDt = codeGen.vmType(expr.type)
val symbol = expr.targetName.joinToString(".")
code += if (expr.type in PassByValueDatatypes) {
if(vmDt==VmDataType.FLOAT)
IRCodeInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, labelSymbol = symbol)
IRInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, labelSymbol = symbol)
else
IRCodeInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, labelSymbol = symbol)
IRInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, labelSymbol = symbol)
} else {
// for strings and arrays etc., load the *address* of the value instead
IRCodeInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol)
IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol)
}
}
is PtAddressOf -> {
val vmDt = codeGen.vmType(expr.type)
val symbol = expr.identifier.targetName.joinToString(".")
// note: LOAD <symbol> gets you the address of the symbol, whereas LOADM <symbol> would get you the value stored at that location
code += IRCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, labelSymbol = symbol)
code += IRInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, labelSymbol = symbol)
}
is PtMemoryByte -> {
if(expr.address is PtNumber) {
val address = (expr.address as PtNumber).number.toInt()
code += IRCodeInstruction(Opcode.LOADM, VmDataType.BYTE, reg1=resultRegister, value = address)
code += IRInstruction(Opcode.LOADM, VmDataType.BYTE, reg1=resultRegister, value = address)
} else {
val addressRegister = codeGen.vmRegisters.nextFree()
code += translateExpression(expr.address, addressRegister, -1)
code += IRCodeInstruction(Opcode.LOADI, VmDataType.BYTE, reg1=resultRegister, reg2=addressRegister)
code += IRInstruction(Opcode.LOADI, VmDataType.BYTE, reg1=resultRegister, reg2=addressRegister)
}
}
is PtTypeCast -> code += translate(expr, resultRegister, resultFpRegister)
@ -117,24 +117,24 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(arrayIx.index.type!=DataType.UBYTE)
throw AssemblyError("non-array var indexing requires bytes index")
code += translateExpression(arrayIx.index, idxReg, -1)
code += IRCodeInstruction(Opcode.LOADIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol)
code += IRInstruction(Opcode.LOADIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol)
return code
}
if(arrayIx.index is PtNumber) {
val memOffset = ((arrayIx.index as PtNumber).number.toInt() * eltSize).toString()
if(vmDt==VmDataType.FLOAT)
code += IRCodeInstruction(Opcode.LOADM, VmDataType.FLOAT, fpReg1=resultFpRegister, labelSymbol = "$arrayVarSymbol+$memOffset")
code += IRInstruction(Opcode.LOADM, VmDataType.FLOAT, fpReg1=resultFpRegister, labelSymbol = "$arrayVarSymbol+$memOffset")
else
code += IRCodeInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, labelSymbol = "$arrayVarSymbol+$memOffset")
code += IRInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, labelSymbol = "$arrayVarSymbol+$memOffset")
} else {
code += translateExpression(arrayIx.index, idxReg, -1)
if(eltSize>1)
code += codeGen.multiplyByConst(VmDataType.BYTE, idxReg, eltSize, arrayIx.position)
if(vmDt==VmDataType.FLOAT)
code += IRCodeInstruction(Opcode.LOADX, VmDataType.FLOAT, fpReg1 = resultFpRegister, reg1=idxReg, labelSymbol = arrayVarSymbol)
code += IRInstruction(Opcode.LOADX, VmDataType.FLOAT, fpReg1 = resultFpRegister, reg1=idxReg, labelSymbol = arrayVarSymbol)
else
code += IRCodeInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol)
code += IRInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol)
}
return code
}
@ -146,11 +146,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
when(expr.operator) {
"+" -> { }
"-" -> {
code += IRCodeInstruction(Opcode.NEG, vmDt, reg1=resultRegister)
code += IRInstruction(Opcode.NEG, vmDt, reg1=resultRegister)
}
"~" -> {
val mask = if(vmDt==VmDataType.BYTE) 0x00ff else 0xffff
code += IRCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, value=mask)
code += IRInstruction(Opcode.XOR, vmDt, reg1=resultRegister, value=mask)
}
else -> throw AssemblyError("weird prefix operator")
}
@ -173,14 +173,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
DataType.UBYTE -> {
when(cast.value.type) {
DataType.BYTE, DataType.UWORD, DataType.WORD -> { /* just keep the LSB as it is */ }
DataType.FLOAT -> code += IRCodeInstruction(Opcode.FTOUB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
DataType.FLOAT -> code += IRInstruction(Opcode.FTOUB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
else -> throw AssemblyError("weird cast value type")
}
}
DataType.BYTE -> {
when(cast.value.type) {
DataType.UBYTE, DataType.UWORD, DataType.WORD -> { /* just keep the LSB as it is */ }
DataType.FLOAT -> code += IRCodeInstruction(Opcode.FTOSB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
DataType.FLOAT -> code += IRInstruction(Opcode.FTOSB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
else -> throw AssemblyError("weird cast value type")
}
}
@ -188,15 +188,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
when(cast.value.type) {
DataType.BYTE -> {
// byte -> uword: sign extend
code += IRCodeInstruction(Opcode.EXTS, type = VmDataType.BYTE, reg1 = actualResultReg)
code += IRInstruction(Opcode.EXTS, type = VmDataType.BYTE, reg1 = actualResultReg)
}
DataType.UBYTE -> {
// ubyte -> uword: sign extend
code += IRCodeInstruction(Opcode.EXT, type = VmDataType.BYTE, reg1 = actualResultReg)
code += IRInstruction(Opcode.EXT, type = VmDataType.BYTE, reg1 = actualResultReg)
}
DataType.WORD -> { }
DataType.FLOAT -> {
code += IRCodeInstruction(Opcode.FTOUW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
code += IRInstruction(Opcode.FTOUW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
else -> throw AssemblyError("weird cast value type")
}
@ -205,15 +205,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
when(cast.value.type) {
DataType.BYTE -> {
// byte -> word: sign extend
code += IRCodeInstruction(Opcode.EXTS, type = VmDataType.BYTE, reg1 = actualResultReg)
code += IRInstruction(Opcode.EXTS, type = VmDataType.BYTE, reg1 = actualResultReg)
}
DataType.UBYTE -> {
// byte -> word: sign extend
code += IRCodeInstruction(Opcode.EXT, type = VmDataType.BYTE, reg1 = actualResultReg)
code += IRInstruction(Opcode.EXT, type = VmDataType.BYTE, reg1 = actualResultReg)
}
DataType.UWORD -> { }
DataType.FLOAT -> {
code += IRCodeInstruction(Opcode.FTOSW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
code += IRInstruction(Opcode.FTOSW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
else -> throw AssemblyError("weird cast value type")
}
@ -221,16 +221,16 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
DataType.FLOAT -> {
code += when(cast.value.type) {
DataType.UBYTE -> {
IRCodeInstruction(Opcode.FFROMUB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
IRInstruction(Opcode.FFROMUB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
DataType.BYTE -> {
IRCodeInstruction(Opcode.FFROMSB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
IRInstruction(Opcode.FFROMSB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
DataType.UWORD -> {
IRCodeInstruction(Opcode.FFROMUW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
IRInstruction(Opcode.FFROMUW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
DataType.WORD -> {
IRCodeInstruction(Opcode.FFROMSW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
IRInstruction(Opcode.FFROMSW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
else -> throw AssemblyError("weird cast value type")
}
@ -278,14 +278,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val zeroRegister = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, -1, leftFpReg)
code += translateExpression(binExpr.right, -1, rightFpReg)
code += IRCodeInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0)
code += IRInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0)
val ins = if (signed) {
if (greaterEquals) Opcode.SGES else Opcode.SGTS
} else {
if (greaterEquals) Opcode.SGE else Opcode.SGT
}
code += IRCodeInstruction(ins, VmDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister)
code += IRInstruction(ins, VmDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister)
} else {
if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) {
val comparisonCall = PtFunctionCall(listOf("prog8_lib", "string_compare"), false, DataType.BYTE, Position.DUMMY)
@ -293,11 +293,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
comparisonCall.children.add(binExpr.right)
code += translate(comparisonCall, resultRegister, -1)
val zeroRegister = codeGen.vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0)
code += if(greaterEquals)
IRCodeInstruction(Opcode.SGES, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
IRInstruction(Opcode.SGES, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
else
IRCodeInstruction(Opcode.SGTS, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
IRInstruction(Opcode.SGTS, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
} else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
@ -307,7 +307,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} else {
if (greaterEquals) Opcode.SGE else Opcode.SGT
}
code += IRCodeInstruction(ins, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(ins, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
return code
@ -327,14 +327,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val zeroRegister = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, -1, leftFpReg)
code += translateExpression(binExpr.right, -1, rightFpReg)
code += IRCodeInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0)
code += IRInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0)
val ins = if (signed) {
if (lessEquals) Opcode.SLES else Opcode.SLTS
} else {
if (lessEquals) Opcode.SLE else Opcode.SLT
}
code += IRCodeInstruction(ins, VmDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister)
code += IRInstruction(ins, VmDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister)
} else {
if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) {
val comparisonCall = PtFunctionCall(listOf("prog8_lib", "string_compare"), false, DataType.BYTE, Position.DUMMY)
@ -342,11 +342,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
comparisonCall.children.add(binExpr.right)
code += translate(comparisonCall, resultRegister, -1)
val zeroRegister = codeGen.vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0)
code += if(lessEquals)
IRCodeInstruction(Opcode.SLES, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
IRInstruction(Opcode.SLES, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
else
IRCodeInstruction(Opcode.SLTS, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
IRInstruction(Opcode.SLTS, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
} else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
@ -356,7 +356,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} else {
if (lessEquals) Opcode.SLE else Opcode.SLT
}
code += IRCodeInstruction(ins, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(ins, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
return code
@ -370,14 +370,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
code += translateExpression(binExpr.left, -1, leftFpReg)
code += translateExpression(binExpr.right, -1, rightFpReg)
if (notEquals) {
code += IRCodeInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
code += IRInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
} else {
val label = codeGen.createLabelName()
val valueReg = codeGen.vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=resultRegister, value=1)
code += IRCodeInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=valueReg, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
code += IRCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=valueReg, labelSymbol = label)
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=resultRegister, value=0)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=resultRegister, value=1)
code += IRInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=valueReg, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
code += IRInstruction(Opcode.BZ, VmDataType.BYTE, reg1=valueReg, labelSymbol = label)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=resultRegister, value=0)
code += IRCodeLabel(label)
}
} else {
@ -387,14 +387,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
comparisonCall.children.add(binExpr.right)
code += translate(comparisonCall, resultRegister, -1)
if(!notEquals)
code += IRCodeInstruction(Opcode.INV, vmDt, reg1=resultRegister)
code += IRCodeInstruction(Opcode.AND, vmDt, reg1=resultRegister, value=1)
code += IRInstruction(Opcode.INV, vmDt, reg1=resultRegister)
code += IRInstruction(Opcode.AND, vmDt, reg1=resultRegister, value=1)
} else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
val opcode = if (notEquals) Opcode.SNE else Opcode.SEQ
code += IRCodeInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
return code
@ -405,13 +405,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(codeGen.isOne(binExpr.right)) {
code += translateExpression(binExpr.left, resultRegister, -1)
val opc = if (signed) Opcode.ASR else Opcode.LSR
code += IRCodeInstruction(opc, vmDt, reg1 = resultRegister)
code += IRInstruction(opc, vmDt, reg1 = resultRegister)
} else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
val opc = if (signed) Opcode.ASRN else Opcode.LSRN
code += IRCodeInstruction(opc, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(opc, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
return code
}
@ -421,17 +421,17 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(codeGen.isOne(operand)) {
val opc = if (signed) Opcode.ASRM else Opcode.LSRM
code += if(knownAddress!=null)
IRCodeInstruction(opc, vmDt, value=knownAddress)
IRInstruction(opc, vmDt, value=knownAddress)
else
IRCodeInstruction(opc, vmDt, labelSymbol = symbol)
IRInstruction(opc, vmDt, labelSymbol = symbol)
} else {
val operandReg = codeGen.vmRegisters.nextFree()
code += translateExpression(operand, operandReg, -1)
val opc = if (signed) Opcode.ASRNM else Opcode.LSRNM
code += if(knownAddress!=null)
IRCodeInstruction(opc, vmDt, reg1 = operandReg, value=knownAddress)
IRInstruction(opc, vmDt, reg1 = operandReg, value=knownAddress)
else
IRCodeInstruction(opc, vmDt, reg1 = operandReg, labelSymbol = symbol)
IRInstruction(opc, vmDt, reg1 = operandReg, labelSymbol = symbol)
}
return code
}
@ -440,12 +440,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val code = IRCodeChunk(binExpr.position)
if(codeGen.isOne(binExpr.right)){
code += translateExpression(binExpr.left, resultRegister, -1)
code += IRCodeInstruction(Opcode.LSL, vmDt, reg1=resultRegister)
code += IRInstruction(Opcode.LSL, vmDt, reg1=resultRegister)
} else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += IRCodeInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, rightResultReg)
code += IRInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, rightResultReg)
}
return code
}
@ -454,16 +454,16 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val code = IRCodeChunk(operand.position)
if(codeGen.isOne(operand)){
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.LSLM, vmDt, value=knownAddress)
IRInstruction(Opcode.LSLM, vmDt, value=knownAddress)
else
IRCodeInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol)
IRInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol)
} else {
val operandReg = codeGen.vmRegisters.nextFree()
code += translateExpression(operand, operandReg, -1)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, value=knownAddress)
IRInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, value=knownAddress)
else
IRCodeInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, labelSymbol = symbol)
IRInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, labelSymbol = symbol)
}
return code
}
@ -472,12 +472,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val code = IRCodeChunk(binExpr.position)
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += IRCodeInstruction(Opcode.XOR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
code += IRInstruction(Opcode.XOR, 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 += IRCodeInstruction(Opcode.XORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(Opcode.XORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
return code
}
@ -487,9 +487,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val operandReg = codeGen.vmRegisters.nextFree()
code += translateExpression(operand, operandReg, -1)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.XORM, vmDt, reg1=operandReg, value = knownAddress)
IRInstruction(Opcode.XORM, vmDt, reg1=operandReg, value = knownAddress)
else
IRCodeInstruction(Opcode.XORM, vmDt, reg1=operandReg, labelSymbol = symbol)
IRInstruction(Opcode.XORM, vmDt, reg1=operandReg, labelSymbol = symbol)
return code
}
@ -497,12 +497,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val code = IRCodeChunk(binExpr.position)
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += IRCodeInstruction(Opcode.AND, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
code += IRInstruction(Opcode.AND, 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 += IRCodeInstruction(Opcode.ANDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(Opcode.ANDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
return code
}
@ -512,9 +512,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val operandReg = codeGen.vmRegisters.nextFree()
code += translateExpression(operand, operandReg, -1)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.ANDM, vmDt, reg1=operandReg, value=knownAddress)
IRInstruction(Opcode.ANDM, vmDt, reg1=operandReg, value=knownAddress)
else
IRCodeInstruction(Opcode.ANDM, vmDt, reg1=operandReg, labelSymbol = symbol)
IRInstruction(Opcode.ANDM, vmDt, reg1=operandReg, labelSymbol = symbol)
return code
}
@ -522,12 +522,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val code = IRCodeChunk(binExpr.position)
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += IRCodeInstruction(Opcode.OR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
code += IRInstruction(Opcode.OR, 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 += IRCodeInstruction(Opcode.ORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(Opcode.ORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
return code
}
@ -537,9 +537,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val operandReg = codeGen.vmRegisters.nextFree()
code += translateExpression(operand, operandReg, -1)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.ORM, vmDt, reg1=operandReg, value = knownAddress)
IRInstruction(Opcode.ORM, vmDt, reg1=operandReg, value = knownAddress)
else
IRCodeInstruction(Opcode.ORM, vmDt, reg1=operandReg, labelSymbol = symbol)
IRInstruction(Opcode.ORM, vmDt, reg1=operandReg, labelSymbol = symbol)
return code
}
@ -550,11 +550,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += IRCodeInstruction(Opcode.MOD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
code += IRInstruction(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 += IRCodeInstruction(Opcode.MODR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(Opcode.MODR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
return code
}
@ -576,9 +576,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += translateExpression(binExpr.right, -1, rightResultFpReg)
code += if(signed)
IRCodeInstruction(Opcode.DIVSR, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
IRInstruction(Opcode.DIVSR, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
else
IRCodeInstruction(Opcode.DIVR, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
IRInstruction(Opcode.DIVR, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
}
} else {
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
@ -590,16 +590,16 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += if (signed)
IRCodeInstruction(Opcode.DIVS, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
IRInstruction(Opcode.DIVS, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
else
IRCodeInstruction(Opcode.DIV, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
IRInstruction(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)
IRCodeInstruction(Opcode.DIVSR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
IRInstruction(Opcode.DIVSR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
else
IRCodeInstruction(Opcode.DIVR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
IRInstruction(Opcode.DIVR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
}
@ -618,15 +618,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
code += translateExpression(operand, -1, operandFpReg)
code += if(signed) {
if(knownAddress!=null)
IRCodeInstruction(Opcode.DIVSM, vmDt, fpReg1 = operandFpReg, value = knownAddress)
IRInstruction(Opcode.DIVSM, vmDt, fpReg1 = operandFpReg, value = knownAddress)
else
IRCodeInstruction(Opcode.DIVSM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol)
IRInstruction(Opcode.DIVSM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRCodeInstruction(Opcode.DIVM, vmDt, fpReg1 = operandFpReg, value = knownAddress)
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = operandFpReg, value = knownAddress)
else
IRCodeInstruction(Opcode.DIVM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol)
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol)
}
}
} else {
@ -638,15 +638,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
code += translateExpression(operand, operandReg, -1)
code += if(signed) {
if(knownAddress!=null)
IRCodeInstruction(Opcode.DIVSM, vmDt, reg1 = operandReg, value = knownAddress)
IRInstruction(Opcode.DIVSM, vmDt, reg1 = operandReg, value = knownAddress)
else
IRCodeInstruction(Opcode.DIVSM, vmDt, reg1 = operandReg, labelSymbol = symbol)
IRInstruction(Opcode.DIVSM, vmDt, reg1 = operandReg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRCodeInstruction(Opcode.DIVM, vmDt, reg1 = operandReg, value = knownAddress)
IRInstruction(Opcode.DIVM, vmDt, reg1 = operandReg, value = knownAddress)
else
IRCodeInstruction(Opcode.DIVM, vmDt, reg1 = operandReg, labelSymbol = symbol)
IRInstruction(Opcode.DIVM, vmDt, reg1 = operandReg, labelSymbol = symbol)
}
}
}
@ -670,7 +670,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += translateExpression(binExpr.right, -1, rightResultFpReg)
code += IRCodeInstruction(Opcode.MULR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg)
code += IRInstruction(Opcode.MULR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg)
}
} else {
if(constFactorLeft!=null && constFactorLeft.type!=DataType.FLOAT) {
@ -685,7 +685,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += IRCodeInstruction(Opcode.MULR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(Opcode.MULR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
return code
@ -702,9 +702,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val operandFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(operand, -1, operandFpReg)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, value = knownAddress)
IRInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, value = knownAddress)
else
IRCodeInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol)
IRInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol)
}
} else {
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
@ -714,9 +714,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val operandReg = codeGen.vmRegisters.nextFree()
code += translateExpression(operand, operandReg, -1)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.MULM, vmDt, reg1=operandReg, value = knownAddress)
IRInstruction(Opcode.MULM, vmDt, reg1=operandReg, value = knownAddress)
else
IRCodeInstruction(Opcode.MULM, vmDt, reg1=operandReg, labelSymbol = symbol)
IRInstruction(Opcode.MULM, vmDt, reg1=operandReg, labelSymbol = symbol)
}
}
return code
@ -727,33 +727,33 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(vmDt==VmDataType.FLOAT) {
if((binExpr.right as? PtNumber)?.number==1.0) {
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += IRCodeInstruction(Opcode.DEC, vmDt, fpReg1 = resultFpRegister)
code += IRInstruction(Opcode.DEC, vmDt, fpReg1 = resultFpRegister)
}
else {
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += IRCodeInstruction(Opcode.SUB, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat())
code += IRInstruction(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 += IRCodeInstruction(Opcode.SUBR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg)
code += IRInstruction(Opcode.SUBR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg)
}
}
} else {
if((binExpr.right as? PtNumber)?.number==1.0) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += IRCodeInstruction(Opcode.DEC, vmDt, reg1=resultRegister)
code += IRInstruction(Opcode.DEC, vmDt, reg1=resultRegister)
}
else {
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += IRCodeInstruction(Opcode.SUB, vmDt, reg1 = resultRegister, value = (binExpr.right as PtNumber).number.toInt())
code += IRInstruction(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 += IRCodeInstruction(Opcode.SUBR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(Opcode.SUBR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
}
@ -765,32 +765,32 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(vmDt==VmDataType.FLOAT) {
if((operand as? PtNumber)?.number==1.0) {
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.DECM, vmDt, value=knownAddress)
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
else
IRCodeInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
}
else {
val operandFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(operand, -1, operandFpReg)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, value=knownAddress)
IRInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, value=knownAddress)
else
IRCodeInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, labelSymbol = symbol)
IRInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, labelSymbol = symbol)
}
} else {
if((operand as? PtNumber)?.number==1.0) {
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.DECM, vmDt, value=knownAddress)
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
else
IRCodeInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
}
else {
val operandReg = codeGen.vmRegisters.nextFree()
code += translateExpression(operand, operandReg, -1)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.SUBM, vmDt, reg1=operandReg, value = knownAddress)
IRInstruction(Opcode.SUBM, vmDt, reg1=operandReg, value = knownAddress)
else
IRCodeInstruction(Opcode.SUBM, vmDt, reg1=operandReg, labelSymbol = symbol)
IRInstruction(Opcode.SUBM, vmDt, reg1=operandReg, labelSymbol = symbol)
}
}
return code
@ -801,41 +801,41 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(vmDt==VmDataType.FLOAT) {
if((binExpr.left as? PtNumber)?.number==1.0) {
code += translateExpression(binExpr.right, -1, resultFpRegister)
code += IRCodeInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister)
code += IRInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister)
}
else if((binExpr.right as? PtNumber)?.number==1.0) {
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += IRCodeInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister)
code += IRInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister)
}
else {
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, -1, resultFpRegister)
code += IRCodeInstruction(Opcode.ADD, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat())
code += IRInstruction(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 += IRCodeInstruction(Opcode.ADDR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg)
code += IRInstruction(Opcode.ADDR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg)
}
}
} else {
if((binExpr.left as? PtNumber)?.number==1.0) {
code += translateExpression(binExpr.right, resultRegister, -1)
code += IRCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister)
code += IRInstruction(Opcode.INC, vmDt, reg1=resultRegister)
}
else if((binExpr.right as? PtNumber)?.number==1.0) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += IRCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister)
code += IRInstruction(Opcode.INC, vmDt, reg1=resultRegister)
}
else {
if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += IRCodeInstruction(Opcode.ADD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
code += IRInstruction(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 += IRCodeInstruction(Opcode.ADDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
code += IRInstruction(Opcode.ADDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
}
}
@ -847,32 +847,32 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(vmDt==VmDataType.FLOAT) {
if((operand as? PtNumber)?.number==1.0) {
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.INCM, vmDt, value = knownAddress)
IRInstruction(Opcode.INCM, vmDt, value = knownAddress)
else
IRCodeInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
}
else {
val operandFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(operand, -1, operandFpReg)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, value = knownAddress)
IRInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, value = knownAddress)
else
IRCodeInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, labelSymbol = symbol)
IRInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, labelSymbol = symbol)
}
} else {
if((operand as? PtNumber)?.number==1.0) {
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.INCM, vmDt, value = knownAddress)
IRInstruction(Opcode.INCM, vmDt, value = knownAddress)
else
IRCodeInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
}
else {
val operandReg = codeGen.vmRegisters.nextFree()
code += translateExpression(operand, operandReg, -1)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.ADDM, vmDt, reg1=operandReg, value=knownAddress)
IRInstruction(Opcode.ADDM, vmDt, reg1=operandReg, value=knownAddress)
else
IRCodeInstruction(Opcode.ADDM, vmDt, reg1=operandReg, labelSymbol = symbol)
IRInstruction(Opcode.ADDM, vmDt, reg1=operandReg, labelSymbol = symbol)
}
}
return code
@ -886,29 +886,29 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val paramDt = codeGen.vmType(parameter.type)
val symbol = (fcall.functionName + parameter.name).joinToString(".")
if(codeGen.isZero(arg)) {
code += IRCodeInstruction(Opcode.STOREZM, paramDt, labelSymbol = symbol)
code += IRInstruction(Opcode.STOREZM, paramDt, labelSymbol = symbol)
} else {
if (paramDt == VmDataType.FLOAT) {
val argFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(arg, -1, argFpReg)
code += IRCodeInstruction(Opcode.STOREM, paramDt, fpReg1 = argFpReg, labelSymbol = symbol)
code += IRInstruction(Opcode.STOREM, paramDt, fpReg1 = argFpReg, labelSymbol = symbol)
} else {
val argReg = codeGen.vmRegisters.nextFree()
code += translateExpression(arg, argReg, -1)
code += IRCodeInstruction(Opcode.STOREM, paramDt, reg1 = argReg, labelSymbol = symbol)
code += IRInstruction(Opcode.STOREM, paramDt, reg1 = argReg, labelSymbol = symbol)
}
}
}
code += IRCodeInstruction(Opcode.CALL, labelSymbol=fcall.functionName.joinToString("."))
code += IRInstruction(Opcode.CALL, labelSymbol=fcall.functionName.joinToString("."))
if(fcall.type==DataType.FLOAT) {
if (!fcall.void && resultFpRegister != 0) {
// Call convention: result value is in fr0, so put it in the required register instead.
code += IRCodeInstruction(Opcode.LOADR, VmDataType.FLOAT, fpReg1 = resultFpRegister, fpReg2 = 0)
code += IRInstruction(Opcode.LOADR, VmDataType.FLOAT, fpReg1 = resultFpRegister, fpReg2 = 0)
}
} else {
if (!fcall.void && resultRegister != 0) {
// Call convention: result value is in r0, so put it in the required register instead.
code += IRCodeInstruction(Opcode.LOADR, codeGen.vmType(fcall.type), reg1 = resultRegister, reg2 = 0)
code += IRInstruction(Opcode.LOADR, codeGen.vmType(fcall.type), reg1 = resultRegister, reg2 = 0)
}
}
return code
@ -919,16 +919,16 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val paramDt = codeGen.vmType(parameter.type)
val paramRegStr = if(parameter.register.registerOrPair!=null) parameter.register.registerOrPair.toString() else parameter.register.statusflag.toString()
if(codeGen.isZero(arg)) {
code += IRCodeInstruction(Opcode.STOREZCPU, paramDt, labelSymbol = paramRegStr)
code += IRInstruction(Opcode.STOREZCPU, paramDt, labelSymbol = paramRegStr)
} else {
if (paramDt == VmDataType.FLOAT)
throw AssemblyError("doesn't support float register argument in asm romsub")
val argReg = codeGen.vmRegisters.nextFree()
code += translateExpression(arg, argReg, -1)
code += IRCodeInstruction(Opcode.STORECPU, paramDt, reg1 = argReg, labelSymbol = paramRegStr)
code += IRInstruction(Opcode.STORECPU, paramDt, reg1 = argReg, labelSymbol = paramRegStr)
}
}
code += IRCodeInstruction(Opcode.CALL, value=callTarget.address.toInt())
code += IRInstruction(Opcode.CALL, value=callTarget.address.toInt())
if(!fcall.void) {
if(callTarget.returns.size!=1)
throw AssemblyError("expect precisely 1 return value")
@ -936,7 +936,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
throw AssemblyError("doesn't support float register result in asm romsub")
val returns = callTarget.returns.single()
val regStr = if(returns.registerOrPair!=null) returns.registerOrPair.toString() else returns.statusflag.toString()
code += IRCodeInstruction(Opcode.LOADCPU, codeGen.vmType(fcall.type), reg1=resultRegister, labelSymbol = regStr)
code += IRInstruction(Opcode.LOADCPU, codeGen.vmType(fcall.type), reg1=resultRegister, labelSymbol = regStr)
}
return code
}

View File

@ -64,8 +64,8 @@ class IRCodeGen(
val replacements = mutableListOf<Triple<IRCodeChunkBase, Int, UInt>>()
irProg.blocks.asSequence().flatMap { it.subroutines }.flatMap { it.chunks }.forEach { chunk ->
chunk.lines.withIndex().forEach {
(lineIndex, line)-> if(line is IRCodeInstruction) {
val symbolExpr = line.ins.labelSymbol
(lineIndex, line) -> if(line is IRInstruction) {
val symbolExpr = line.labelSymbol
if(symbolExpr!=null) {
val symbol: String
val index: UInt
@ -87,14 +87,14 @@ class IRCodeGen(
}
replacements.forEach {
val old = it.first.lines[it.second] as IRCodeInstruction
it.first.lines[it.second] = IRCodeInstruction(
old.ins.opcode,
old.ins.type,
old.ins.reg1,
old.ins.reg2,
old.ins.fpReg1,
old.ins.fpReg2,
val old = it.first.lines[it.second] as IRInstruction
it.first.lines[it.second] = IRInstruction(
old.opcode,
old.type,
old.reg1,
old.reg2,
old.fpReg1,
old.fpReg2,
it.third.toInt(),
null,
null
@ -234,7 +234,7 @@ class IRCodeGen(
}
is PtBreakpoint -> {
val chunk = IRCodeChunk(node.position)
chunk += IRCodeInstruction(Opcode.BREAKPOINT)
chunk += IRInstruction(Opcode.BREAKPOINT)
return chunk
}
is PtConditionalBranch -> translate(node)
@ -275,19 +275,19 @@ class IRCodeGen(
val elseLabel = createLabelName()
// note that the branch opcode used is the opposite as the branch condition, because the generated code jumps to the 'else' part
code += when(branch.condition) {
BranchCondition.CS -> IRCodeInstruction(Opcode.BSTCC, labelSymbol = elseLabel)
BranchCondition.CC -> IRCodeInstruction(Opcode.BSTCS, labelSymbol = elseLabel)
BranchCondition.EQ, BranchCondition.Z -> IRCodeInstruction(Opcode.BSTNE, labelSymbol = elseLabel)
BranchCondition.NE, BranchCondition.NZ -> IRCodeInstruction(Opcode.BSTEQ, labelSymbol = elseLabel)
BranchCondition.MI, BranchCondition.NEG -> IRCodeInstruction(Opcode.BSTPOS, labelSymbol = elseLabel)
BranchCondition.PL, BranchCondition.POS -> IRCodeInstruction(Opcode.BSTNEG, labelSymbol = elseLabel)
BranchCondition.CS -> IRInstruction(Opcode.BSTCC, labelSymbol = elseLabel)
BranchCondition.CC -> IRInstruction(Opcode.BSTCS, labelSymbol = elseLabel)
BranchCondition.EQ, BranchCondition.Z -> IRInstruction(Opcode.BSTNE, labelSymbol = elseLabel)
BranchCondition.NE, BranchCondition.NZ -> IRInstruction(Opcode.BSTEQ, labelSymbol = elseLabel)
BranchCondition.MI, BranchCondition.NEG -> IRInstruction(Opcode.BSTPOS, labelSymbol = elseLabel)
BranchCondition.PL, BranchCondition.POS -> IRInstruction(Opcode.BSTNEG, labelSymbol = elseLabel)
BranchCondition.VC,
BranchCondition.VS -> throw AssemblyError("conditional branch ${branch.condition} not supported in vm target due to lack of cpu V flag ${branch.position}")
}
code += translateNode(branch.trueScope)
if(branch.falseScope.children.isNotEmpty()) {
val endLabel = createLabelName()
code += IRCodeInstruction(Opcode.JUMP, labelSymbol = endLabel)
code += IRInstruction(Opcode.JUMP, labelSymbol = endLabel)
code += IRCodeLabel(elseLabel)
code += translateNode(branch.falseScope)
code += IRCodeLabel(endLabel)
@ -314,22 +314,22 @@ class IRCodeGen(
val skipLabel = createLabelName()
val values = choice.values.children.map {it as PtNumber}
if(values.size==1) {
code += IRCodeInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=values[0].number.toInt())
code += IRCodeInstruction(Opcode.BNE, valueDt, reg1=valueReg, reg2=choiceReg, labelSymbol = skipLabel)
code += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=values[0].number.toInt())
code += IRInstruction(Opcode.BNE, valueDt, reg1=valueReg, reg2=choiceReg, labelSymbol = skipLabel)
code += translateNode(choice.statements)
if(choice.statements.children.last() !is PtReturn)
code += IRCodeInstruction(Opcode.JUMP, labelSymbol = endLabel)
code += IRInstruction(Opcode.JUMP, labelSymbol = endLabel)
} else {
val matchLabel = createLabelName()
for (value in values) {
code += IRCodeInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=value.number.toInt())
code += IRCodeInstruction(Opcode.BEQ, valueDt, reg1=valueReg, reg2=choiceReg, labelSymbol = matchLabel)
code += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=value.number.toInt())
code += IRInstruction(Opcode.BEQ, valueDt, reg1=valueReg, reg2=choiceReg, labelSymbol = matchLabel)
}
code += IRCodeInstruction(Opcode.JUMP, labelSymbol = skipLabel)
code += IRInstruction(Opcode.JUMP, labelSymbol = skipLabel)
code += IRCodeLabel(matchLabel)
code += translateNode(choice.statements)
if(choice.statements.children.last() !is PtReturn)
code += IRCodeInstruction(Opcode.JUMP, labelSymbol = endLabel)
code += IRInstruction(Opcode.JUMP, labelSymbol = endLabel)
}
code += IRCodeLabel(skipLabel)
}
@ -359,14 +359,14 @@ class IRCodeGen(
val endLabel = createLabelName()
if(iterableVar.dt==DataType.STR) {
// iterate over a zero-terminated string
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0)
code += IRCodeLabel(loopLabel)
code += IRCodeInstruction(Opcode.LOADX, VmDataType.BYTE, reg1=tmpReg, reg2=indexReg, labelSymbol = symbol)
code += IRCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=tmpReg, labelSymbol = endLabel)
code += IRCodeInstruction(Opcode.STOREM, VmDataType.BYTE, reg1=tmpReg, labelSymbol = loopvarSymbol)
code += IRInstruction(Opcode.LOADX, VmDataType.BYTE, reg1=tmpReg, reg2=indexReg, labelSymbol = symbol)
code += IRInstruction(Opcode.BZ, VmDataType.BYTE, reg1=tmpReg, labelSymbol = endLabel)
code += IRInstruction(Opcode.STOREM, VmDataType.BYTE, reg1=tmpReg, labelSymbol = loopvarSymbol)
code += translateNode(forLoop.statements)
code += IRCodeInstruction(Opcode.INC, VmDataType.BYTE, reg1=indexReg)
code += IRCodeInstruction(Opcode.JUMP, labelSymbol = loopLabel)
code += IRInstruction(Opcode.INC, VmDataType.BYTE, reg1=indexReg)
code += IRInstruction(Opcode.JUMP, labelSymbol = loopLabel)
code += IRCodeLabel(endLabel)
} else {
// iterate over array
@ -375,22 +375,22 @@ class IRCodeGen(
val lengthBytes = iterableVar.length!! * elementSize
if(lengthBytes<256) {
val lengthReg = vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0)
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=lengthReg, value=lengthBytes)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=lengthReg, value=lengthBytes)
code += IRCodeLabel(loopLabel)
code += IRCodeInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol)
code += IRCodeInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
code += IRInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol)
code += IRInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
code += translateNode(forLoop.statements)
code += addConstReg(VmDataType.BYTE, indexReg, elementSize, iterable.position)
code += IRCodeInstruction(Opcode.BNE, VmDataType.BYTE, reg1=indexReg, reg2=lengthReg, labelSymbol = loopLabel)
code += IRInstruction(Opcode.BNE, VmDataType.BYTE, reg1=indexReg, reg2=lengthReg, labelSymbol = loopLabel)
} else if(lengthBytes==256) {
code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0)
code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0)
code += IRCodeLabel(loopLabel)
code += IRCodeInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol)
code += IRCodeInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
code += IRInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol)
code += IRInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
code += translateNode(forLoop.statements)
code += addConstReg(VmDataType.BYTE, indexReg, elementSize, iterable.position)
code += IRCodeInstruction(Opcode.BNZ, VmDataType.BYTE, reg1=indexReg, labelSymbol = loopLabel)
code += IRInstruction(Opcode.BNZ, VmDataType.BYTE, reg1=indexReg, labelSymbol = loopLabel)
} else {
throw AssemblyError("iterator length should never exceed 256")
}
@ -415,13 +415,13 @@ class IRCodeGen(
code += expressionEval.translateExpression(iterable.to, endvalueReg, -1)
code += expressionEval.translateExpression(iterable.from, indexReg, -1)
code += IRCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, labelSymbol=loopvarSymbol)
code += IRInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, labelSymbol=loopvarSymbol)
code += IRCodeLabel(loopLabel)
code += translateNode(forLoop.statements)
code += addConstMem(loopvarDt, null, loopvarSymbol, step, iterable.position)
code += IRCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, labelSymbol = loopvarSymbol)
code += IRInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, labelSymbol = loopvarSymbol)
val branchOpcode = if(loopvar.dt in SignedDatatypes) Opcode.BLES else Opcode.BLE
code += IRCodeInstruction(branchOpcode, loopvarDt, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel)
code += IRInstruction(branchOpcode, loopvarDt, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel)
return code
}
@ -443,20 +443,20 @@ class IRCodeGen(
val endvalueReg: Int
if(rangeEndWrapped!=0) {
endvalueReg = vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, loopvarDt, reg1 = endvalueReg, value = rangeEndWrapped)
code += IRInstruction(Opcode.LOAD, loopvarDt, reg1 = endvalueReg, value = rangeEndWrapped)
} else {
endvalueReg = -1 // not used
}
code += IRCodeInstruction(Opcode.LOAD, loopvarDt, reg1=indexReg, value=rangeStart)
code += IRCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, labelSymbol=loopvarSymbol)
code += IRInstruction(Opcode.LOAD, loopvarDt, reg1=indexReg, value=rangeStart)
code += IRInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, labelSymbol=loopvarSymbol)
code += IRCodeLabel(loopLabel)
code += translateNode(forLoop.statements)
code += addConstMem(loopvarDt, null, loopvarSymbol, step, iterable.position)
code += IRCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, labelSymbol = loopvarSymbol)
code += IRInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, labelSymbol = loopvarSymbol)
code += if(rangeEndWrapped==0) {
IRCodeInstruction(Opcode.BNZ, loopvarDt, reg1 = indexReg, labelSymbol = loopLabel)
IRInstruction(Opcode.BNZ, loopvarDt, reg1 = indexReg, labelSymbol = loopLabel)
} else {
IRCodeInstruction(Opcode.BNE, loopvarDt, reg1 = indexReg, reg2 = endvalueReg, labelSymbol = loopLabel)
IRInstruction(Opcode.BNE, loopvarDt, reg1 = indexReg, reg2 = endvalueReg, labelSymbol = loopLabel)
}
return code
}
@ -466,24 +466,24 @@ class IRCodeGen(
when(value) {
0 -> { /* do nothing */ }
1 -> {
code += IRCodeInstruction(Opcode.INC, dt, reg1=reg)
code += IRInstruction(Opcode.INC, dt, reg1=reg)
}
2 -> {
code += IRCodeInstruction(Opcode.INC, dt, reg1=reg)
code += IRCodeInstruction(Opcode.INC, dt, reg1=reg)
code += IRInstruction(Opcode.INC, dt, reg1=reg)
code += IRInstruction(Opcode.INC, dt, reg1=reg)
}
-1 -> {
code += IRCodeInstruction(Opcode.DEC, dt, reg1=reg)
code += IRInstruction(Opcode.DEC, dt, reg1=reg)
}
-2 -> {
code += IRCodeInstruction(Opcode.DEC, dt, reg1=reg)
code += IRCodeInstruction(Opcode.DEC, dt, reg1=reg)
code += IRInstruction(Opcode.DEC, dt, reg1=reg)
code += IRInstruction(Opcode.DEC, dt, reg1=reg)
}
else -> {
code += if(value>0) {
IRCodeInstruction(Opcode.ADD, dt, reg1 = reg, value=value)
IRInstruction(Opcode.ADD, dt, reg1 = reg, value=value)
} else {
IRCodeInstruction(Opcode.SUB, dt, reg1 = reg, value=-value)
IRInstruction(Opcode.SUB, dt, reg1 = reg, value=-value)
}
}
}
@ -496,49 +496,49 @@ class IRCodeGen(
0 -> { /* do nothing */ }
1 -> {
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.INCM, dt, value=knownAddress.toInt())
IRInstruction(Opcode.INCM, dt, value=knownAddress.toInt())
else
IRCodeInstruction(Opcode.INCM, dt, labelSymbol = symbol)
IRInstruction(Opcode.INCM, dt, labelSymbol = symbol)
}
2 -> {
if(knownAddress!=null) {
code += IRCodeInstruction(Opcode.INCM, dt, value = knownAddress.toInt())
code += IRCodeInstruction(Opcode.INCM, dt, value = knownAddress.toInt())
code += IRInstruction(Opcode.INCM, dt, value = knownAddress.toInt())
code += IRInstruction(Opcode.INCM, dt, value = knownAddress.toInt())
} else {
code += IRCodeInstruction(Opcode.INCM, dt, labelSymbol = symbol)
code += IRCodeInstruction(Opcode.INCM, dt, labelSymbol = symbol)
code += IRInstruction(Opcode.INCM, dt, labelSymbol = symbol)
code += IRInstruction(Opcode.INCM, dt, labelSymbol = symbol)
}
}
-1 -> {
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.DECM, dt, value=knownAddress.toInt())
IRInstruction(Opcode.DECM, dt, value=knownAddress.toInt())
else
IRCodeInstruction(Opcode.DECM, dt, labelSymbol = symbol)
IRInstruction(Opcode.DECM, dt, labelSymbol = symbol)
}
-2 -> {
if(knownAddress!=null) {
code += IRCodeInstruction(Opcode.DECM, dt, value = knownAddress.toInt())
code += IRCodeInstruction(Opcode.DECM, dt, value = knownAddress.toInt())
code += IRInstruction(Opcode.DECM, dt, value = knownAddress.toInt())
code += IRInstruction(Opcode.DECM, dt, value = knownAddress.toInt())
} else {
code += IRCodeInstruction(Opcode.DECM, dt, labelSymbol = symbol)
code += IRCodeInstruction(Opcode.DECM, dt, labelSymbol = symbol)
code += IRInstruction(Opcode.DECM, dt, labelSymbol = symbol)
code += IRInstruction(Opcode.DECM, dt, labelSymbol = symbol)
}
}
else -> {
val valueReg = vmRegisters.nextFree()
if(value>0) {
code += IRCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value=value)
code += IRInstruction(Opcode.LOAD, dt, reg1=valueReg, value=value)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.ADDM, dt, reg1=valueReg, value=knownAddress.toInt())
IRInstruction(Opcode.ADDM, dt, reg1=valueReg, value=knownAddress.toInt())
else
IRCodeInstruction(Opcode.ADDM, dt, reg1=valueReg, labelSymbol = symbol)
IRInstruction(Opcode.ADDM, dt, reg1=valueReg, labelSymbol = symbol)
}
else {
code += IRCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value=-value)
code += IRInstruction(Opcode.LOAD, dt, reg1=valueReg, value=-value)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.SUBM, dt, reg1=valueReg, value=knownAddress.toInt())
IRInstruction(Opcode.SUBM, dt, reg1=valueReg, value=knownAddress.toInt())
else
IRCodeInstruction(Opcode.SUBM, dt, reg1=valueReg, labelSymbol = symbol)
IRInstruction(Opcode.SUBM, dt, reg1=valueReg, labelSymbol = symbol)
}
}
}
@ -550,9 +550,9 @@ class IRCodeGen(
if(factor==1f)
return code
code += if(factor==0f) {
IRCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = 0f)
IRInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = 0f)
} else {
IRCodeInstruction(Opcode.MUL, VmDataType.FLOAT, fpReg1 = fpReg, fpValue=factor)
IRInstruction(Opcode.MUL, VmDataType.FLOAT, fpReg1 = fpReg, fpValue=factor)
}
return code
}
@ -563,16 +563,16 @@ class IRCodeGen(
return code
if(factor==0f) {
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.STOREZM, VmDataType.FLOAT, value = knownAddress)
IRInstruction(Opcode.STOREZM, VmDataType.FLOAT, value = knownAddress)
else
IRCodeInstruction(Opcode.STOREZM, VmDataType.FLOAT, labelSymbol = symbol)
IRInstruction(Opcode.STOREZM, VmDataType.FLOAT, labelSymbol = symbol)
} else {
val factorReg = vmRegisters.nextFreeFloat()
code += IRCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1=factorReg, fpValue = factor)
code += IRInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1=factorReg, fpValue = factor)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.MULM, VmDataType.FLOAT, fpReg1 = factorReg, value = knownAddress)
IRInstruction(Opcode.MULM, VmDataType.FLOAT, fpReg1 = factorReg, value = knownAddress)
else
IRCodeInstruction(Opcode.MULM, VmDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol)
IRInstruction(Opcode.MULM, VmDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol)
}
return code
}
@ -586,18 +586,18 @@ class IRCodeGen(
val pow2 = powersOfTwo.indexOf(factor)
if(pow2==1) {
// just shift 1 bit
code += IRCodeInstruction(Opcode.LSL, dt, reg1=reg)
code += IRInstruction(Opcode.LSL, dt, reg1=reg)
}
else if(pow2>=1) {
// just shift multiple bits
val pow2reg = vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += IRCodeInstruction(Opcode.LSLN, dt, reg1=reg, reg2=pow2reg)
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += IRInstruction(Opcode.LSLN, dt, reg1=reg, reg2=pow2reg)
} else {
code += if (factor == 0) {
IRCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0)
IRInstruction(Opcode.LOAD, dt, reg1=reg, value=0)
} else {
IRCodeInstruction(Opcode.MUL, dt, reg1=reg, value=factor)
IRInstruction(Opcode.MUL, dt, reg1=reg, value=factor)
}
}
return code
@ -611,32 +611,32 @@ class IRCodeGen(
if(pow2==1) {
// just shift 1 bit
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.LSLM, dt, value = knownAddress)
IRInstruction(Opcode.LSLM, dt, value = knownAddress)
else
IRCodeInstruction(Opcode.LSLM, dt, labelSymbol = symbol)
IRInstruction(Opcode.LSLM, dt, labelSymbol = symbol)
}
else if(pow2>=1) {
// just shift multiple bits
val pow2reg = vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.LSLNM, dt, reg1=pow2reg, value=knownAddress)
IRInstruction(Opcode.LSLNM, dt, reg1=pow2reg, value=knownAddress)
else
IRCodeInstruction(Opcode.LSLNM, dt, reg1=pow2reg, labelSymbol = symbol)
IRInstruction(Opcode.LSLNM, dt, reg1=pow2reg, labelSymbol = symbol)
} else {
if (factor == 0) {
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.STOREZM, dt, value=knownAddress)
IRInstruction(Opcode.STOREZM, dt, value=knownAddress)
else
IRCodeInstruction(Opcode.STOREZM, dt, labelSymbol = symbol)
IRInstruction(Opcode.STOREZM, dt, labelSymbol = symbol)
}
else {
val factorReg = vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, dt, reg1=factorReg, value = factor)
code += IRInstruction(Opcode.LOAD, dt, reg1=factorReg, value = factor)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.MULM, dt, reg1=factorReg, value = knownAddress)
IRInstruction(Opcode.MULM, dt, reg1=factorReg, value = knownAddress)
else
IRCodeInstruction(Opcode.MULM, dt, reg1=factorReg, labelSymbol = symbol)
IRInstruction(Opcode.MULM, dt, reg1=factorReg, labelSymbol = symbol)
}
}
return code
@ -647,9 +647,9 @@ class IRCodeGen(
if(factor==1f)
return code
code += if(factor==0f) {
IRCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = Float.MAX_VALUE)
IRInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = Float.MAX_VALUE)
} else {
IRCodeInstruction(Opcode.DIVS, VmDataType.FLOAT, fpReg1 = fpReg, fpValue=factor)
IRInstruction(Opcode.DIVS, VmDataType.FLOAT, fpReg1 = fpReg, fpValue=factor)
}
return code
}
@ -660,18 +660,18 @@ class IRCodeGen(
return code
if(factor==0f) {
val maxvalueReg = vmRegisters.nextFreeFloat()
code += IRCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = maxvalueReg, fpValue = Float.MAX_VALUE)
code += IRInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = maxvalueReg, fpValue = Float.MAX_VALUE)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.STOREM, VmDataType.FLOAT, fpReg1 = maxvalueReg, value=knownAddress)
IRInstruction(Opcode.STOREM, VmDataType.FLOAT, fpReg1 = maxvalueReg, value=knownAddress)
else
IRCodeInstruction(Opcode.STOREM, VmDataType.FLOAT, fpReg1 = maxvalueReg, labelSymbol = symbol)
IRInstruction(Opcode.STOREM, VmDataType.FLOAT, fpReg1 = maxvalueReg, labelSymbol = symbol)
} else {
val factorReg = vmRegisters.nextFreeFloat()
code += IRCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1=factorReg, fpValue = factor)
code += IRInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1=factorReg, fpValue = factor)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.DIVSM, VmDataType.FLOAT, fpReg1 = factorReg, value=knownAddress)
IRInstruction(Opcode.DIVSM, VmDataType.FLOAT, fpReg1 = factorReg, value=knownAddress)
else
IRCodeInstruction(Opcode.DIVSM, VmDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol)
IRInstruction(Opcode.DIVSM, VmDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol)
}
return code
}
@ -682,24 +682,24 @@ class IRCodeGen(
return code
val pow2 = powersOfTwo.indexOf(factor)
if(pow2==1 && !signed) {
code += IRCodeInstruction(Opcode.LSR, dt, reg1=reg) // simple single bit shift
code += IRInstruction(Opcode.LSR, dt, reg1=reg) // simple single bit shift
}
else if(pow2>=1 &&!signed) {
// just shift multiple bits
val pow2reg = vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += if(signed)
IRCodeInstruction(Opcode.ASRN, dt, reg1=reg, reg2=pow2reg)
IRInstruction(Opcode.ASRN, dt, reg1=reg, reg2=pow2reg)
else
IRCodeInstruction(Opcode.LSRN, dt, reg1=reg, reg2=pow2reg)
IRInstruction(Opcode.LSRN, dt, reg1=reg, reg2=pow2reg)
} else {
code += if (factor == 0) {
IRCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
IRInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
} else {
if(signed)
IRCodeInstruction(Opcode.DIVS, dt, reg1=reg, value=factor)
IRInstruction(Opcode.DIVS, dt, reg1=reg, value=factor)
else
IRCodeInstruction(Opcode.DIV, dt, reg1=reg, value=factor)
IRInstruction(Opcode.DIV, dt, reg1=reg, value=factor)
}
}
return code
@ -713,49 +713,49 @@ class IRCodeGen(
if(pow2==1 && !signed) {
// just simple bit shift
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.LSRM, dt, value=knownAddress)
IRInstruction(Opcode.LSRM, dt, value=knownAddress)
else
IRCodeInstruction(Opcode.LSRM, dt, labelSymbol = symbol)
IRInstruction(Opcode.LSRM, dt, labelSymbol = symbol)
}
else if(pow2>=1 && !signed) {
// just shift multiple bits
val pow2reg = vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += if(signed) {
if(knownAddress!=null)
IRCodeInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, value = knownAddress)
IRInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, value = knownAddress)
else
IRCodeInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, labelSymbol = symbol)
IRInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRCodeInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, value = knownAddress)
IRInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, value = knownAddress)
else
IRCodeInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, labelSymbol = symbol)
IRInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, labelSymbol = symbol)
}
} else {
if (factor == 0) {
val reg = vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
code += IRInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
code += if(knownAddress!=null)
IRCodeInstruction(Opcode.STOREM, dt, reg1=reg, value=knownAddress)
IRInstruction(Opcode.STOREM, dt, reg1=reg, value=knownAddress)
else
IRCodeInstruction(Opcode.STOREM, dt, reg1=reg, labelSymbol = symbol)
IRInstruction(Opcode.STOREM, dt, reg1=reg, labelSymbol = symbol)
}
else {
val factorReg = vmRegisters.nextFree()
code += IRCodeInstruction(Opcode.LOAD, dt, reg1=factorReg, value= factor)
code += IRInstruction(Opcode.LOAD, dt, reg1=factorReg, value= factor)
code += if(signed) {
if(knownAddress!=null)
IRCodeInstruction(Opcode.DIVSM, dt, reg1 = factorReg, value = knownAddress)
IRInstruction(Opcode.DIVSM, dt, reg1 = factorReg, value = knownAddress)
else
IRCodeInstruction(Opcode.DIVSM, dt, reg1 = factorReg, labelSymbol = symbol)
IRInstruction(Opcode.DIVSM, dt, reg1 = factorReg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRCodeInstruction(Opcode.DIVM, dt, reg1 = factorReg, value = knownAddress)
IRInstruction(Opcode.DIVM, dt, reg1 = factorReg, value = knownAddress)
else
IRCodeInstruction(Opcode.DIVM, dt, reg1 = factorReg, labelSymbol = symbol)
IRInstruction(Opcode.DIVM, dt, reg1 = factorReg, labelSymbol = symbol)
}
}
}
@ -789,16 +789,16 @@ class IRCodeGen(
// if and else parts
val elseLabel = createLabelName()
val afterIfLabel = createLabelName()
code += IRCodeInstruction(elseBranch, vmDt, reg1=leftReg, reg2=rightReg, labelSymbol = elseLabel)
code += IRInstruction(elseBranch, vmDt, reg1=leftReg, reg2=rightReg, labelSymbol = elseLabel)
code += translateNode(ifElse.ifScope)
code += IRCodeInstruction(Opcode.JUMP, labelSymbol = afterIfLabel)
code += IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel)
code += IRCodeLabel(elseLabel)
code += translateNode(ifElse.elseScope)
code += IRCodeLabel(afterIfLabel)
} else {
// only if part
val afterIfLabel = createLabelName()
code += IRCodeInstruction(elseBranch, vmDt, reg1=leftReg, reg2=rightReg, labelSymbol = afterIfLabel)
code += IRInstruction(elseBranch, vmDt, reg1=leftReg, reg2=rightReg, labelSymbol = afterIfLabel)
code += translateNode(ifElse.ifScope)
code += IRCodeLabel(afterIfLabel)
}
@ -813,16 +813,16 @@ class IRCodeGen(
// if and else parts
val elseLabel = createLabelName()
val afterIfLabel = createLabelName()
code += IRCodeInstruction(elseBranch, vmDt, reg1=leftReg, labelSymbol = elseLabel)
code += IRInstruction(elseBranch, vmDt, reg1=leftReg, labelSymbol = elseLabel)
code += translateNode(ifElse.ifScope)
code += IRCodeInstruction(Opcode.JUMP, labelSymbol = afterIfLabel)
code += IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel)
code += IRCodeLabel(elseLabel)
code += translateNode(ifElse.elseScope)
code += IRCodeLabel(afterIfLabel)
} else {
// only if part
val afterIfLabel = createLabelName()
code += IRCodeInstruction(elseBranch, vmDt, reg1=leftReg, labelSymbol = afterIfLabel)
code += IRInstruction(elseBranch, vmDt, reg1=leftReg, labelSymbol = afterIfLabel)
code += translateNode(ifElse.ifScope)
code += IRCodeLabel(afterIfLabel)
}
@ -871,18 +871,18 @@ class IRCodeGen(
val array = postIncrDecr.target.array
val vmDt = vmType(postIncrDecr.target.type)
if(ident!=null) {
code += IRCodeInstruction(operationMem, vmDt, labelSymbol = ident.targetName.joinToString("."))
code += IRInstruction(operationMem, vmDt, labelSymbol = ident.targetName.joinToString("."))
} else if(memory!=null) {
if(memory.address is PtNumber) {
val address = (memory.address as PtNumber).number.toInt()
code += IRCodeInstruction(operationMem, vmDt, value = address)
code += IRInstruction(operationMem, vmDt, value = address)
} else {
val incReg = vmRegisters.nextFree()
val addressReg = vmRegisters.nextFree()
code += expressionEval.translateExpression(memory.address, addressReg, -1)
code += IRCodeInstruction(Opcode.LOADI, vmDt, reg1 = incReg, reg2 = addressReg)
code += IRCodeInstruction(operationRegister, vmDt, reg1 = incReg)
code += IRCodeInstruction(Opcode.STOREI, vmDt, reg1 = incReg, reg2 = addressReg)
code += IRInstruction(Opcode.LOADI, vmDt, reg1 = incReg, reg2 = addressReg)
code += IRInstruction(operationRegister, vmDt, reg1 = incReg)
code += IRInstruction(Opcode.STOREI, vmDt, reg1 = incReg, reg2 = addressReg)
}
} else if (array!=null) {
val variable = array.variable.targetName.joinToString(".")
@ -890,14 +890,14 @@ class IRCodeGen(
val fixedIndex = constIntValue(array.index)
if(fixedIndex!=null) {
val offset = fixedIndex*itemsize
code += IRCodeInstruction(operationMem, vmDt, labelSymbol="$variable+$offset")
code += IRInstruction(operationMem, vmDt, labelSymbol="$variable+$offset")
} else {
val incReg = vmRegisters.nextFree()
val indexReg = vmRegisters.nextFree()
code += expressionEval.translateExpression(array.index, indexReg, -1)
code += IRCodeInstruction(Opcode.LOADX, vmDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
code += IRCodeInstruction(operationRegister, vmDt, reg1=incReg)
code += IRCodeInstruction(Opcode.STOREX, vmDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
code += IRInstruction(Opcode.LOADX, vmDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
code += IRInstruction(operationRegister, vmDt, reg1=incReg)
code += IRInstruction(Opcode.STOREX, vmDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
}
} else
throw AssemblyError("weird assigntarget")
@ -921,11 +921,11 @@ class IRCodeGen(
val counterReg = vmRegisters.nextFree()
val vmDt = vmType(repeat.count.type)
code += expressionEval.translateExpression(repeat.count, counterReg, -1)
code += IRCodeInstruction(Opcode.BZ, vmDt, reg1=counterReg, labelSymbol = skipRepeatLabel)
code += IRInstruction(Opcode.BZ, vmDt, reg1=counterReg, labelSymbol = skipRepeatLabel)
code += IRCodeLabel(repeatLabel)
code += translateNode(repeat.statements)
code += IRCodeInstruction(Opcode.DEC, vmDt, reg1=counterReg)
code += IRCodeInstruction(Opcode.BNZ, vmDt, reg1=counterReg, labelSymbol = repeatLabel)
code += IRInstruction(Opcode.DEC, vmDt, reg1=counterReg)
code += IRInstruction(Opcode.BNZ, vmDt, reg1=counterReg, labelSymbol = repeatLabel)
code += IRCodeLabel(skipRepeatLabel)
return code
}
@ -935,9 +935,9 @@ class IRCodeGen(
if(jump.address!=null)
throw AssemblyError("cannot jump to memory location in the vm target")
code += if(jump.generatedLabel!=null)
IRCodeInstruction(Opcode.JUMP, labelSymbol = jump.generatedLabel!!)
IRInstruction(Opcode.JUMP, labelSymbol = jump.generatedLabel!!)
else if(jump.identifier!=null)
IRCodeInstruction(Opcode.JUMP, labelSymbol = jump.identifier!!.targetName.joinToString("."))
IRInstruction(Opcode.JUMP, labelSymbol = jump.identifier!!.targetName.joinToString("."))
else
throw AssemblyError("weird jump")
return code
@ -959,7 +959,7 @@ class IRCodeGen(
else
expressionEval.translateExpression(value, 0, -1)
}
code += IRCodeInstruction(Opcode.RETURN)
code += IRInstruction(Opcode.RETURN)
return code
}

View File

@ -10,8 +10,8 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
if(chunk is IRCodeChunk) {
do {
val indexedInstructions = chunk.lines.withIndex()
.filter { it.value is IRCodeInstruction }
.map { IndexedValue(it.index, (it.value as IRCodeInstruction).ins) }
.filter { it.value is IRInstruction }
.map { IndexedValue(it.index, it.value as IRInstruction) }
val changed = removeNops(chunk, indexedInstructions)
|| removeDoubleLoadsAndStores(chunk, indexedInstructions) // TODO not yet implemented
|| removeUselessArithmetic(chunk, indexedInstructions)
@ -26,19 +26,19 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
}
}
private fun cleanupPushPop(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<Instruction>>): Boolean {
private fun cleanupPushPop(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<IRInstruction>>): Boolean {
// push followed by pop to same target, or different target->replace with load
var changed = false
indexedInstructions.reversed().forEach { (idx, ins) ->
if(ins.opcode== Opcode.PUSH) {
if(idx < chunk.lines.size-1) {
val insAfter = chunk.lines[idx+1] as? IRCodeInstruction
if(insAfter!=null && insAfter.ins.opcode == Opcode.POP) {
if(ins.reg1==insAfter.ins.reg1) {
val insAfter = chunk.lines[idx+1] as? IRInstruction
if(insAfter!=null && insAfter.opcode == Opcode.POP) {
if(ins.reg1==insAfter.reg1) {
chunk.lines.removeAt(idx)
chunk.lines.removeAt(idx)
} else {
chunk.lines[idx] = IRCodeInstruction(Opcode.LOADR, ins.type, reg1=insAfter.ins.reg1, reg2=ins.reg1)
chunk.lines[idx] = IRInstruction(Opcode.LOADR, ins.type, reg1=insAfter.reg1, reg2=ins.reg1)
chunk.lines.removeAt(idx+1)
}
changed = true
@ -49,23 +49,23 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
return changed
}
private fun removeDoubleSecClc(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<Instruction>>): Boolean {
private fun removeDoubleSecClc(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<IRInstruction>>): Boolean {
// double sec, clc
// sec+clc or clc+sec
var changed = false
indexedInstructions.reversed().forEach { (idx, ins) ->
if(ins.opcode== Opcode.SEC || ins.opcode== Opcode.CLC) {
if(idx < chunk.lines.size-1) {
val insAfter = chunk.lines[idx+1] as? IRCodeInstruction
if(insAfter?.ins?.opcode == ins.opcode) {
val insAfter = chunk.lines[idx+1] as? IRInstruction
if(insAfter?.opcode == ins.opcode) {
chunk.lines.removeAt(idx)
changed = true
}
else if(ins.opcode== Opcode.SEC && insAfter?.ins?.opcode== Opcode.CLC) {
else if(ins.opcode== Opcode.SEC && insAfter?.opcode== Opcode.CLC) {
chunk.lines.removeAt(idx)
changed = true
}
else if(ins.opcode== Opcode.CLC && insAfter?.ins?.opcode== Opcode.SEC) {
else if(ins.opcode== Opcode.CLC && insAfter?.opcode== Opcode.SEC) {
chunk.lines.removeAt(idx)
changed = true
}
@ -75,7 +75,7 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
return changed
}
private fun removeWeirdBranches(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<Instruction>>): Boolean {
private fun removeWeirdBranches(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<IRInstruction>>): Boolean {
// jump/branch to label immediately below
var changed = false
indexedInstructions.reversed().forEach { (idx, ins) ->
@ -94,7 +94,7 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
return changed
}
private fun removeUselessArithmetic(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<Instruction>>): Boolean {
private fun removeUselessArithmetic(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<IRInstruction>>): Boolean {
// note: 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) ->
@ -107,7 +107,7 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
}
Opcode.ADD, Opcode.SUB -> {
if (ins.value == 1) {
chunk.lines[idx] = IRCodeInstruction(
chunk.lines[idx] = IRInstruction(
if (ins.opcode == Opcode.ADD) Opcode.INC else Opcode.DEC,
ins.type,
ins.reg1
@ -120,7 +120,7 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
}
Opcode.AND -> {
if (ins.value == 0) {
chunk.lines[idx] = IRCodeInstruction(Opcode.LOAD, ins.type, reg1 = ins.reg1, value = 0)
chunk.lines[idx] = IRInstruction(Opcode.LOAD, ins.type, reg1 = ins.reg1, value = 0)
changed = true
} else if (ins.value == 255 && ins.type == VmDataType.BYTE) {
chunk.lines.removeAt(idx)
@ -135,7 +135,7 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
chunk.lines.removeAt(idx)
changed = true
} else if ((ins.value == 255 && ins.type == VmDataType.BYTE) || (ins.value == 65535 && ins.type == VmDataType.WORD)) {
chunk.lines[idx] = IRCodeInstruction(Opcode.LOAD, ins.type, reg1 = ins.reg1, value = ins.value)
chunk.lines[idx] = IRInstruction(Opcode.LOAD, ins.type, reg1 = ins.reg1, value = ins.value)
changed = true
}
}
@ -151,7 +151,7 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
return changed
}
private fun removeNops(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<Instruction>>): Boolean {
private fun removeNops(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<IRInstruction>>): Boolean {
var changed = false
indexedInstructions.reversed().forEach { (idx, ins) ->
if (ins.opcode == Opcode.NOP) {
@ -162,7 +162,7 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
return changed
}
private fun removeDoubleLoadsAndStores(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<Instruction>>): Boolean {
private fun removeDoubleLoadsAndStores(chunk: IRCodeChunk, indexedInstructions: List<IndexedValue<IRInstruction>>): Boolean {
var changed = false
indexedInstructions.forEach { (idx, ins) ->

View File

@ -34,9 +34,9 @@ class TestIRPeepholeOpt: FunSpec({
test("remove nops") {
val irProg = makeIRProgram(listOf(
IRCodeInstruction(Opcode.JUMP, labelSymbol = "dummy"),
IRCodeInstruction(Opcode.NOP),
IRCodeInstruction(Opcode.NOP)
IRInstruction(Opcode.JUMP, labelSymbol = "dummy"),
IRInstruction(Opcode.NOP),
IRInstruction(Opcode.NOP)
))
irProg.lines().size shouldBe 3
val opt = IRPeepholeOptimizer(irProg)
@ -46,13 +46,13 @@ class TestIRPeepholeOpt: FunSpec({
test("remove jmp to label below") {
val irProg = makeIRProgram(listOf(
IRCodeInstruction(Opcode.JUMP, labelSymbol = "label"), // removed
IRInstruction(Opcode.JUMP, labelSymbol = "label"), // removed
IRCodeLabel("label"),
IRCodeInstruction(Opcode.JUMP, labelSymbol = "label2"), // removed
IRCodeInstruction(Opcode.NOP), // removed
IRInstruction(Opcode.JUMP, labelSymbol = "label2"), // removed
IRInstruction(Opcode.NOP), // removed
IRCodeLabel("label2"),
IRCodeInstruction(Opcode.JUMP, labelSymbol = "label3"),
IRCodeInstruction(Opcode.INC, VmDataType.BYTE, reg1=1),
IRInstruction(Opcode.JUMP, labelSymbol = "label3"),
IRInstruction(Opcode.INC, VmDataType.BYTE, reg1=1),
IRCodeLabel("label3")
))
irProg.lines().size shouldBe 8
@ -62,57 +62,57 @@ class TestIRPeepholeOpt: FunSpec({
lines.size shouldBe 5
(lines[0] as IRCodeLabel).name shouldBe "label"
(lines[1] as IRCodeLabel).name shouldBe "label2"
(lines[2] as IRCodeInstruction).ins.opcode shouldBe Opcode.JUMP
(lines[3] as IRCodeInstruction).ins.opcode shouldBe Opcode.INC
(lines[2] as IRInstruction).opcode shouldBe Opcode.JUMP
(lines[3] as IRInstruction).opcode shouldBe Opcode.INC
(lines[4] as IRCodeLabel).name shouldBe "label3"
}
test("remove double sec/clc") {
val irProg = makeIRProgram(listOf(
IRCodeInstruction(Opcode.SEC),
IRCodeInstruction(Opcode.SEC),
IRCodeInstruction(Opcode.SEC),
IRCodeInstruction(Opcode.CLC),
IRCodeInstruction(Opcode.CLC),
IRCodeInstruction(Opcode.CLC)
IRInstruction(Opcode.SEC),
IRInstruction(Opcode.SEC),
IRInstruction(Opcode.SEC),
IRInstruction(Opcode.CLC),
IRInstruction(Opcode.CLC),
IRInstruction(Opcode.CLC)
))
irProg.lines().size shouldBe 6
val opt = IRPeepholeOptimizer(irProg)
opt.optimize()
val lines = irProg.lines()
lines.size shouldBe 1
(lines[0] as IRCodeInstruction).ins.opcode shouldBe Opcode.CLC
(lines[0] as IRInstruction).opcode shouldBe Opcode.CLC
}
test("push followed by pop") {
val irProg = makeIRProgram(listOf(
IRCodeInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=42),
IRCodeInstruction(Opcode.POP, VmDataType.BYTE, reg1=42),
IRCodeInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=99),
IRCodeInstruction(Opcode.POP, VmDataType.BYTE, reg1=222)
IRInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=42),
IRInstruction(Opcode.POP, VmDataType.BYTE, reg1=42),
IRInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=99),
IRInstruction(Opcode.POP, VmDataType.BYTE, reg1=222)
))
irProg.lines().size shouldBe 4
val opt = IRPeepholeOptimizer(irProg)
opt.optimize()
val lines = irProg.lines()
lines.size shouldBe 1
(lines[0] as IRCodeInstruction).ins.opcode shouldBe Opcode.LOADR
(lines[0] as IRCodeInstruction).ins.reg1 shouldBe 222
(lines[0] as IRCodeInstruction).ins.reg2 shouldBe 99
(lines[0] as IRInstruction).opcode shouldBe Opcode.LOADR
(lines[0] as IRInstruction).reg1 shouldBe 222
(lines[0] as IRInstruction).reg2 shouldBe 99
}
test("remove useless div/mul, add/sub") {
val irProg = makeIRProgram(listOf(
IRCodeInstruction(Opcode.DIV, VmDataType.BYTE, reg1=42, value = 1),
IRCodeInstruction(Opcode.DIVS, VmDataType.BYTE, reg1=42, value = 1),
IRCodeInstruction(Opcode.MUL, VmDataType.BYTE, reg1=42, value = 1),
IRCodeInstruction(Opcode.MOD, VmDataType.BYTE, reg1=42, value = 1),
IRCodeInstruction(Opcode.DIV, VmDataType.BYTE, reg1=42, value = 2),
IRCodeInstruction(Opcode.DIVS, VmDataType.BYTE, reg1=42, value = 2),
IRCodeInstruction(Opcode.MUL, VmDataType.BYTE, reg1=42, value = 2),
IRCodeInstruction(Opcode.MOD, VmDataType.BYTE, reg1=42, value = 2),
IRCodeInstruction(Opcode.ADD, VmDataType.BYTE, reg1=42, value = 0),
IRCodeInstruction(Opcode.SUB, VmDataType.BYTE, reg1=42, value = 0)
IRInstruction(Opcode.DIV, VmDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.DIVS, VmDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.MUL, VmDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.MOD, VmDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.DIV, VmDataType.BYTE, reg1=42, value = 2),
IRInstruction(Opcode.DIVS, VmDataType.BYTE, reg1=42, value = 2),
IRInstruction(Opcode.MUL, VmDataType.BYTE, reg1=42, value = 2),
IRInstruction(Opcode.MOD, VmDataType.BYTE, reg1=42, value = 2),
IRInstruction(Opcode.ADD, VmDataType.BYTE, reg1=42, value = 0),
IRInstruction(Opcode.SUB, VmDataType.BYTE, reg1=42, value = 0)
))
irProg.lines().size shouldBe 10
val opt = IRPeepholeOptimizer(irProg)
@ -123,28 +123,28 @@ class TestIRPeepholeOpt: FunSpec({
test("replace add/sub 1 by inc/dec") {
val irProg = makeIRProgram(listOf(
IRCodeInstruction(Opcode.ADD, VmDataType.BYTE, reg1=42, value = 1),
IRCodeInstruction(Opcode.SUB, VmDataType.BYTE, reg1=42, value = 1)
IRInstruction(Opcode.ADD, VmDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.SUB, VmDataType.BYTE, reg1=42, value = 1)
))
irProg.lines().size shouldBe 2
val opt = IRPeepholeOptimizer(irProg)
opt.optimize()
val lines = irProg.lines()
lines.size shouldBe 2
(lines[0] as IRCodeInstruction).ins.opcode shouldBe Opcode.INC
(lines[1] as IRCodeInstruction).ins.opcode shouldBe Opcode.DEC
(lines[0] as IRInstruction).opcode shouldBe Opcode.INC
(lines[1] as IRInstruction).opcode shouldBe Opcode.DEC
}
test("remove useless and/or/xor") {
val irProg = makeIRProgram(listOf(
IRCodeInstruction(Opcode.AND, VmDataType.BYTE, reg1=42, value = 255),
IRCodeInstruction(Opcode.AND, VmDataType.WORD, reg1=42, value = 65535),
IRCodeInstruction(Opcode.OR, VmDataType.BYTE, reg1=42, value = 0),
IRCodeInstruction(Opcode.XOR, VmDataType.BYTE, reg1=42, value = 0),
IRCodeInstruction(Opcode.AND, VmDataType.BYTE, reg1=42, value = 200),
IRCodeInstruction(Opcode.AND, VmDataType.WORD, reg1=42, value = 60000),
IRCodeInstruction(Opcode.OR, VmDataType.BYTE, reg1=42, value = 1),
IRCodeInstruction(Opcode.XOR, VmDataType.BYTE, reg1=42, value = 1)
IRInstruction(Opcode.AND, VmDataType.BYTE, reg1=42, value = 255),
IRInstruction(Opcode.AND, VmDataType.WORD, reg1=42, value = 65535),
IRInstruction(Opcode.OR, VmDataType.BYTE, reg1=42, value = 0),
IRInstruction(Opcode.XOR, VmDataType.BYTE, reg1=42, value = 0),
IRInstruction(Opcode.AND, VmDataType.BYTE, reg1=42, value = 200),
IRInstruction(Opcode.AND, VmDataType.WORD, reg1=42, value = 60000),
IRInstruction(Opcode.OR, VmDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.XOR, VmDataType.BYTE, reg1=42, value = 1)
))
irProg.lines().size shouldBe 8
val opt = IRPeepholeOptimizer(irProg)
@ -155,23 +155,23 @@ class TestIRPeepholeOpt: FunSpec({
test("replace and/or/xor by constant number") {
val irProg = makeIRProgram(listOf(
IRCodeInstruction(Opcode.AND, VmDataType.BYTE, reg1=42, value = 0),
IRCodeInstruction(Opcode.AND, VmDataType.WORD, reg1=42, value = 0),
IRCodeInstruction(Opcode.OR, VmDataType.BYTE, reg1=42, value = 255),
IRCodeInstruction(Opcode.OR, VmDataType.WORD, reg1=42, value = 65535)
IRInstruction(Opcode.AND, VmDataType.BYTE, reg1=42, value = 0),
IRInstruction(Opcode.AND, VmDataType.WORD, reg1=42, value = 0),
IRInstruction(Opcode.OR, VmDataType.BYTE, reg1=42, value = 255),
IRInstruction(Opcode.OR, VmDataType.WORD, reg1=42, value = 65535)
))
irProg.lines().size shouldBe 4
val opt = IRPeepholeOptimizer(irProg)
opt.optimize()
val lines = irProg.lines()
lines.size shouldBe 4
(lines[0] as IRCodeInstruction).ins.opcode shouldBe Opcode.LOAD
(lines[1] as IRCodeInstruction).ins.opcode shouldBe Opcode.LOAD
(lines[2] as IRCodeInstruction).ins.opcode shouldBe Opcode.LOAD
(lines[3] as IRCodeInstruction).ins.opcode shouldBe Opcode.LOAD
(lines[0] as IRCodeInstruction).ins.value shouldBe 0
(lines[1] as IRCodeInstruction).ins.value shouldBe 0
(lines[2] as IRCodeInstruction).ins.value shouldBe 255
(lines[3] as IRCodeInstruction).ins.value shouldBe 65535
(lines[0] as IRInstruction).opcode shouldBe Opcode.LOAD
(lines[1] as IRInstruction).opcode shouldBe Opcode.LOAD
(lines[2] as IRInstruction).opcode shouldBe Opcode.LOAD
(lines[3] as IRInstruction).opcode shouldBe Opcode.LOAD
(lines[0] as IRInstruction).value shouldBe 0
(lines[1] as IRInstruction).value shouldBe 0
(lines[2] as IRInstruction).value shouldBe 255
(lines[3] as IRInstruction).value shouldBe 65535
}
})

View File

@ -1,16 +0,0 @@
package prog8.codegen.virtual
import prog8.code.core.CompilationOptions
import prog8.code.core.IAssemblyProgram
import prog8.intermediate.IRFileWriter
import prog8.intermediate.IRProgram
internal class VmAssemblyProgram(override val name: String, private val irProgram: IRProgram): IAssemblyProgram {
override fun assemble(options: CompilationOptions): Boolean {
val writtenFile = IRFileWriter(irProgram, null).write()
println("Wrote intermediate representation to $writtenFile")
return true
}
}

View File

@ -9,6 +9,7 @@ import prog8.code.core.IErrorReporter
import prog8.codegen.intermediate.IRCodeGen
import prog8.intermediate.IRFileReader
import prog8.intermediate.IRFileWriter
import prog8.intermediate.IRProgram
import java.nio.file.Path
class VmCodeGen(private val program: PtProgram,
@ -37,4 +38,14 @@ class VmCodeGen(private val program: PtProgram,
return VmAssemblyProgram(irProgram.name, irProgram)
}
}
}
}
internal class VmAssemblyProgram(override val name: String, private val irProgram: IRProgram): IAssemblyProgram {
override fun assemble(options: CompilationOptions): Boolean {
val writtenFile = IRFileWriter(irProgram, null).write()
println("Wrote intermediate representation to $writtenFile")
return true
}
}

View File

@ -3,7 +3,7 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- vm: merge IRCodeInstruction into Instruction directly
- vm: move codeGenVirtual module into virtualmachine module?
- vm: actually translate IRProgram to vm program list again.
- docs: modify compiler arch picture once this is done.

View File

@ -562,7 +562,7 @@ class IRFileReader {
if(format.fpValue && value!=null)
floatValue = value
return IRCodeInstruction(opcode, type, reg1, reg2, fpReg1, fpReg2, intValue, floatValue, labelSymbol)
return IRInstruction(opcode, type, reg1, reg2, fpReg1, fpReg2, intValue, floatValue, labelSymbol)
}
private fun convertVmType(typestr: String): VmDataType? {

View File

@ -152,9 +152,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
private fun BufferedWriter.writeLine(line: IRCodeLine) {
when(line) {
is IRCodeComment -> write("; ${line.comment}\n")
is IRCodeInstruction -> {
write(line.ins.toString() + "\n")
}
is IRInstruction -> write(line.toString() + "\n")
is IRCodeLabel -> write("_${line.name}:\n")
is IRCodeInlineBinary -> {
write("<BYTES>\n")

View File

@ -398,7 +398,7 @@ enum class VmDataType {
// TODO add INT (32-bit)? INT24 (24-bit)?
}
data class Instruction(
data class IRInstruction(
val opcode: Opcode,
val type: VmDataType?=null,
val reg1: Int?=null, // 0-$ffff
@ -409,13 +409,38 @@ data class Instruction(
val fpValue: Float?=null,
val labelSymbol: String?=null, // symbolic label name as alternative to value (so only for Branch/jump/call Instructions!)
val binaryData: ByteArray?=null
) {
): IRCodeLine() {
// reg1 and fpreg1 can be IN/OUT/INOUT (all others are readonly INPUT)
// This knowledge is useful in IL assembly optimizers to see how registers are used.
val reg1direction: OperandDirection
val fpReg1direction: OperandDirection
init {
if(labelSymbol?.startsWith('_')==true) {
throw IllegalArgumentException("label/symbol should not start with underscore $labelSymbol")
}
if(reg1!=null && (reg1<0 || reg1>65536))
throw IllegalArgumentException("reg1 out of bounds")
if(reg2!=null && (reg2<0 || reg2>65536))
throw IllegalArgumentException("reg2 out of bounds")
if(fpReg1!=null && (fpReg1<0 || fpReg1>65536))
throw IllegalArgumentException("fpReg1 out of bounds")
if(fpReg2!=null && (fpReg2<0 || fpReg2>65536))
throw IllegalArgumentException("fpReg2 out of bounds")
if(value!=null && opcode !in OpcodesWithAddress) {
when (type) {
VmDataType.BYTE -> {
if (value < -128 || value > 255)
throw IllegalArgumentException("value out of range for byte: $value")
}
VmDataType.WORD -> {
if (value < -32768 || value > 65535)
throw IllegalArgumentException("value out of range for word: $value")
}
VmDataType.FLOAT, null -> {}
}
}
if(opcode==Opcode.BINARYDATA && binaryData==null || binaryData!=null && opcode!=Opcode.BINARYDATA)
throw IllegalArgumentException("binarydata inconsistency")

View File

@ -126,49 +126,6 @@ class IRAsmSubroutine(val name: String,
sealed class IRCodeLine
class IRCodeInstruction( // TODO join this into Instruction directly
opcode: Opcode,
type: VmDataType?=null,
reg1: Int?=null, // 0-$ffff
reg2: Int?=null, // 0-$ffff
fpReg1: Int?=null, // 0-$ffff
fpReg2: Int?=null, // 0-$ffff
value: Int?=null, // 0-$ffff
fpValue: Float?=null,
labelSymbol: String?=null // alternative to value
): IRCodeLine() {
val ins = Instruction(opcode, type, reg1, reg2, fpReg1, fpReg2, value, fpValue, labelSymbol)
init {
if(reg1!=null && (reg1<0 || reg1>65536))
throw IllegalArgumentException("reg1 out of bounds")
if(reg2!=null && (reg2<0 || reg2>65536))
throw IllegalArgumentException("reg2 out of bounds")
if(fpReg1!=null && (fpReg1<0 || fpReg1>65536))
throw IllegalArgumentException("fpReg1 out of bounds")
if(fpReg2!=null && (fpReg2<0 || fpReg2>65536))
throw IllegalArgumentException("fpReg2 out of bounds")
if(value!=null && opcode !in OpcodesWithAddress) {
when (type) {
VmDataType.BYTE -> {
if (value < -128 || value > 255)
throw IllegalArgumentException("value out of range for byte: $value")
}
VmDataType.WORD -> {
if (value < -32768 || value > 65535)
throw IllegalArgumentException("value out of range for word: $value")
}
VmDataType.FLOAT, null -> {}
}
}
if(labelSymbol?.startsWith('_')==true) {
throw IllegalArgumentException("label/symbol should not start with underscore $labelSymbol")
}
}
}
class IRCodeLabel(val name: String): IRCodeLine()
class IRCodeComment(val comment: String): IRCodeLine()

View File

@ -8,7 +8,7 @@ import prog8.intermediate.*
class TestInstructions: FunSpec({
test("simple") {
val ins = Instruction(Opcode.NOP)
val ins = IRInstruction(Opcode.NOP)
ins.opcode shouldBe Opcode.NOP
ins.type shouldBe null
ins.reg1 shouldBe null
@ -21,33 +21,33 @@ class TestInstructions: FunSpec({
}
test("with value") {
val ins = Instruction(Opcode.BZ, VmDataType.BYTE, reg1=42, value = 9999)
val ins = IRInstruction(Opcode.BZ, VmDataType.BYTE, reg1=42, value = 99)
ins.opcode shouldBe Opcode.BZ
ins.type shouldBe VmDataType.BYTE
ins.reg1 shouldBe 42
ins.reg2 shouldBe null
ins.value shouldBe 9999
ins.value shouldBe 99
ins.labelSymbol shouldBe null
ins.reg1direction shouldBe OperandDirection.INPUT
ins.fpReg1direction shouldBe OperandDirection.INPUT
ins.toString() shouldBe "bz.b r42,9999"
ins.toString() shouldBe "bz.b r42,99"
}
test("with label") {
val ins = Instruction(Opcode.BZ, VmDataType.WORD, reg1=11, labelSymbol = "a.b.c")
val ins = IRInstruction(Opcode.BZ, VmDataType.WORD, reg1=11, labelSymbol = "a.b.c")
ins.opcode shouldBe Opcode.BZ
ins.type shouldBe VmDataType.WORD
ins.reg1 shouldBe 11
ins.reg2 shouldBe null
ins.value shouldBe null
ins.labelSymbol shouldBe listOf("a","b","c")
ins.labelSymbol shouldBe "a.b.c"
ins.reg1direction shouldBe OperandDirection.INPUT
ins.fpReg1direction shouldBe OperandDirection.INPUT
ins.toString() shouldBe "bz.w r11,_a.b.c"
}
test("with output registers") {
val ins = Instruction(Opcode.ADDR, VmDataType.WORD, reg1=11, reg2=22)
val ins = IRInstruction(Opcode.ADDR, VmDataType.WORD, reg1=11, reg2=22)
ins.opcode shouldBe Opcode.ADDR
ins.type shouldBe VmDataType.WORD
ins.reg1 shouldBe 11
@ -58,7 +58,7 @@ class TestInstructions: FunSpec({
ins.fpReg1direction shouldBe OperandDirection.INPUT
ins.toString() shouldBe "addr.w r11,r22"
val ins2 = Instruction(Opcode.SQRT, VmDataType.BYTE, reg1=11, reg2=22)
val ins2 = IRInstruction(Opcode.SQRT, VmDataType.BYTE, reg1=11, reg2=22)
ins2.opcode shouldBe Opcode.SQRT
ins2.type shouldBe VmDataType.BYTE
ins2.reg1 shouldBe 11
@ -73,19 +73,19 @@ class TestInstructions: FunSpec({
test("missing type should fail") {
shouldThrow<IllegalArgumentException> {
Instruction(Opcode.BZ, reg1=42, value=9999)
IRInstruction(Opcode.BZ, reg1=42, value=9999)
}
}
test("missing registers should fail") {
shouldThrow<IllegalArgumentException> {
Instruction(Opcode.BZ, VmDataType.BYTE, value=9999)
IRInstruction(Opcode.BZ, VmDataType.BYTE, value=9999)
}
}
test("missing value should fail") {
shouldThrow<IllegalArgumentException> {
Instruction(Opcode.BZ, VmDataType.BYTE, reg1=42)
IRInstruction(Opcode.BZ, VmDataType.BYTE, reg1=42)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -5,11 +5,11 @@ import java.lang.IllegalArgumentException
class VmProgramLoader {
fun load(irProgram: IRProgram, memory: Memory): Array<Instruction> {
fun load(irProgram: IRProgram, memory: Memory): Array<IRInstruction> {
// at long last, allocate the variables in memory.
val allocations = VmVariableAllocator(irProgram.st, irProgram.encoding, irProgram.options.compTarget)
val program = mutableListOf<Instruction>()
val program = mutableListOf<IRInstruction>()
// TODO stuff the allocated variables into memory
@ -22,7 +22,7 @@ class VmProgramLoader {
// make sure that if there is a "main.start" entrypoint, we jump to it
irProgram.blocks.firstOrNull()?.let {
if(it.subroutines.any { sub -> sub.name=="main.start" }) {
program.add(Instruction(Opcode.JUMP, labelSymbol = "main.start"))
program.add(IRInstruction(Opcode.JUMP, labelSymbol = "main.start"))
}
}

View File

@ -42,9 +42,9 @@ class TestVm: FunSpec( {
val block = IRBlock("main", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
val startSub = IRSubroutine("main.start2222", emptyList(), null, Position.DUMMY) // TODO proper name main.start
val code = IRCodeChunk(Position.DUMMY)
code += IRCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=1, value=12345)
code += IRCodeInstruction(Opcode.STOREM, VmDataType.WORD, reg1=1, value=1000)
code += IRCodeInstruction(Opcode.RETURN)
code += IRInstruction(Opcode.LOAD, VmDataType.WORD, reg1=1, value=12345)
code += IRInstruction(Opcode.STOREM, VmDataType.WORD, reg1=1, value=1000)
code += IRInstruction(Opcode.RETURN)
startSub += code
block += startSub
program.addBlock(block)