tweaking IR instruction formats

This commit is contained in:
Irmen de Jong
2023-04-09 15:06:40 +02:00
parent c3d74f2ae9
commit ccdf05e922
16 changed files with 451 additions and 474 deletions
@@ -138,16 +138,16 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
"+" -> { }
"-" -> {
code += if(address!=null)
IRInstruction(Opcode.NEGM, vmDt, value = address)
IRInstruction(Opcode.NEGM, vmDt, address = address)
else
IRInstruction(Opcode.NEGM, vmDt, labelSymbol = symbol)
}
"~" -> {
val regMask = codeGen.registers.nextFree()
val mask = if(vmDt==IRDataType.BYTE) 0x00ff else 0xffff
code += IRInstruction(Opcode.LOAD, vmDt, reg1=regMask, value = mask)
code += IRInstruction(Opcode.LOAD, vmDt, reg1=regMask, immediate = mask)
code += if(address!=null)
IRInstruction(Opcode.XORM, vmDt, reg1=regMask, value = address)
IRInstruction(Opcode.XORM, vmDt, reg1=regMask, address = address)
else
IRInstruction(Opcode.XORM, vmDt, reg1=regMask, labelSymbol = symbol)
}
@@ -214,7 +214,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
if(zero) {
// there's no STOREZIX instruction
valueRegister = codeGen.registers.nextFree()
code += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegister, value=0)
code += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegister, immediate = 0)
}
code += IRInstruction(Opcode.STOREIX, vmDt, reg1=valueRegister, reg2=idxReg, labelSymbol = variable)
result += code
@@ -261,7 +261,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
require(vmDt== IRDataType.BYTE) { "must be byte type ${targetMemory.position}"}
if(zero) {
if(targetMemory.address is PtNumber) {
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZM, vmDt, value=(targetMemory.address as PtNumber).number.toInt()) }
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZM, vmDt, address = (targetMemory.address as PtNumber).number.toInt()) }
result += chunk
} else {
val tr = expressionEval.translateExpression(targetMemory.address)
@@ -271,7 +271,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
}
} else {
if(targetMemory.address is PtNumber) {
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREM, vmDt, reg1=valueRegister, value=(targetMemory.address as PtNumber).number.toInt()) }
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREM, vmDt, reg1=valueRegister, address=(targetMemory.address as PtNumber).number.toInt()) }
result += chunk
} else {
val tr = expressionEval.translateExpression(targetMemory.address)
@@ -300,7 +300,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
if(codeGen.options.useNewExprCode) {
val tr = expressionEval.translateExpression(array.index)
result += tr.chunks
addInstr(result, IRInstruction(Opcode.MUL, tr.dt, reg1=tr.resultReg, value = itemsize), null)
addInstr(result, IRInstruction(Opcode.MUL, tr.dt, reg1=tr.resultReg, immediate = itemsize), null)
return Pair(result, tr.resultReg)
} else {
val mult: PtExpression
@@ -55,7 +55,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
if(divident is PtNumber) {
val tr = exprGen.translateExpression(number)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, IRInstruction(Opcode.DIVMOD, type, reg1 = tr.resultReg, value=divident.number.toInt()), null)
addInstr(result, IRInstruction(Opcode.DIVMOD, type, reg1 = tr.resultReg, immediate = divident.number.toInt()), null)
} else {
val numTr = exprGen.translateExpression(number)
addToResult(result, numTr, numTr.resultReg, -1)
@@ -76,7 +76,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val targetReg = codeGen.registers.nextFree()
addToResult(result, left, 65500, -1)
addToResult(result, right, 65501, -1)
addInstr(result, IRInstruction(Opcode.SYSCALL, value=IMSyscall.COMPARE_STRINGS.number), null)
addInstr(result, IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.COMPARE_STRINGS.number), null)
addInstr(result, IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=targetReg, reg2=0), null)
return ExpressionCodeResult(result, IRDataType.BYTE, targetReg, -1)
}
@@ -110,8 +110,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val tr = exprGen.translateExpression(call.args[0])
addToResult(result, tr, SyscallRegisterBase, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, immediate = array.length)
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number)
// SysCall call convention: return value in register r0
if(tr.resultReg!=0)
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1 = tr.resultReg, reg2 = 0)
@@ -135,8 +135,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val tr = exprGen.translateExpression(call.args[0])
addToResult(result, tr, SyscallRegisterBase, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, immediate = array.length)
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number)
// SysCall call convention: return value in register r0
if(tr.resultReg!=0)
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1 = tr.resultReg, reg2 = 0)
@@ -164,7 +164,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val compareReg = codeGen.registers.nextFree()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=tr.resultReg)
it += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=compareReg, value=0x80)
it += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=compareReg, immediate = 0x80)
it += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=compareReg, labelSymbol = notNegativeLabel)
it += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1=tr.resultReg)
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=tr.resultReg)
@@ -177,7 +177,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val compareReg = codeGen.registers.nextFree()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=tr.resultReg)
it += IRInstruction(Opcode.AND, IRDataType.WORD, reg1=compareReg, value=0x8000)
it += IRInstruction(Opcode.AND, IRDataType.WORD, reg1=compareReg, immediate = 0x8000)
it += IRInstruction(Opcode.BZ, IRDataType.WORD, reg1=compareReg, labelSymbol = notNegativeLabel)
it += IRInstruction(Opcode.NEG, IRDataType.WORD, reg1=tr.resultReg)
}
@@ -263,8 +263,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val tr = exprGen.translateExpression(call.args[0])
addToResult(result, tr, SyscallRegisterBase, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, immediate = array.length)
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number)
}
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
}
@@ -286,8 +286,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val tr = exprGen.translateExpression(call.args[0])
addToResult(result, tr, SyscallRegisterBase, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, immediate = array.length)
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number)
}
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
}
@@ -310,7 +310,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
if (call.args[0] is PtNumber) {
val address = (call.args[0] as PtNumber).number.toInt()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREZM, IRDataType.WORD, value = address)
it += IRInstruction(Opcode.STOREZM, IRDataType.WORD, address = address)
}
} else {
val tr = exprGen.translateExpression(call.args[0])
@@ -325,7 +325,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val tr = exprGen.translateExpression(call.args[1])
addToResult(result, tr, tr.resultReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1 = tr.resultReg, value = address)
it += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1 = tr.resultReg, address = address)
}
} else {
val addressTr = exprGen.translateExpression(call.args[0])
@@ -346,7 +346,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
if (call.args[0] is PtNumber) {
val address = (call.args[0] as PtNumber).number.toInt()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREZM, IRDataType.BYTE, value = address)
it += IRInstruction(Opcode.STOREZM, IRDataType.BYTE, address = address)
}
} else {
val tr = exprGen.translateExpression(call.args[0])
@@ -361,7 +361,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val tr = exprGen.translateExpression(call.args[1])
addToResult(result, tr, tr.resultReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = tr.resultReg, value = address)
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = tr.resultReg, address = address)
}
} else {
val addressTr = exprGen.translateExpression(call.args[0])
@@ -382,7 +382,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val resultRegister = codeGen.registers.nextFree()
val address = (call.args[0] as PtNumber).number.toInt()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, IRDataType.WORD, reg1 = resultRegister, value = address)
it += IRInstruction(Opcode.LOADM, IRDataType.WORD, reg1 = resultRegister, address = address)
}
ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
} else {
@@ -402,7 +402,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val resultRegister = codeGen.registers.nextFree()
val address = (call.args[0] as PtNumber).number.toInt()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1 = resultRegister, value = address)
it += IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1 = resultRegister, address = address)
}
ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
} else {
@@ -35,12 +35,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val code = IRCodeChunk(null, null)
if(vmDt==IRDataType.FLOAT) {
val resultFpRegister = codeGen.registers.nextFreeFloat()
code += IRInstruction(Opcode.LOAD, vmDt, fpReg1 = resultFpRegister, fpValue = expr.number.toFloat())
code += IRInstruction(Opcode.LOAD, vmDt, fpReg1 = resultFpRegister, immediateFp = expr.number.toFloat())
ExpressionCodeResult(code, vmDt,-1, resultFpRegister)
}
else {
val resultRegister = codeGen.registers.nextFree()
code += IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, value = expr.number.toInt())
code += IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, immediate = expr.number.toInt())
ExpressionCodeResult(code, vmDt, resultRegister, -1)
}
}
@@ -79,7 +79,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(expr.address is PtNumber) {
val address = (expr.address as PtNumber).number.toInt()
val resultRegister = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1=resultRegister, value = address), null)
addInstr(result, IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1=resultRegister, address = address), null)
ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
} else {
val tr = translateExpression(expr.address)
@@ -116,7 +116,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
addToResult(result, tr, SyscallRegisterBase+1, -1)
val resultReg = codeGen.registers.nextFree()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.SYSCALL, value = IMSyscall.STRING_CONTAINS.number)
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.STRING_CONTAINS.number)
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=resultReg, reg2=0)
}
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
@@ -128,8 +128,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
addToResult(result, tr, SyscallRegisterBase+1, -1)
val resultReg = codeGen.registers.nextFree()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=SyscallRegisterBase+2, value = iterable.length!!)
it += IRInstruction(Opcode.SYSCALL, value = IMSyscall.BYTEARRAY_CONTAINS.number)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=SyscallRegisterBase+2, immediate = iterable.length!!)
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.BYTEARRAY_CONTAINS.number)
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=resultReg, reg2=0)
}
// SysCall call convention: return value in register r0
@@ -142,8 +142,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
addToResult(result, tr, SyscallRegisterBase+1, -1)
val resultReg = codeGen.registers.nextFree()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=SyscallRegisterBase+2, value = iterable.length!!)
it += IRInstruction(Opcode.SYSCALL, value = IMSyscall.WORDARRAY_CONTAINS.number)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=SyscallRegisterBase+2, immediate = iterable.length!!)
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.WORDARRAY_CONTAINS.number)
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=resultReg, reg2=0)
}
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
@@ -216,7 +216,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
}
"~" -> {
val mask = if(vmDt==IRDataType.BYTE) 0x00ff else 0xffff
addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = tr.resultReg, value = mask), null)
addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = tr.resultReg, immediate = mask), null)
}
else -> throw AssemblyError("weird prefix operator")
}
@@ -402,7 +402,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
}
}
// just a regular call without using Vm register call convention: the value is returned in CPU registers!
addInstr(result, IRInstruction(Opcode.CALL, value=callTarget.address.toInt()), null)
addInstr(result, IRInstruction(Opcode.CALL, address = callTarget.address.toInt()), null)
val resultReg = codeGen.registers.nextFree()
if(!fcall.void) {
when(callTarget.returns.size) {
@@ -454,7 +454,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val resultRegister = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null)
val zeroRegister = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0), null)
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, immediate = 0), null)
val ins = if (signed) {
if (greaterEquals) Opcode.SGES else Opcode.SGTS
} else {
@@ -469,10 +469,10 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val rightTr = translateExpression(binExpr.right)
addToResult(result, rightTr, SyscallRegisterBase+1, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.SYSCALL, value = IMSyscall.COMPARE_STRINGS.number)
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.COMPARE_STRINGS.number)
// SysCall call convention: return value in register r0
val zeroReg = codeGen.registers.nextFree()
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = zeroReg, value = 0)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = zeroReg, immediate = 0)
it += if (greaterEquals)
IRInstruction(Opcode.SGES, IRDataType.BYTE, reg1 = leftTr.resultReg, reg2 = zeroReg)
else
@@ -510,7 +510,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val resultRegister = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null)
val zeroRegister = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0), null)
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, immediate = 0), null)
val ins = if (signed) {
if (lessEquals) Opcode.SLES else Opcode.SLTS
} else {
@@ -526,10 +526,10 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
addToResult(result, rightTr, SyscallRegisterBase+1, -1)
val resultReg = codeGen.registers.nextFree()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.SYSCALL, value = IMSyscall.COMPARE_STRINGS.number)
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.COMPARE_STRINGS.number)
// SysCall call convention: return value in register r0
val zeroReg = codeGen.registers.nextFree()
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = zeroReg, value = 0)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = zeroReg, immediate = 0)
it += if (lessEquals)
IRInstruction(Opcode.SLES, IRDataType.BYTE, reg1 = 0, reg2 = zeroReg)
else
@@ -563,14 +563,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val resultRegister = codeGen.registers.nextFree()
val valueReg = codeGen.registers.nextFree()
val label = codeGen.createLabelName()
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, value=1), null)
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, immediate = 1), null)
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=valueReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null)
if (notEquals) {
addInstr(result, IRInstruction(Opcode.BNZ, IRDataType.BYTE, reg1=valueReg, labelSymbol = label), null)
} else {
addInstr(result, IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=valueReg, labelSymbol = label), null)
}
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, value=0), null)
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, immediate = 0), null)
result += IRCodeChunk(label, null)
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
} else {
@@ -581,12 +581,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
addToResult(result, rightTr, SyscallRegisterBase+1, -1)
val resultRegister = codeGen.registers.nextFree()
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.SYSCALL, value = IMSyscall.COMPARE_STRINGS.number)
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.COMPARE_STRINGS.number)
// SysCall call convention: return value in register r0
if (!notEquals)
it += IRInstruction(Opcode.INV, vmDt, reg1 = 0)
it += IRInstruction(Opcode.LOADR, vmDt, reg1=resultRegister, reg2=0)
it += IRInstruction(Opcode.AND, vmDt, reg1 = resultRegister, value = 1)
it += IRInstruction(Opcode.AND, vmDt, reg1 = resultRegister, immediate = 1)
}
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
} else {
@@ -651,7 +651,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = tr.resultReg, value=(binExpr.right as PtNumber).number.toInt()), null)
addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = tr.resultReg, immediate = (binExpr.right as PtNumber).number.toInt()), null)
ExpressionCodeResult(result, vmDt, tr.resultReg, -1)
} else {
val leftTr = translateExpression(binExpr.left)
@@ -668,7 +668,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, IRInstruction(Opcode.AND, vmDt, reg1 = tr.resultReg, value=(binExpr.right as PtNumber).number.toInt()), null)
addInstr(result, IRInstruction(Opcode.AND, vmDt, reg1 = tr.resultReg, immediate = (binExpr.right as PtNumber).number.toInt()), null)
ExpressionCodeResult(result, vmDt, tr.resultReg, -1)
} else {
val leftTr = translateExpression(binExpr.left)
@@ -685,7 +685,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, IRInstruction(Opcode.OR, vmDt, reg1 = tr.resultReg, value=(binExpr.right as PtNumber).number.toInt()), null)
addInstr(result, IRInstruction(Opcode.OR, vmDt, reg1 = tr.resultReg, immediate = (binExpr.right as PtNumber).number.toInt()), null)
ExpressionCodeResult(result, vmDt, tr.resultReg, -1)
} else {
val leftTr = translateExpression(binExpr.left)
@@ -703,7 +703,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, IRInstruction(Opcode.MOD, vmDt, reg1 = tr.resultReg, value=(binExpr.right as PtNumber).number.toInt()), null)
addInstr(result, IRInstruction(Opcode.MOD, vmDt, reg1 = tr.resultReg, immediate = (binExpr.right as PtNumber).number.toInt()), null)
ExpressionCodeResult(result, vmDt, tr.resultReg, -1)
} else {
val leftTr = translateExpression(binExpr.left)
@@ -749,9 +749,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val leftTr = translateExpression(binExpr.left)
addToResult(result, leftTr, leftTr.resultReg, -1)
addInstr(result, if (signed)
IRInstruction(Opcode.DIVS, vmDt, reg1 = leftTr.resultReg, value=(binExpr.right as PtNumber).number.toInt())
IRInstruction(Opcode.DIVS, vmDt, reg1 = leftTr.resultReg, immediate = (binExpr.right as PtNumber).number.toInt())
else
IRInstruction(Opcode.DIV, vmDt, reg1 = leftTr.resultReg, value=(binExpr.right as PtNumber).number.toInt())
IRInstruction(Opcode.DIV, vmDt, reg1 = leftTr.resultReg, immediate = (binExpr.right as PtNumber).number.toInt())
, null)
ExpressionCodeResult(result, vmDt, leftTr.resultReg, -1)
} else {
@@ -832,7 +832,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left)
addToResult(result, tr, -1, tr.resultFpReg)
addInstr(result, IRInstruction(Opcode.SUB, vmDt, fpReg1 = tr.resultFpReg, fpValue = (binExpr.right as PtNumber).number.toFloat()), null)
addInstr(result, IRInstruction(Opcode.SUB, vmDt, fpReg1 = tr.resultFpReg, immediateFp = (binExpr.right as PtNumber).number.toFloat()), null)
ExpressionCodeResult(result, vmDt, -1, tr.resultFpReg)
} else {
val leftTr = translateExpression(binExpr.left)
@@ -854,7 +854,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left,)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, IRInstruction(Opcode.SUB, vmDt, reg1 = tr.resultReg, value = (binExpr.right as PtNumber).number.toInt()), null)
addInstr(result, IRInstruction(Opcode.SUB, vmDt, reg1 = tr.resultReg, immediate = (binExpr.right as PtNumber).number.toInt()), null)
ExpressionCodeResult(result, vmDt, tr.resultReg, -1)
} else {
val leftTr = translateExpression(binExpr.left)
@@ -887,7 +887,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left)
addToResult(result, tr, -1, tr.resultFpReg)
addInstr(result, IRInstruction(Opcode.ADD, vmDt, fpReg1 = tr.resultFpReg, fpValue = (binExpr.right as PtNumber).number.toFloat()), null)
addInstr(result, IRInstruction(Opcode.ADD, vmDt, fpReg1 = tr.resultFpReg, immediateFp = (binExpr.right as PtNumber).number.toFloat()), null)
ExpressionCodeResult(result, vmDt, -1, tr.resultFpReg)
} else {
val leftTr = translateExpression(binExpr.left)
@@ -915,7 +915,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, IRInstruction(Opcode.ADD, vmDt, reg1 = tr.resultReg, value=(binExpr.right as PtNumber).number.toInt()), null)
addInstr(result, IRInstruction(Opcode.ADD, vmDt, reg1 = tr.resultReg, immediate = (binExpr.right as PtNumber).number.toInt()), null)
ExpressionCodeResult(result, vmDt, tr.resultReg, -1)
} else {
val leftTr = translateExpression(binExpr.left)
@@ -935,7 +935,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, value=knownAddress)
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, address = knownAddress)
else
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
,null)
@@ -947,7 +947,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, value = knownAddress)
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, address = knownAddress)
else
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
@@ -966,13 +966,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
addToResult(result, tr, -1, tr.resultFpReg)
val ins = if(signed) {
if(knownAddress!=null)
IRInstruction(Opcode.DIVSM, vmDt, fpReg1 = tr.resultFpReg, value = knownAddress)
IRInstruction(Opcode.DIVSM, vmDt, fpReg1 = tr.resultFpReg, address = knownAddress)
else
IRInstruction(Opcode.DIVSM, vmDt, fpReg1 = tr.resultFpReg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = tr.resultFpReg, value = knownAddress)
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = tr.resultFpReg, address = knownAddress)
else
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = tr.resultFpReg, labelSymbol = symbol)
}
@@ -987,13 +987,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
addToResult(result, tr, tr.resultReg, -1)
val ins = if(signed) {
if(knownAddress!=null)
IRInstruction(Opcode.DIVSM, vmDt, reg1 = tr.resultReg, value = knownAddress)
IRInstruction(Opcode.DIVSM, vmDt, reg1 = tr.resultReg, address = knownAddress)
else
IRInstruction(Opcode.DIVSM, vmDt, reg1 = tr.resultReg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRInstruction(Opcode.DIVM, vmDt, reg1 = tr.resultReg, value = knownAddress)
IRInstruction(Opcode.DIVM, vmDt, reg1 = tr.resultReg, address = knownAddress)
else
IRInstruction(Opcode.DIVM, vmDt, reg1 = tr.resultReg, labelSymbol = symbol)
}
@@ -1014,7 +1014,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val tr = translateExpression(operand)
addToResult(result, tr, -1, tr.resultFpReg)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.MULM, vmDt, fpReg1 = tr.resultFpReg, value = knownAddress)
IRInstruction(Opcode.MULM, vmDt, fpReg1 = tr.resultFpReg, address = knownAddress)
else
IRInstruction(Opcode.MULM, vmDt, fpReg1 = tr.resultFpReg, labelSymbol = symbol)
, null)
@@ -1027,7 +1027,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.MULM, vmDt, reg1=tr.resultReg, value = knownAddress)
IRInstruction(Opcode.MULM, vmDt, reg1=tr.resultReg, address = knownAddress)
else
IRInstruction(Opcode.MULM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
@@ -1041,7 +1041,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(vmDt==IRDataType.FLOAT) {
if((operand as? PtNumber)?.number==1.0) {
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
IRInstruction(Opcode.DECM, vmDt, address = knownAddress)
else
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
, null)
@@ -1050,7 +1050,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val tr = translateExpression(operand)
addToResult(result, tr, -1, tr.resultFpReg)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.SUBM, vmDt, fpReg1=tr.resultFpReg, value=knownAddress)
IRInstruction(Opcode.SUBM, vmDt, fpReg1=tr.resultFpReg, address = knownAddress)
else
IRInstruction(Opcode.SUBM, vmDt, fpReg1=tr.resultFpReg, labelSymbol = symbol)
, null)
@@ -1058,7 +1058,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} else {
if((operand as? PtNumber)?.number==1.0) {
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
IRInstruction(Opcode.DECM, vmDt, address = knownAddress)
else
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
, null)
@@ -1067,7 +1067,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.SUBM, vmDt, reg1=tr.resultReg, value = knownAddress)
IRInstruction(Opcode.SUBM, vmDt, reg1=tr.resultReg, address = knownAddress)
else
IRInstruction(Opcode.SUBM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
@@ -1081,7 +1081,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(vmDt==IRDataType.FLOAT) {
if((operand as? PtNumber)?.number==1.0) {
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.INCM, vmDt, value = knownAddress)
IRInstruction(Opcode.INCM, vmDt, address = knownAddress)
else
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
, null)
@@ -1090,7 +1090,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val tr = translateExpression(operand)
addToResult(result, tr, -1, tr.resultFpReg)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.ADDM, vmDt, fpReg1=tr.resultFpReg, value = knownAddress)
IRInstruction(Opcode.ADDM, vmDt, fpReg1=tr.resultFpReg, address = knownAddress)
else
IRInstruction(Opcode.ADDM, vmDt, fpReg1=tr.resultFpReg, labelSymbol = symbol)
, null)
@@ -1098,7 +1098,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} else {
if((operand as? PtNumber)?.number==1.0) {
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.INCM, vmDt, value = knownAddress)
IRInstruction(Opcode.INCM, vmDt, address = knownAddress)
else
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
, null)
@@ -1107,7 +1107,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.ADDM, vmDt, reg1=tr.resultReg, value=knownAddress)
IRInstruction(Opcode.ADDM, vmDt, reg1=tr.resultReg, address = knownAddress)
else
IRInstruction(Opcode.ADDM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
@@ -1121,7 +1121,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if(codeGen.isOne(operand)) {
val opc = if (signed) Opcode.ASRM else Opcode.LSRM
val ins = if(knownAddress!=null)
IRInstruction(opc, vmDt, value=knownAddress)
IRInstruction(opc, vmDt, address = knownAddress)
else
IRInstruction(opc, vmDt, labelSymbol = symbol)
addInstr(result, ins, null)
@@ -1130,7 +1130,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
addToResult(result, tr, tr.resultReg, -1)
val opc = if (signed) Opcode.ASRNM else Opcode.LSRNM
val ins = if(knownAddress!=null)
IRInstruction(opc, vmDt, reg1 = tr.resultReg, value=knownAddress)
IRInstruction(opc, vmDt, reg1 = tr.resultReg, address = knownAddress)
else
IRInstruction(opc, vmDt, reg1 = tr.resultReg, labelSymbol = symbol)
addInstr(result, ins, null)
@@ -1142,7 +1142,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val result = mutableListOf<IRCodeChunkBase>()
if(codeGen.isOne(operand)){
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.LSLM, vmDt, value=knownAddress)
IRInstruction(Opcode.LSLM, vmDt, address = knownAddress)
else
IRInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol)
, null)
@@ -1150,7 +1150,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.LSLNM, vmDt, reg1=tr.resultReg, value=knownAddress)
IRInstruction(Opcode.LSLNM, vmDt, reg1=tr.resultReg, address = knownAddress)
else
IRInstruction(Opcode.LSLNM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
,null)
@@ -1163,7 +1163,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.XORM, vmDt, reg1=tr.resultReg, value = knownAddress)
IRInstruction(Opcode.XORM, vmDt, reg1=tr.resultReg, address = knownAddress)
else
IRInstruction(Opcode.XORM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
,null)
@@ -1178,15 +1178,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if (knownAddress != null) {
// @(address) = @(address) %= operand
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = resultReg, value = knownAddress)
it += IRInstruction(Opcode.MOD, vmDt, reg1 = resultReg, value = number)
it += IRInstruction(Opcode.STOREM, vmDt, reg1 = resultReg, value = knownAddress)
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = resultReg, address = knownAddress)
it += IRInstruction(Opcode.MOD, vmDt, reg1 = resultReg, immediate = number)
it += IRInstruction(Opcode.STOREM, vmDt, reg1 = resultReg, address = knownAddress)
}
} else {
// symbol = symbol %= operand
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = resultReg, labelSymbol = symbol)
it += IRInstruction(Opcode.MOD, vmDt, reg1 = resultReg, value = number)
it += IRInstruction(Opcode.MOD, vmDt, reg1 = resultReg, immediate = number)
it += IRInstruction(Opcode.STOREM, vmDt, reg1 = resultReg, labelSymbol = symbol)
}
}
@@ -1196,9 +1196,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if (knownAddress != null) {
// @(address) = @(address) %= operand
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = resultReg, value = knownAddress)
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = resultReg, address = knownAddress)
it += IRInstruction(Opcode.MODR, vmDt, reg1 = resultReg, reg2 = tr.resultReg)
it += IRInstruction(Opcode.STOREM, vmDt, reg1 = resultReg, value = knownAddress)
it += IRInstruction(Opcode.STOREM, vmDt, reg1 = resultReg, address = knownAddress)
}
} else {
// symbol = symbol %= operand
@@ -1279,16 +1279,16 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if (knownAddress != null) {
// in-place modify a memory location
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = valueReg, value = knownAddress)
it += IRInstruction(Opcode.LOAD, vmDt, reg1=numberReg, value=operand.number.toInt())
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = valueReg, address = knownAddress)
it += IRInstruction(Opcode.LOAD, vmDt, reg1=numberReg, immediate = operand.number.toInt())
it += IRInstruction(compareAndSetOpcode, vmDt, reg1 = valueReg, reg2 = numberReg)
it += IRInstruction(Opcode.STOREM, vmDt, reg1 = valueReg, value = knownAddress)
it += IRInstruction(Opcode.STOREM, vmDt, reg1 = valueReg, address = knownAddress)
}
} else {
// in-place modify a symbol (variable)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = valueReg, labelSymbol = symbol)
it += IRInstruction(Opcode.LOAD, vmDt, reg1=numberReg, value=operand.number.toInt())
it += IRInstruction(Opcode.LOAD, vmDt, reg1=numberReg, immediate = operand.number.toInt())
it += IRInstruction(compareAndSetOpcode, vmDt, reg1 = valueReg, reg2 = numberReg)
it += IRInstruction(Opcode.STOREM, vmDt, reg1 = valueReg, labelSymbol = symbol)
}
@@ -1299,9 +1299,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if (knownAddress != null) {
// in-place modify a memory location
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = valueReg, value = knownAddress)
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = valueReg, address = knownAddress)
it += IRInstruction(compareAndSetOpcode, vmDt, reg1 = valueReg, reg2 = tr.resultReg)
it += IRInstruction(Opcode.STOREM, vmDt, reg1 = valueReg, value = knownAddress)
it += IRInstruction(Opcode.STOREM, vmDt, reg1 = valueReg, address = knownAddress)
}
} else {
// in-place modify a symbol (variable)
@@ -1330,21 +1330,21 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if (knownAddress != null) {
// in-place modify a memory location
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1 = valueReg, value = knownAddress)
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = numberReg, fpValue = operand.number.toFloat())
it += IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1 = valueReg, address = knownAddress)
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = numberReg, immediateFp = operand.number.toFloat())
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=cmpReg, fpReg1 = valueReg, fpReg2 = numberReg)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroReg, value=0)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroReg, immediate = 0)
it += IRInstruction(compareAndSetOpcode, IRDataType.BYTE, reg1=cmpReg, reg2=zeroReg)
it += IRInstruction(Opcode.FFROMUB, IRDataType.FLOAT, reg1=cmpReg, fpReg1 = valueReg)
it += IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = valueReg, value=knownAddress)
it += IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = valueReg, address = knownAddress)
}
} else {
// in-place modify a symbol (variable)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1 = valueReg, labelSymbol = symbol)
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = numberReg, fpValue = operand.number.toFloat())
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = numberReg, immediateFp = operand.number.toFloat())
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=cmpReg, fpReg1 = valueReg, fpReg2 = numberReg)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroReg, value=0)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroReg, immediate = 0)
it += IRInstruction(compareAndSetOpcode, IRDataType.BYTE, reg1=cmpReg, reg2=zeroReg)
it += IRInstruction(Opcode.FFROMUB, IRDataType.FLOAT, reg1=cmpReg, fpReg1 = valueReg)
it += IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = valueReg, labelSymbol = symbol)
@@ -1356,19 +1356,19 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
if (knownAddress != null) {
// in-place modify a memory location
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1 = valueReg, value = knownAddress)
it += IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1 = valueReg, address = knownAddress)
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=cmpReg, fpReg1 = valueReg, fpReg2 = tr.resultFpReg)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroReg, value=0)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroReg, immediate = 0)
it += IRInstruction(compareAndSetOpcode, IRDataType.BYTE, reg1=cmpReg, reg2=zeroReg)
it += IRInstruction(Opcode.FFROMUB, IRDataType.FLOAT, reg1=cmpReg, fpReg1 = valueReg)
it += IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = valueReg, value=knownAddress)
it += IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = valueReg, address = knownAddress)
}
} else {
// in-place modify a symbol (variable)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1 = valueReg, labelSymbol = symbol)
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=cmpReg, fpReg1 = valueReg, fpReg2 = tr.resultFpReg)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroReg, value=0)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroReg, immediate = 0)
it += IRInstruction(compareAndSetOpcode, IRDataType.BYTE, reg1=cmpReg, reg2=zeroReg)
it += IRInstruction(Opcode.FFROMUB, IRDataType.FLOAT, reg1=cmpReg, fpReg1 = valueReg)
it += IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = valueReg, labelSymbol = symbol)
@@ -185,7 +185,9 @@ class IRCodeGen(
old.reg2,
old.fpReg1,
old.fpReg2,
it.third.toInt(),
null,
null,
address = it.third.toInt(),
null,
null
)
@@ -314,14 +316,14 @@ class IRCodeGen(
val address = goto.address?.toInt()
if(address!=null) {
val branchIns = when(branch.condition) {
BranchCondition.CS -> IRInstruction(Opcode.BSTCS, value = address)
BranchCondition.CC -> IRInstruction(Opcode.BSTCC, value = address)
BranchCondition.EQ, BranchCondition.Z -> IRInstruction(Opcode.BSTEQ, value = address)
BranchCondition.NE, BranchCondition.NZ -> IRInstruction(Opcode.BSTNE, value = address)
BranchCondition.MI, BranchCondition.NEG -> IRInstruction(Opcode.BSTNEG, value = address)
BranchCondition.PL, BranchCondition.POS -> IRInstruction(Opcode.BSTPOS, value = address)
BranchCondition.VC -> IRInstruction(Opcode.BSTVC, value = address)
BranchCondition.VS -> IRInstruction(Opcode.BSTVS, value = address)
BranchCondition.CS -> IRInstruction(Opcode.BSTCS, address = address)
BranchCondition.CC -> IRInstruction(Opcode.BSTCC, address = address)
BranchCondition.EQ, BranchCondition.Z -> IRInstruction(Opcode.BSTEQ, address = address)
BranchCondition.NE, BranchCondition.NZ -> IRInstruction(Opcode.BSTNE, address = address)
BranchCondition.MI, BranchCondition.NEG -> IRInstruction(Opcode.BSTNEG, address = address)
BranchCondition.PL, BranchCondition.POS -> IRInstruction(Opcode.BSTPOS, address = address)
BranchCondition.VC -> IRInstruction(Opcode.BSTVC, address = address)
BranchCondition.VS -> IRInstruction(Opcode.BSTVS, address = address)
}
addInstr(result, branchIns, null)
} else {
@@ -420,7 +422,7 @@ class IRCodeGen(
val choiceReg = registers.nextFree()
if(values.size==1) {
val chunk = IRCodeChunk(null, null)
chunk += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=values[0].number.toInt())
chunk += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, immediate = values[0].number.toInt())
chunk += IRInstruction(Opcode.BNE, valueDt, reg1=valueTr.resultReg, reg2=choiceReg, labelSymbol = skipLabel)
result += chunk
result += translateNode(choice.statements)
@@ -430,7 +432,7 @@ class IRCodeGen(
val matchLabel = createLabelName()
val chunk = IRCodeChunk(null, null)
for (value in values) {
chunk += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=value.number.toInt())
chunk += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, immediate = value.number.toInt())
chunk += IRInstruction(Opcode.BEQ, valueDt, reg1=valueTr.resultReg, reg2=choiceReg, labelSymbol = matchLabel)
}
chunk += IRInstruction(Opcode.JUMP, labelSymbol = skipLabel)
@@ -467,7 +469,7 @@ class IRCodeGen(
val endLabel = createLabelName()
if(iterableVar.dt==DataType.STR) {
// iterate over a zero-terminated string
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0), null)
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, immediate = 0), null)
val chunk = IRCodeChunk(loopLabel, null)
chunk += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpReg, reg2=indexReg, labelSymbol = iterable.name)
chunk += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=tmpReg, labelSymbol = endLabel)
@@ -487,8 +489,8 @@ class IRCodeGen(
if(lengthBytes<256) {
val lengthReg = registers.nextFree()
val chunk = IRCodeChunk(null, null)
chunk += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0)
chunk += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=lengthReg, value=lengthBytes)
chunk += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, immediate = 0)
chunk += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=lengthReg, immediate = lengthBytes)
result += chunk
val chunk2 = IRCodeChunk(loopLabel, null)
chunk2 += IRInstruction(Opcode.LOADX, irType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=iterable.name)
@@ -498,7 +500,7 @@ class IRCodeGen(
result += addConstReg(IRDataType.BYTE, indexReg, elementSize)
addInstr(result, IRInstruction(Opcode.BNE, IRDataType.BYTE, reg1=indexReg, reg2=lengthReg, labelSymbol = loopLabel), null)
} else if(lengthBytes==256) {
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0), null)
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, immediate = 0), null)
val chunk = IRCodeChunk(loopLabel, null)
chunk += IRInstruction(Opcode.LOADX, irType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=iterable.name)
chunk += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
@@ -578,11 +580,11 @@ class IRCodeGen(
val chunk = IRCodeChunk(null, null)
if(rangeEndWrapped!=0) {
endvalueReg = registers.nextFree()
chunk += IRInstruction(Opcode.LOAD, loopvarDtIr, reg1 = endvalueReg, value = rangeEndWrapped)
chunk += IRInstruction(Opcode.LOAD, loopvarDtIr, reg1 = endvalueReg, immediate = rangeEndWrapped)
} else {
endvalueReg = -1 // not used
}
chunk += IRInstruction(Opcode.LOAD, loopvarDtIr, reg1=indexReg, value=rangeStart)
chunk += IRInstruction(Opcode.LOAD, loopvarDtIr, reg1=indexReg, immediate = rangeStart)
chunk += IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=indexReg, labelSymbol=loopvarSymbol)
result += chunk
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel)
@@ -618,9 +620,9 @@ class IRCodeGen(
}
else -> {
code += if(value>0) {
IRInstruction(Opcode.ADD, dt, reg1 = reg, value=value)
IRInstruction(Opcode.ADD, dt, reg1 = reg, immediate = value)
} else {
IRInstruction(Opcode.SUB, dt, reg1 = reg, value=-value)
IRInstruction(Opcode.SUB, dt, reg1 = reg, immediate = -value)
}
}
}
@@ -633,14 +635,14 @@ class IRCodeGen(
0 -> { /* do nothing */ }
1 -> {
code += if(knownAddress!=null)
IRInstruction(Opcode.INCM, dt, value=knownAddress.toInt())
IRInstruction(Opcode.INCM, dt, address = knownAddress.toInt())
else
IRInstruction(Opcode.INCM, dt, labelSymbol = symbol)
}
2 -> {
if(knownAddress!=null) {
code += IRInstruction(Opcode.INCM, dt, value = knownAddress.toInt())
code += IRInstruction(Opcode.INCM, dt, value = knownAddress.toInt())
code += IRInstruction(Opcode.INCM, dt, address = knownAddress.toInt())
code += IRInstruction(Opcode.INCM, dt, address = knownAddress.toInt())
} else {
code += IRInstruction(Opcode.INCM, dt, labelSymbol = symbol)
code += IRInstruction(Opcode.INCM, dt, labelSymbol = symbol)
@@ -648,14 +650,14 @@ class IRCodeGen(
}
-1 -> {
code += if(knownAddress!=null)
IRInstruction(Opcode.DECM, dt, value=knownAddress.toInt())
IRInstruction(Opcode.DECM, dt, address = knownAddress.toInt())
else
IRInstruction(Opcode.DECM, dt, labelSymbol = symbol)
}
-2 -> {
if(knownAddress!=null) {
code += IRInstruction(Opcode.DECM, dt, value = knownAddress.toInt())
code += IRInstruction(Opcode.DECM, dt, value = knownAddress.toInt())
code += IRInstruction(Opcode.DECM, dt, address = knownAddress.toInt())
code += IRInstruction(Opcode.DECM, dt, address = knownAddress.toInt())
} else {
code += IRInstruction(Opcode.DECM, dt, labelSymbol = symbol)
code += IRInstruction(Opcode.DECM, dt, labelSymbol = symbol)
@@ -664,16 +666,16 @@ class IRCodeGen(
else -> {
val valueReg = registers.nextFree()
if(value>0) {
code += IRInstruction(Opcode.LOAD, dt, reg1=valueReg, value=value)
code += IRInstruction(Opcode.LOAD, dt, reg1=valueReg, immediate = value)
code += if(knownAddress!=null)
IRInstruction(Opcode.ADDM, dt, reg1=valueReg, value=knownAddress.toInt())
IRInstruction(Opcode.ADDM, dt, reg1=valueReg, address = knownAddress.toInt())
else
IRInstruction(Opcode.ADDM, dt, reg1=valueReg, labelSymbol = symbol)
}
else {
code += IRInstruction(Opcode.LOAD, dt, reg1=valueReg, value=-value)
code += IRInstruction(Opcode.LOAD, dt, reg1=valueReg, immediate = -value)
code += if(knownAddress!=null)
IRInstruction(Opcode.SUBM, dt, reg1=valueReg, value=knownAddress.toInt())
IRInstruction(Opcode.SUBM, dt, reg1=valueReg, address = knownAddress.toInt())
else
IRInstruction(Opcode.SUBM, dt, reg1=valueReg, labelSymbol = symbol)
}
@@ -687,9 +689,9 @@ class IRCodeGen(
if(factor==1f)
return code
code += if(factor==0f) {
IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = fpReg, fpValue = 0f)
IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = fpReg, immediateFp = 0f)
} else {
IRInstruction(Opcode.MUL, IRDataType.FLOAT, fpReg1 = fpReg, fpValue=factor)
IRInstruction(Opcode.MUL, IRDataType.FLOAT, fpReg1 = fpReg, immediateFp = factor)
}
return code
}
@@ -700,14 +702,14 @@ class IRCodeGen(
return code
if(factor==0f) {
code += if(knownAddress!=null)
IRInstruction(Opcode.STOREZM, IRDataType.FLOAT, value = knownAddress)
IRInstruction(Opcode.STOREZM, IRDataType.FLOAT, address = knownAddress)
else
IRInstruction(Opcode.STOREZM, IRDataType.FLOAT, labelSymbol = symbol)
} else {
val factorReg = registers.nextFreeFloat()
code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1=factorReg, fpValue = factor)
code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1=factorReg, immediateFp = factor)
code += if(knownAddress!=null)
IRInstruction(Opcode.MULM, IRDataType.FLOAT, fpReg1 = factorReg, value = knownAddress)
IRInstruction(Opcode.MULM, IRDataType.FLOAT, fpReg1 = factorReg, address = knownAddress)
else
IRInstruction(Opcode.MULM, IRDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol)
}
@@ -728,13 +730,13 @@ class IRCodeGen(
else if(pow2>=1) {
// just shift multiple bits
val pow2reg = registers.nextFree()
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, immediate = pow2)
code += IRInstruction(Opcode.LSLN, dt, reg1=reg, reg2=pow2reg)
} else {
code += if (factor == 0) {
IRInstruction(Opcode.LOAD, dt, reg1=reg, value=0)
IRInstruction(Opcode.LOAD, dt, reg1=reg, immediate = 0)
} else {
IRInstruction(Opcode.MUL, dt, reg1=reg, value=factor)
IRInstruction(Opcode.MUL, dt, reg1=reg, immediate = factor)
}
}
return code
@@ -748,30 +750,30 @@ class IRCodeGen(
if(pow2==1) {
// just shift 1 bit
code += if(knownAddress!=null)
IRInstruction(Opcode.LSLM, dt, value = knownAddress)
IRInstruction(Opcode.LSLM, dt, address = knownAddress)
else
IRInstruction(Opcode.LSLM, dt, labelSymbol = symbol)
}
else if(pow2>=1) {
// just shift multiple bits
val pow2reg = registers.nextFree()
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, immediate = pow2)
code += if(knownAddress!=null)
IRInstruction(Opcode.LSLNM, dt, reg1=pow2reg, value=knownAddress)
IRInstruction(Opcode.LSLNM, dt, reg1=pow2reg, address = knownAddress)
else
IRInstruction(Opcode.LSLNM, dt, reg1=pow2reg, labelSymbol = symbol)
} else {
if (factor == 0) {
code += if(knownAddress!=null)
IRInstruction(Opcode.STOREZM, dt, value=knownAddress)
IRInstruction(Opcode.STOREZM, dt, address = knownAddress)
else
IRInstruction(Opcode.STOREZM, dt, labelSymbol = symbol)
}
else {
val factorReg = registers.nextFree()
code += IRInstruction(Opcode.LOAD, dt, reg1=factorReg, value = factor)
code += IRInstruction(Opcode.LOAD, dt, reg1=factorReg, immediate = factor)
code += if(knownAddress!=null)
IRInstruction(Opcode.MULM, dt, reg1=factorReg, value = knownAddress)
IRInstruction(Opcode.MULM, dt, reg1=factorReg, address = knownAddress)
else
IRInstruction(Opcode.MULM, dt, reg1=factorReg, labelSymbol = symbol)
}
@@ -784,9 +786,9 @@ class IRCodeGen(
if(factor==1f)
return code
code += if(factor==0f) {
IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = fpReg, fpValue = Float.MAX_VALUE)
IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = fpReg, immediateFp = Float.MAX_VALUE)
} else {
IRInstruction(Opcode.DIVS, IRDataType.FLOAT, fpReg1 = fpReg, fpValue=factor)
IRInstruction(Opcode.DIVS, IRDataType.FLOAT, fpReg1 = fpReg, immediateFp = factor)
}
return code
}
@@ -797,16 +799,16 @@ class IRCodeGen(
return code
if(factor==0f) {
val maxvalueReg = registers.nextFreeFloat()
code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = maxvalueReg, fpValue = Float.MAX_VALUE)
code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = maxvalueReg, immediateFp = Float.MAX_VALUE)
code += if(knownAddress!=null)
IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = maxvalueReg, value=knownAddress)
IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = maxvalueReg, address = knownAddress)
else
IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = maxvalueReg, labelSymbol = symbol)
} else {
val factorReg = registers.nextFreeFloat()
code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1=factorReg, fpValue = factor)
code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1=factorReg, immediateFp = factor)
code += if(knownAddress!=null)
IRInstruction(Opcode.DIVSM, IRDataType.FLOAT, fpReg1 = factorReg, value=knownAddress)
IRInstruction(Opcode.DIVSM, IRDataType.FLOAT, fpReg1 = factorReg, address = knownAddress)
else
IRInstruction(Opcode.DIVSM, IRDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol)
}
@@ -824,19 +826,19 @@ class IRCodeGen(
else if(pow2>=1 &&!signed) {
// just shift multiple bits
val pow2reg = registers.nextFree()
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, immediate = pow2)
code += if(signed)
IRInstruction(Opcode.ASRN, dt, reg1=reg, reg2=pow2reg)
else
IRInstruction(Opcode.LSRN, dt, reg1=reg, reg2=pow2reg)
} else {
code += if (factor == 0) {
IRInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
IRInstruction(Opcode.LOAD, dt, reg1=reg, immediate = 0xffff)
} else {
if(signed)
IRInstruction(Opcode.DIVS, dt, reg1=reg, value=factor)
IRInstruction(Opcode.DIVS, dt, reg1=reg, immediate = factor)
else
IRInstruction(Opcode.DIV, dt, reg1=reg, value=factor)
IRInstruction(Opcode.DIV, dt, reg1=reg, immediate = factor)
}
}
return code
@@ -850,47 +852,47 @@ class IRCodeGen(
if(pow2==1 && !signed) {
// just simple bit shift
code += if(knownAddress!=null)
IRInstruction(Opcode.LSRM, dt, value=knownAddress)
IRInstruction(Opcode.LSRM, dt, address = knownAddress)
else
IRInstruction(Opcode.LSRM, dt, labelSymbol = symbol)
}
else if(pow2>=1 && !signed) {
// just shift multiple bits
val pow2reg = registers.nextFree()
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, immediate = pow2)
code += if(signed) {
if(knownAddress!=null)
IRInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, value = knownAddress)
IRInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, address = knownAddress)
else
IRInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, value = knownAddress)
IRInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, address = knownAddress)
else
IRInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, labelSymbol = symbol)
}
} else {
if (factor == 0) {
val reg = registers.nextFree()
code += IRInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
code += IRInstruction(Opcode.LOAD, dt, reg1=reg, immediate = 0xffff)
code += if(knownAddress!=null)
IRInstruction(Opcode.STOREM, dt, reg1=reg, value=knownAddress)
IRInstruction(Opcode.STOREM, dt, reg1=reg, address = knownAddress)
else
IRInstruction(Opcode.STOREM, dt, reg1=reg, labelSymbol = symbol)
}
else {
val factorReg = registers.nextFree()
code += IRInstruction(Opcode.LOAD, dt, reg1=factorReg, value= factor)
code += IRInstruction(Opcode.LOAD, dt, reg1=factorReg, immediate = factor)
code += if(signed) {
if(knownAddress!=null)
IRInstruction(Opcode.DIVSM, dt, reg1 = factorReg, value = knownAddress)
IRInstruction(Opcode.DIVSM, dt, reg1 = factorReg, address = knownAddress)
else
IRInstruction(Opcode.DIVSM, dt, reg1 = factorReg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRInstruction(Opcode.DIVM, dt, reg1 = factorReg, value = knownAddress)
IRInstruction(Opcode.DIVM, dt, reg1 = factorReg, address = knownAddress)
else
IRInstruction(Opcode.DIVM, dt, reg1 = factorReg, labelSymbol = symbol)
}
@@ -968,7 +970,7 @@ class IRCodeGen(
gotoOpcode,
IRDataType.BYTE,
reg1 = compResultReg,
value = goto.address?.toInt()
address = goto.address?.toInt()
)
else if (goto.generatedLabel != null)
IRInstruction(
@@ -1018,7 +1020,7 @@ class IRCodeGen(
else -> throw AssemblyError("invalid comparison operator")
}
if (goto.address != null)
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = leftTr.resultReg, value = goto.address?.toInt()), null)
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = leftTr.resultReg, address = goto.address?.toInt()), null)
else if (goto.generatedLabel != null)
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = leftTr.resultReg, labelSymbol = goto.generatedLabel), null)
else
@@ -1037,7 +1039,7 @@ class IRCodeGen(
val tr = expressionEval.translateExpression(ifElse.condition)
result += tr.chunks
if (goto.address != null)
addInstr(result, IRInstruction(Opcode.BNZ, irDtLeft, reg1 = tr.resultReg, value = goto.address?.toInt()), null)
addInstr(result, IRInstruction(Opcode.BNZ, irDtLeft, reg1 = tr.resultReg, address = goto.address?.toInt()), null)
else if (goto.generatedLabel != null)
addInstr(result, IRInstruction(Opcode.BNZ, irDtLeft, reg1 = tr.resultReg, labelSymbol = goto.generatedLabel), null)
else
@@ -1086,7 +1088,7 @@ class IRCodeGen(
else -> throw AssemblyError("invalid comparison operator")
}
if (goto.address != null)
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, value = goto.address?.toInt()), null)
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, address = goto.address?.toInt()), null)
else if (goto.generatedLabel != null)
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, labelSymbol = goto.generatedLabel), null)
else
@@ -1107,7 +1109,7 @@ class IRCodeGen(
addToResult(result, leftTr, -1, leftTr.resultFpReg)
result += IRCodeChunk(null, null).also {
val rightFpReg = registers.nextFreeFloat()
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = rightFpReg, fpValue = 0f)
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = rightFpReg, immediateFp = 0f)
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightFpReg)
}
elseBranch = when (condition.operator) {
@@ -1341,7 +1343,7 @@ class IRCodeGen(
} else if(memory!=null) {
if(memory.address is PtNumber) {
val address = (memory.address as PtNumber).number.toInt()
addInstr(result, IRInstruction(operationMem, irDt, value = address), null)
addInstr(result, IRInstruction(operationMem, irDt, address = address), null)
} else {
val tr = expressionEval.translateExpression(memory.address)
addToResult(result, tr, tr.resultReg, -1)
@@ -1404,7 +1406,7 @@ class IRCodeGen(
private fun translate(jump: PtJump): IRCodeChunks {
val result = mutableListOf<IRCodeChunkBase>()
val instr = if(jump.address!=null) {
IRInstruction(Opcode.JUMPA, value = jump.address!!.toInt())
IRInstruction(Opcode.JUMPA, address = jump.address!!.toInt())
} else {
if (jump.generatedLabel != null)
IRInstruction(Opcode.JUMP, labelSymbol = jump.generatedLabel!!)
@@ -205,7 +205,7 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
if(idx>0 && ins.opcode==Opcode.RETURN) {
val previous = chunk.instructions[idx-1]
if(previous.opcode==Opcode.CALL || previous.opcode==Opcode.CALLRVAL) {
chunk.instructions[idx-1] = IRInstruction(Opcode.JUMP, value=previous.value, labelSymbol = previous.labelSymbol, branchTarget = previous.branchTarget)
chunk.instructions[idx-1] = IRInstruction(Opcode.JUMP, address = previous.address, labelSymbol = previous.labelSymbol, branchTarget = previous.branchTarget)
chunk.instructions.removeAt(idx)
changed = true
}
@@ -220,47 +220,47 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
indexedInstructions.reversed().forEach { (idx, ins) ->
when (ins.opcode) {
Opcode.DIV, Opcode.DIVS, Opcode.MUL, Opcode.MOD -> {
if (ins.value == 1) {
if (ins.immediate == 1) {
chunk.instructions.removeAt(idx)
changed = true
}
}
Opcode.ADD, Opcode.SUB -> {
if (ins.value == 1) {
if (ins.immediate == 1) {
chunk.instructions[idx] = IRInstruction(
if (ins.opcode == Opcode.ADD) Opcode.INC else Opcode.DEC,
ins.type,
ins.reg1
)
changed = true
} else if (ins.value == 0) {
} else if (ins.immediate == 0) {
chunk.instructions.removeAt(idx)
changed = true
}
}
Opcode.AND -> {
if (ins.value == 0) {
chunk.instructions[idx] = IRInstruction(Opcode.LOAD, ins.type, reg1 = ins.reg1, value = 0)
if (ins.immediate == 0) {
chunk.instructions[idx] = IRInstruction(Opcode.LOAD, ins.type, reg1 = ins.reg1, immediate = 0)
changed = true
} else if (ins.value == 255 && ins.type == IRDataType.BYTE) {
} else if (ins.immediate == 255 && ins.type == IRDataType.BYTE) {
chunk.instructions.removeAt(idx)
changed = true
} else if (ins.value == 65535 && ins.type == IRDataType.WORD) {
} else if (ins.immediate == 65535 && ins.type == IRDataType.WORD) {
chunk.instructions.removeAt(idx)
changed = true
}
}
Opcode.OR -> {
if (ins.value == 0) {
if (ins.immediate == 0) {
chunk.instructions.removeAt(idx)
changed = true
} else if ((ins.value == 255 && ins.type == IRDataType.BYTE) || (ins.value == 65535 && ins.type == IRDataType.WORD)) {
chunk.instructions[idx] = IRInstruction(Opcode.LOAD, ins.type, reg1 = ins.reg1, value = ins.value)
} else if ((ins.immediate == 255 && ins.type == IRDataType.BYTE) || (ins.immediate == 65535 && ins.type == IRDataType.WORD)) {
chunk.instructions[idx] = IRInstruction(Opcode.LOAD, ins.type, reg1 = ins.reg1, immediate = ins.immediate)
changed = true
}
}
Opcode.XOR -> {
if (ins.value == 0) {
if (ins.immediate == 0) {
chunk.instructions.removeAt(idx)
changed = true
}
+29 -29
View File
@@ -40,7 +40,7 @@ class TestIRPeepholeOpt: FunSpec({
test("remove nops") {
val irProg = makeIRProgram(listOf(
IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=1, value=42),
IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=1, immediate=42),
IRInstruction(Opcode.NOP),
IRInstruction(Opcode.NOP)
))
@@ -117,16 +117,16 @@ class TestIRPeepholeOpt: FunSpec({
test("remove useless div/mul, add/sub") {
val irProg = makeIRProgram(listOf(
IRInstruction(Opcode.DIV, IRDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.DIVS, IRDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.MUL, IRDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.MOD, IRDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.DIV, IRDataType.BYTE, reg1=42, value = 2),
IRInstruction(Opcode.DIVS, IRDataType.BYTE, reg1=42, value = 2),
IRInstruction(Opcode.MUL, IRDataType.BYTE, reg1=42, value = 2),
IRInstruction(Opcode.MOD, IRDataType.BYTE, reg1=42, value = 2),
IRInstruction(Opcode.ADD, IRDataType.BYTE, reg1=42, value = 0),
IRInstruction(Opcode.SUB, IRDataType.BYTE, reg1=42, value = 0)
IRInstruction(Opcode.DIV, IRDataType.BYTE, reg1=42, immediate = 1),
IRInstruction(Opcode.DIVS, IRDataType.BYTE, reg1=42, immediate = 1),
IRInstruction(Opcode.MUL, IRDataType.BYTE, reg1=42, immediate = 1),
IRInstruction(Opcode.MOD, IRDataType.BYTE, reg1=42, immediate = 1),
IRInstruction(Opcode.DIV, IRDataType.BYTE, reg1=42, immediate = 2),
IRInstruction(Opcode.DIVS, IRDataType.BYTE, reg1=42, immediate = 2),
IRInstruction(Opcode.MUL, IRDataType.BYTE, reg1=42, immediate = 2),
IRInstruction(Opcode.MOD, IRDataType.BYTE, reg1=42, immediate = 2),
IRInstruction(Opcode.ADD, IRDataType.BYTE, reg1=42, immediate = 0),
IRInstruction(Opcode.SUB, IRDataType.BYTE, reg1=42, immediate = 0)
))
irProg.chunks().single().instructions.size shouldBe 10
val opt = IRPeepholeOptimizer(irProg)
@@ -136,8 +136,8 @@ class TestIRPeepholeOpt: FunSpec({
test("replace add/sub 1 by inc/dec") {
val irProg = makeIRProgram(listOf(
IRInstruction(Opcode.ADD, IRDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.SUB, IRDataType.BYTE, reg1=42, value = 1)
IRInstruction(Opcode.ADD, IRDataType.BYTE, reg1=42, immediate = 1),
IRInstruction(Opcode.SUB, IRDataType.BYTE, reg1=42, immediate = 1)
))
irProg.chunks().single().instructions.size shouldBe 2
val opt = IRPeepholeOptimizer(irProg)
@@ -150,14 +150,14 @@ class TestIRPeepholeOpt: FunSpec({
test("remove useless and/or/xor") {
val irProg = makeIRProgram(listOf(
IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=42, value = 255),
IRInstruction(Opcode.AND, IRDataType.WORD, reg1=42, value = 65535),
IRInstruction(Opcode.OR, IRDataType.BYTE, reg1=42, value = 0),
IRInstruction(Opcode.XOR, IRDataType.BYTE, reg1=42, value = 0),
IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=42, value = 200),
IRInstruction(Opcode.AND, IRDataType.WORD, reg1=42, value = 60000),
IRInstruction(Opcode.OR, IRDataType.BYTE, reg1=42, value = 1),
IRInstruction(Opcode.XOR, IRDataType.BYTE, reg1=42, value = 1)
IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=42, immediate = 255),
IRInstruction(Opcode.AND, IRDataType.WORD, reg1=42, immediate = 65535),
IRInstruction(Opcode.OR, IRDataType.BYTE, reg1=42, immediate = 0),
IRInstruction(Opcode.XOR, IRDataType.BYTE, reg1=42, immediate = 0),
IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=42, immediate = 200),
IRInstruction(Opcode.AND, IRDataType.WORD, reg1=42, immediate = 60000),
IRInstruction(Opcode.OR, IRDataType.BYTE, reg1=42, immediate = 1),
IRInstruction(Opcode.XOR, IRDataType.BYTE, reg1=42, immediate = 1)
))
irProg.chunks().single().instructions.size shouldBe 8
val opt = IRPeepholeOptimizer(irProg)
@@ -167,10 +167,10 @@ class TestIRPeepholeOpt: FunSpec({
test("replace and/or/xor by constant number") {
val irProg = makeIRProgram(listOf(
IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=42, value = 0),
IRInstruction(Opcode.AND, IRDataType.WORD, reg1=42, value = 0),
IRInstruction(Opcode.OR, IRDataType.BYTE, reg1=42, value = 255),
IRInstruction(Opcode.OR, IRDataType.WORD, reg1=42, value = 65535)
IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=42, immediate = 0),
IRInstruction(Opcode.AND, IRDataType.WORD, reg1=42, immediate = 0),
IRInstruction(Opcode.OR, IRDataType.BYTE, reg1=42, immediate = 255),
IRInstruction(Opcode.OR, IRDataType.WORD, reg1=42, immediate = 65535)
))
irProg.chunks().single().instructions.size shouldBe 4
val opt = IRPeepholeOptimizer(irProg)
@@ -181,9 +181,9 @@ class TestIRPeepholeOpt: FunSpec({
instr[1].opcode shouldBe Opcode.LOAD
instr[2].opcode shouldBe Opcode.LOAD
instr[3].opcode shouldBe Opcode.LOAD
instr[0].value shouldBe 0
instr[1].value shouldBe 0
instr[2].value shouldBe 255
instr[3].value shouldBe 65535
instr[0].immediate shouldBe 0
instr[1].immediate shouldBe 0
instr[2].immediate shouldBe 255
instr[3].immediate shouldBe 65535
}
})
+1 -1
View File
@@ -468,6 +468,6 @@ class TestVmCodeGen: FunSpec({
irChunks.size shouldBe 1
val callInstr = irChunks.single().instructions.single()
callInstr.opcode shouldBe Opcode.CALL
callInstr.value shouldBe 0x5000
callInstr.address shouldBe 0x5000
}
})
+1
View File
@@ -12,6 +12,7 @@ generate:
p8compile -noopt -target cx16 *.p8 >/dev/null
test_prgs:
x16emu -run -prg more_compares.prg
for program in *.prg; do \
echo "RUNNING:" $$program ; \
x16emu -run -prg $$program >/dev/null ; \
+1
View File
@@ -3,6 +3,7 @@ TODO
For next minor release
^^^^^^^^^^^^^^^^^^^^^^
fix compiler crash on test/arithmethic/builtins.p8 and test the others as well
...
@@ -406,63 +406,6 @@ val OpcodesForCpuRegisters = setOf(
Opcode.STOREZCPU
)
val OpcodesWithMemoryAddressAsValue = setOf(
Opcode.LOADM,
Opcode.LOADX,
Opcode.LOADIX,
Opcode.STOREM,
Opcode.STOREX,
Opcode.STOREIX,
Opcode.STOREZM,
Opcode.STOREZX,
Opcode.JUMP,
Opcode.JUMPA,
Opcode.CALL,
Opcode.CALLRVAL,
Opcode.BSTCC,
Opcode.BSTCS,
Opcode.BSTEQ,
Opcode.BSTNE,
Opcode.BSTNEG,
Opcode.BSTPOS,
Opcode.BSTVC,
Opcode.BSTVS,
Opcode.BZ,
Opcode.BNZ,
Opcode.BGZS,
Opcode.BGEZS,
Opcode.BLZS,
Opcode.BLEZS,
Opcode.BEQ,
Opcode.BNE,
Opcode.BGT,
Opcode.BGTS,
Opcode.BGE,
Opcode.BGES,
Opcode.INCM,
Opcode.DECM,
Opcode.NEGM,
Opcode.ADDM,
Opcode.SUBM,
Opcode.MULM,
Opcode.DIVM,
Opcode.DIVSM,
Opcode.INVM,
Opcode.ORM,
Opcode.XORM,
Opcode.ANDM,
Opcode.ASRM,
Opcode.LSRM,
Opcode.LSLM,
Opcode.LSLNM,
Opcode.LSRNM,
Opcode.ASRNM,
Opcode.ROLM,
Opcode.RORM,
Opcode.ROXLM,
Opcode.ROXRM
)
enum class IRDataType {
BYTE,
WORD,
@@ -482,9 +425,8 @@ data class InstructionFormat(val datatype: IRDataType?,
val reg2: OperandDirection,
val fpReg1: OperandDirection,
val fpReg2: OperandDirection,
val valueIn: Boolean,
val fpValueIn: Boolean
) {
val address: OperandDirection,
val immediate: Boolean) {
companion object {
fun from(spec: String): Map<IRDataType?, InstructionFormat> {
val result = mutableMapOf<IRDataType?, InstructionFormat>()
@@ -493,8 +435,8 @@ data class InstructionFormat(val datatype: IRDataType?,
var reg2 = OperandDirection.UNUSED
var fpreg1 = OperandDirection.UNUSED
var fpreg2 = OperandDirection.UNUSED
var valueIn = false
var fpvalueIn = false
var address = OperandDirection.UNUSED
var immediate = false
val splits = part.splitToSequence(',').iterator()
val typespec = splits.next()
while(splits.hasNext()) {
@@ -507,23 +449,23 @@ data class InstructionFormat(val datatype: IRDataType?,
">fr1" -> { fpreg1=OperandDirection.WRITE }
"<>fr1" -> { fpreg1=OperandDirection.READWRITE }
"<fr2" -> fpreg2 = OperandDirection.READ
"<v" -> {
if('F' in typespec)
fpvalueIn = true
else
valueIn = true
}
">i", "<>i" -> throw IllegalArgumentException("can't write into an immediate value")
"<i" -> immediate = true
"<a" -> address = OperandDirection.READ
">a" -> address = OperandDirection.WRITE
"<>a" -> address = OperandDirection.READWRITE
else -> throw IllegalArgumentException(spec)
}
}
if(typespec=="N")
result[null] = InstructionFormat(null, reg1, reg2, fpreg1, fpreg2, valueIn, fpvalueIn)
result[null] = InstructionFormat(null, reg1, reg2, fpreg1, fpreg2, address, immediate)
if('B' in typespec)
result[IRDataType.BYTE] = InstructionFormat(IRDataType.BYTE, reg1, reg2, fpreg1, fpreg2, valueIn, fpvalueIn)
result[IRDataType.BYTE] = InstructionFormat(IRDataType.BYTE, reg1, reg2, fpreg1, fpreg2, address, immediate)
if('W' in typespec)
result[IRDataType.WORD] = InstructionFormat(IRDataType.WORD, reg1, reg2, fpreg1, fpreg2, valueIn, fpvalueIn)
result[IRDataType.WORD] = InstructionFormat(IRDataType.WORD, reg1, reg2, fpreg1, fpreg2, address, immediate)
if('F' in typespec)
result[IRDataType.FLOAT] = InstructionFormat(IRDataType.FLOAT, reg1, reg2, fpreg1, fpreg2, valueIn, fpvalueIn)
result[IRDataType.FLOAT] = InstructionFormat(IRDataType.FLOAT, reg1, reg2, fpreg1, fpreg2, address, immediate)
}
return result
}
@@ -534,54 +476,58 @@ data class InstructionFormat(val datatype: IRDataType?,
<X = X is not modified (readonly value)
>X = X is overwritten with output value (write value)
<>X = X is modified (read + written)
where X is one of:
r0... = integer register
fr0... = fp register
a = memory address
i = immediate value
TODO: also encode if *memory* is read/written/modified?
*/
@Suppress("BooleanLiteralArgument")
val instructionFormats = mutableMapOf(
Opcode.NOP to InstructionFormat.from("N"),
Opcode.LOAD to InstructionFormat.from("BW,>r1,<v | F,>fr1,<v"),
Opcode.LOADM to InstructionFormat.from("BW,>r1,<v | F,>fr1,<v"),
Opcode.LOAD to InstructionFormat.from("BW,>r1,<i | F,>fr1,<i"),
Opcode.LOADM to InstructionFormat.from("BW,>r1,<a | F,>fr1,<a"),
Opcode.LOADI to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<r1"),
Opcode.LOADX to InstructionFormat.from("BW,>r1,<r2,<v | F,>fr1,<r1,<v"),
Opcode.LOADIX to InstructionFormat.from("BW,>r1,<r2,<v | F,>fr1,<r1,<v"),
Opcode.LOADX to InstructionFormat.from("BW,>r1,<r2,<a | F,>fr1,<r1,<a"),
Opcode.LOADIX to InstructionFormat.from("BW,>r1,<r2,<a | F,>fr1,<r1,<a"),
Opcode.LOADR to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"),
Opcode.LOADCPU to InstructionFormat.from("BW,>r1"),
Opcode.STOREM to InstructionFormat.from("BW,<r1,<v | F,<fr1,<v"),
Opcode.STOREM to InstructionFormat.from("BW,<r1,>a | F,<fr1,>a"),
Opcode.STORECPU to InstructionFormat.from("BW,<r1"),
Opcode.STOREI to InstructionFormat.from("BW,<r1,<r2 | F,<fr1,<r1"),
Opcode.STOREX to InstructionFormat.from("BW,<r1,<r2,<v | F,<fr1,<r1,<v"),
Opcode.STOREIX to InstructionFormat.from("BW,<r1,<r2,<v | F,<fr1,<r1,<v"),
Opcode.STOREZM to InstructionFormat.from("BW,<v | F,<v"),
Opcode.STOREX to InstructionFormat.from("BW,<r1,<r2,>a | F,<fr1,<r1,>a"),
Opcode.STOREIX to InstructionFormat.from("BW,<r1,<r2,>a | F,<fr1,<r1,>a"),
Opcode.STOREZM to InstructionFormat.from("BW,>a | F,>a"),
Opcode.STOREZCPU to InstructionFormat.from("BW"),
Opcode.STOREZI to InstructionFormat.from("BW,<r1 | F,<r1"),
Opcode.STOREZX to InstructionFormat.from("BW,<r1,<v | F,<r1,<v"),
Opcode.JUMP to InstructionFormat.from("N,<v"),
Opcode.JUMPA to InstructionFormat.from("N,<v"),
Opcode.CALL to InstructionFormat.from("N,<v"),
Opcode.CALLRVAL to InstructionFormat.from("BW,<r1,<v | F,<fr1,<v"),
Opcode.SYSCALL to InstructionFormat.from("N,<v"),
Opcode.STOREZX to InstructionFormat.from("BW,<r1,>a | F,<r1,>a"),
Opcode.JUMP to InstructionFormat.from("N,<a"),
Opcode.JUMPA to InstructionFormat.from("N,<a"),
Opcode.CALL to InstructionFormat.from("N,<a"),
Opcode.CALLRVAL to InstructionFormat.from("BW,<r1,<a | F,<fr1,<a"),
Opcode.SYSCALL to InstructionFormat.from("N,<i"),
Opcode.RETURN to InstructionFormat.from("N"),
Opcode.RETURNREG to InstructionFormat.from("BW,<r1 | F,<fr1"),
Opcode.BSTCC to InstructionFormat.from("N,<v"),
Opcode.BSTCS to InstructionFormat.from("N,<v"),
Opcode.BSTEQ to InstructionFormat.from("N,<v"),
Opcode.BSTNE to InstructionFormat.from("N,<v"),
Opcode.BSTNEG to InstructionFormat.from("N,<v"),
Opcode.BSTPOS to InstructionFormat.from("N,<v"),
Opcode.BSTVC to InstructionFormat.from("N,<v"),
Opcode.BSTVS to InstructionFormat.from("N,<v"),
Opcode.BZ to InstructionFormat.from("BW,<r1,<v"),
Opcode.BNZ to InstructionFormat.from("BW,<r1,<v"),
Opcode.BGZS to InstructionFormat.from("BW,<r1,<v"),
Opcode.BGEZS to InstructionFormat.from("BW,<r1,<v"),
Opcode.BLZS to InstructionFormat.from("BW,<r1,<v"),
Opcode.BLEZS to InstructionFormat.from("BW,<r1,<v"),
Opcode.BEQ to InstructionFormat.from("BW,<r1,<r2,<v"),
Opcode.BNE to InstructionFormat.from("BW,<r1,<r2,<v"),
Opcode.BGT to InstructionFormat.from("BW,<r1,<r2,<v"),
Opcode.BGTS to InstructionFormat.from("BW,<r1,<r2,<v"),
Opcode.BGE to InstructionFormat.from("BW,<r1,<r2,<v"),
Opcode.BGES to InstructionFormat.from("BW,<r1,<r2,<v"),
Opcode.BSTCC to InstructionFormat.from("N,<a"),
Opcode.BSTCS to InstructionFormat.from("N,<a"),
Opcode.BSTEQ to InstructionFormat.from("N,<a"),
Opcode.BSTNE to InstructionFormat.from("N,<a"),
Opcode.BSTNEG to InstructionFormat.from("N,<a"),
Opcode.BSTPOS to InstructionFormat.from("N,<a"),
Opcode.BSTVC to InstructionFormat.from("N,<a"),
Opcode.BSTVS to InstructionFormat.from("N,<a"),
Opcode.BZ to InstructionFormat.from("BW,<r1,<a"),
Opcode.BNZ to InstructionFormat.from("BW,<r1,<a"),
Opcode.BGZS to InstructionFormat.from("BW,<r1,<a"),
Opcode.BGEZS to InstructionFormat.from("BW,<r1,<a"),
Opcode.BLZS to InstructionFormat.from("BW,<r1,<a"),
Opcode.BLEZS to InstructionFormat.from("BW,<r1,<a"),
Opcode.BEQ to InstructionFormat.from("BW,<r1,<r2,<a"),
Opcode.BNE to InstructionFormat.from("BW,<r1,<r2,<a"),
Opcode.BGT to InstructionFormat.from("BW,<r1,<r2,<a"),
Opcode.BGTS to InstructionFormat.from("BW,<r1,<r2,<a"),
Opcode.BGE to InstructionFormat.from("BW,<r1,<r2,<a"),
Opcode.BGES to InstructionFormat.from("BW,<r1,<r2,<a"),
Opcode.SZ to InstructionFormat.from("BW,>r1,<r2"),
Opcode.SNZ to InstructionFormat.from("BW,>r1,<r2"),
Opcode.SEQ to InstructionFormat.from("BW,<>r1,<r2"),
@@ -595,66 +541,66 @@ val instructionFormats = mutableMapOf(
Opcode.SGE to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.SGES to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.INC to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
Opcode.INCM to InstructionFormat.from("BW,<v | F,<v"),
Opcode.INCM to InstructionFormat.from("BW,<>a | F,<>a"),
Opcode.DEC to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
Opcode.DECM to InstructionFormat.from("BW,<v | F,<v"),
Opcode.DECM to InstructionFormat.from("BW,<>a | F,<>a"),
Opcode.NEG to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
Opcode.NEGM to InstructionFormat.from("BW,<v | F,<v"),
Opcode.NEGM to InstructionFormat.from("BW,<>a | F,<>a"),
Opcode.ADDR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
Opcode.ADD to InstructionFormat.from("BW,<>r1,<v | F,<>fr1,<v"),
Opcode.ADDM to InstructionFormat.from("BW,<r1,<v | F,<fr1,<v"),
Opcode.ADD to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
Opcode.ADDM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
Opcode.SUBR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
Opcode.SUB to InstructionFormat.from("BW,<>r1,<v | F,<>fr1,<v"),
Opcode.SUBM to InstructionFormat.from("BW,<r1,<v | F,<fr1,<v"),
Opcode.SUB to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
Opcode.SUBM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
Opcode.MULR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
Opcode.MUL to InstructionFormat.from("BW,<>r1,<v | F,<>fr1,<v"),
Opcode.MULM to InstructionFormat.from("BW,<r1,<v | F,<fr1,<v"),
Opcode.MUL to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
Opcode.MULM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
Opcode.DIVR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.DIV to InstructionFormat.from("BW,<>r1,<v"),
Opcode.DIVM to InstructionFormat.from("BW,<r1,<v"),
Opcode.DIV to InstructionFormat.from("BW,<>r1,<i"),
Opcode.DIVM to InstructionFormat.from("BW,<r1,<>a"),
Opcode.DIVSR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
Opcode.DIVS to InstructionFormat.from("BW,<>r1,<v | F,<>fr1,<v"),
Opcode.DIVSM to InstructionFormat.from("BW,<r1,<v | F,<fr1,<v"),
Opcode.DIVS to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
Opcode.DIVSM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
Opcode.SQRT to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"),
Opcode.SGN to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"),
Opcode.MODR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.MOD to InstructionFormat.from("BW,<>r1,<v"),
Opcode.MOD to InstructionFormat.from("BW,<>r1,<i"),
Opcode.DIVMODR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.DIVMOD to InstructionFormat.from("BW,<>r1,<v"),
Opcode.DIVMOD to InstructionFormat.from("BW,<>r1,<i"),
Opcode.CMP to InstructionFormat.from("BW,<r1,<r2"),
Opcode.EXT to InstructionFormat.from("BW,<>r1"),
Opcode.EXTS to InstructionFormat.from("BW,<>r1"),
Opcode.ANDR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.AND to InstructionFormat.from("BW,<>r1,<v"),
Opcode.ANDM to InstructionFormat.from("BW,<r1,<v"),
Opcode.AND to InstructionFormat.from("BW,<>r1,<i"),
Opcode.ANDM to InstructionFormat.from("BW,<r1,<>a"),
Opcode.ORR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.OR to InstructionFormat.from("BW,<>r1,<v"),
Opcode.ORM to InstructionFormat.from("BW,<r1,<v"),
Opcode.OR to InstructionFormat.from("BW,<>r1,<i"),
Opcode.ORM to InstructionFormat.from("BW,<r1,<>a"),
Opcode.XORR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.XOR to InstructionFormat.from("BW,<>r1,<v"),
Opcode.XORM to InstructionFormat.from("BW,<r1,<v"),
Opcode.XOR to InstructionFormat.from("BW,<>r1,<i"),
Opcode.XORM to InstructionFormat.from("BW,<r1,<>a"),
Opcode.INV to InstructionFormat.from("BW,<>r1"),
Opcode.INVM to InstructionFormat.from("BW,<v"),
Opcode.INVM to InstructionFormat.from("BW,<>a"),
Opcode.ASRN to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.ASRNM to InstructionFormat.from("BW,<r1,<v"),
Opcode.ASRNM to InstructionFormat.from("BW,<r1,<>a"),
Opcode.LSRN to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.LSRNM to InstructionFormat.from("BW,<r1,<v"),
Opcode.LSRNM to InstructionFormat.from("BW,<r1,<>a"),
Opcode.LSLN to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.LSLNM to InstructionFormat.from("BW,<r1,<v"),
Opcode.LSLNM to InstructionFormat.from("BW,<r1,<>a"),
Opcode.ASR to InstructionFormat.from("BW,<>r1"),
Opcode.ASRM to InstructionFormat.from("BW,<v"),
Opcode.ASRM to InstructionFormat.from("BW,<>a"),
Opcode.LSR to InstructionFormat.from("BW,<>r1"),
Opcode.LSRM to InstructionFormat.from("BW,<v"),
Opcode.LSRM to InstructionFormat.from("BW,<>a"),
Opcode.LSL to InstructionFormat.from("BW,<>r1"),
Opcode.LSLM to InstructionFormat.from("BW,<v"),
Opcode.LSLM to InstructionFormat.from("BW,<>a"),
Opcode.ROR to InstructionFormat.from("BW,<>r1"),
Opcode.RORM to InstructionFormat.from("BW,<v"),
Opcode.RORM to InstructionFormat.from("BW,<>a"),
Opcode.ROXR to InstructionFormat.from("BW,<>r1"),
Opcode.ROXRM to InstructionFormat.from("BW,<v"),
Opcode.ROXRM to InstructionFormat.from("BW,<>a"),
Opcode.ROL to InstructionFormat.from("BW,<>r1"),
Opcode.ROLM to InstructionFormat.from("BW,<v"),
Opcode.ROLM to InstructionFormat.from("BW,<>a"),
Opcode.ROXL to InstructionFormat.from("BW,<>r1"),
Opcode.ROXLM to InstructionFormat.from("BW,<v"),
Opcode.ROXLM to InstructionFormat.from("BW,<>a"),
Opcode.FFROMUB to InstructionFormat.from("F,>fr1,<r1"),
Opcode.FFROMSB to InstructionFormat.from("F,>fr1,<r1"),
@@ -695,8 +641,9 @@ data class IRInstruction(
val reg2: Int?=null, // 0-$ffff
val fpReg1: Int?=null, // 0-$ffff
val fpReg2: Int?=null, // 0-$ffff
val value: Int?=null, // 0-$ffff
val fpValue: Float?=null,
val immediate: Int?=null, // 0-$ff or $ffff if word
val immediateFp: Float?=null,
val address: Int?=null, // 0-$ffff
val labelSymbol: String?=null, // symbolic label name as alternative to value (so only for Branch/jump/call Instructions!)
val binaryData: Collection<UByte>?=null,
var branchTarget: IRCodeChunkBase? = null // will be linked after loading
@@ -715,13 +662,6 @@ data class IRInstruction(
require(fpReg1==null || fpReg1 in 0..65536) {"fpReg1 out of bounds"}
require(fpReg2==null || fpReg2 in 0..65536) {"fpReg2 out of bounds"}
if(reg1!=null && reg2!=null) require(reg1!=reg2) {"reg1 must not be same as reg2"} // note: this is ok for fpRegs as these are always the same type
if(value!=null && opcode !in OpcodesWithMemoryAddressAsValue) {
when (type) {
IRDataType.BYTE -> require(value in -128..255) {"value out of range for byte: $value"}
IRDataType.WORD -> require(value in -32768..65535) {"value out of range for word: $value"}
IRDataType.FLOAT, null -> {}
}
}
require((opcode==Opcode.BINARYDATA && binaryData!=null) || (opcode!=Opcode.BINARYDATA && binaryData==null)) {
"binarydata inconsistency"
@@ -739,14 +679,21 @@ data class IRInstruction(
if(format.reg2==OperandDirection.UNUSED) require(reg2==null) { "invalid reg2" }
if(format.fpReg1==OperandDirection.UNUSED) require(fpReg1==null) { "invalid fpReg1" }
if(format.fpReg2==OperandDirection.UNUSED) require(fpReg2==null) { "invalid fpReg2" }
if (type==IRDataType.FLOAT) {
if(format.fpValueIn) require(fpValue!=null || labelSymbol!=null) {"missing a fp-value or labelsymbol"}
} else {
if(format.valueIn) require(value!=null || labelSymbol!=null) {"missing a value or labelsymbol"}
require(fpReg1==null && fpReg2==null) {"integer point instruction can't use floating point registers"}
if(format.immediate) {
if(type==IRDataType.FLOAT) require(immediateFp !=null) {"missing immediate fp value"}
else require(immediate!=null || labelSymbol!=null) {"missing immediate value or labelsymbol"}
}
if(type!=IRDataType.FLOAT)
require(fpReg1==null && fpReg2==null) {"int instruction can't use fp reg"}
if(format.address!=OperandDirection.UNUSED)
require(address!=null || labelSymbol!=null) {"missing an address or labelsymbol"}
if(format.immediate && (immediate!=null || immediateFp!=null)) {
when (type) {
IRDataType.BYTE -> require(immediate in -128..255) {"immediate value out of range for byte: $immediate"}
IRDataType.WORD -> require(immediate in -32768..65535) {"immediate value out of range for word: $immediate"}
IRDataType.FLOAT, null -> {}
}
}
reg1direction = format.reg1
reg2direction = format.reg2
@@ -866,14 +813,18 @@ data class IRInstruction(
result.add("fr$it")
result.add(",")
}
value?.let {
immediate?.let {
result.add(it.toHex())
result.add(",")
}
fpValue?.let {
immediateFp?.let {
result.add(it.toString())
result.add(",")
}
address?.let {
result.add(it.toHex())
result.add(",")
}
labelSymbol?.let {
result.add(it)
}
+16 -11
View File
@@ -194,33 +194,38 @@ fun parseIRCodeLine(line: String, location: Pair<IRCodeChunk, Int>?, placeholder
throw IRParseException("needs reg1 for $line")
if(format.reg2!=OperandDirection.UNUSED && reg2==null)
throw IRParseException("needs reg2 for $line")
if(format.valueIn && value==null && labelSymbol==null)
if(format.address!=OperandDirection.UNUSED && value==null && labelSymbol==null)
throw IRParseException("needs value or symbol for $line")
if(format.reg1==OperandDirection.UNUSED && reg1!=null)
throw IRParseException("invalid reg1 for $line")
if(format.reg2==OperandDirection.UNUSED && reg2!=null)
throw IRParseException("invalid reg2 for $line")
if(value!=null && opcode !in OpcodesWithMemoryAddressAsValue) {
if(value!=null && format.immediate) {
when (type) {
IRDataType.BYTE -> {
if (value < -128 || value > 255)
throw IRParseException("value out of range for byte: $value")
throw IRParseException("immediate value out of range for byte: $value")
}
IRDataType.WORD -> {
if (value < -32768 || value > 65535)
throw IRParseException("value out of range for word: $value")
throw IRParseException("immediate value out of range for word: $value")
}
IRDataType.FLOAT -> {}
null -> {}
}
}
var floatValue: Float? = null
var intValue: Int? = null
var immediateFp: Float? = null
var immediateInt: Int? = null
var address: Int? = null
if(format.valueIn && value!=null)
intValue = value.toInt()
if(format.fpValueIn && value!=null)
floatValue = value
if(format.address!=OperandDirection.UNUSED && value!=null)
address = value.toInt()
if(format.immediate && value!=null) {
if(type==IRDataType.FLOAT)
immediateFp = value
else
immediateInt = value.toInt()
}
if(opcode in OpcodesForCpuRegisters) {
val reg = rest.split(',').last().lowercase().trim()
@@ -237,5 +242,5 @@ fun parseIRCodeLine(line: String, location: Pair<IRCodeChunk, Int>?, placeholder
return left(IRInstruction(opcode, type, reg1, labelSymbol = reg))
}
return left(IRInstruction(opcode, type, reg1, reg2, fpReg1, fpReg2, intValue, floatValue, labelSymbol = labelSymbol))
return left(IRInstruction(opcode, type, reg1, reg2, fpReg1, fpReg2, immediateInt, immediateFp, address, labelSymbol = labelSymbol))
}
+23 -11
View File
@@ -15,20 +15,24 @@ class TestInstructions: FunSpec({
ins.fpReg1direction shouldBe OperandDirection.UNUSED
ins.reg1 shouldBe null
ins.reg2 shouldBe null
ins.value shouldBe null
ins.address shouldBe null
ins.immediate shouldBe null
ins.immediateFp shouldBe null
ins.labelSymbol shouldBe null
ins.toString() shouldBe "nop"
}
test("with value") {
val ins = IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=42, value = 99)
val ins = IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=42, address = 99)
ins.opcode shouldBe Opcode.BZ
ins.type shouldBe IRDataType.BYTE
ins.reg1direction shouldBe OperandDirection.READ
ins.fpReg1direction shouldBe OperandDirection.UNUSED
ins.reg1 shouldBe 42
ins.reg2 shouldBe null
ins.value shouldBe 99
ins.address shouldBe 99
ins.immediate shouldBe null
ins.immediateFp shouldBe null
ins.labelSymbol shouldBe null
ins.toString() shouldBe "bz.b r42,$63"
}
@@ -41,7 +45,9 @@ class TestInstructions: FunSpec({
ins.fpReg1direction shouldBe OperandDirection.UNUSED
ins.reg1 shouldBe 11
ins.reg2 shouldBe null
ins.value shouldBe null
ins.address shouldBe null
ins.immediate shouldBe null
ins.immediateFp shouldBe null
ins.labelSymbol shouldBe "a.b.c"
ins.toString() shouldBe "bz.w r11,a.b.c"
}
@@ -56,7 +62,9 @@ class TestInstructions: FunSpec({
ins.fpReg2direction shouldBe OperandDirection.UNUSED
ins.reg1 shouldBe 11
ins.reg2 shouldBe 22
ins.value shouldBe null
ins.address shouldBe null
ins.immediate shouldBe null
ins.immediateFp shouldBe null
ins.labelSymbol shouldBe null
ins.toString() shouldBe "addr.w r11,r22"
@@ -69,7 +77,9 @@ class TestInstructions: FunSpec({
ins2.fpReg2direction shouldBe OperandDirection.UNUSED
ins2.reg1 shouldBe 11
ins2.reg2 shouldBe 22
ins2.value shouldBe null
ins.address shouldBe null
ins.immediate shouldBe null
ins.immediateFp shouldBe null
ins2.labelSymbol shouldBe null
ins2.toString() shouldBe "sqrt.b r11,r22"
}
@@ -86,7 +96,9 @@ class TestInstructions: FunSpec({
ins.fpReg2 shouldBe 2
ins.reg1 shouldBe null
ins.reg2 shouldBe null
ins.value shouldBe null
ins.address shouldBe null
ins.immediate shouldBe null
ins.immediateFp shouldBe null
ins.labelSymbol shouldBe null
ins.toString() shouldBe "fsin.f fr1,fr2"
}
@@ -94,18 +106,18 @@ class TestInstructions: FunSpec({
test("missing type should fail") {
shouldThrow<IllegalArgumentException> {
IRInstruction(Opcode.BZ, reg1=42, value=99)
IRInstruction(Opcode.BZ, reg1=42, address=99)
}
}
test("missing registers should fail") {
shouldThrowWithMessage<IllegalArgumentException>("missing reg1") {
IRInstruction(Opcode.BZ, IRDataType.BYTE, value=99)
IRInstruction(Opcode.BZ, IRDataType.BYTE, address=99)
}
}
test("missing value should fail") {
shouldThrowWithMessage<IllegalArgumentException>("missing a value or labelsymbol") {
test("missing address should fail") {
shouldThrowWithMessage<IllegalArgumentException>("missing an address or labelsymbol") {
IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=42)
}
}
+83 -76
View File
@@ -149,8 +149,8 @@ class VirtualMachine(irProgram: IRProgram) {
pcIndex = 0
}
null -> {
if(i.value!=null)
throw IllegalArgumentException("vm program can't jump to system memory address (${i.opcode} ${i.value!!.toHex()})")
if(i.address!=null)
throw IllegalArgumentException("vm program can't jump to system memory address (${i.opcode} ${i.address!!.toHex()})")
else
throw IllegalArgumentException("no branchtarget in $i")
}
@@ -357,7 +357,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsSYSCALL(i: IRInstruction) {
val call = Syscall.values()[i.value!!]
val call = Syscall.values()[i.immediate!!]
SysCalls.call(call, this)
nextPc()
}
@@ -452,17 +452,24 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsLOAD(i: IRInstruction) {
if(i.type==IRDataType.FLOAT)
registers.setFloat(i.fpReg1!!, i.fpValue!!)
else
setResultReg(i.reg1!!, i.value!!, i.type!!)
registers.setFloat(i.fpReg1!!, i.immediateFp!!)
else {
if(i.immediate!=null)
setResultReg(i.reg1!!, i.immediate!!, i.type!!)
else {
if(i.labelSymbol==null)
throw IllegalArgumentException("expected LOAD of address of labelsymbol")
setResultReg(i.reg1!!, i.address!!, i.type!!)
}
}
nextPc()
}
private fun InsLOADM(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(i.value!!))
IRDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(i.value!!))
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.value!!))
IRDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(i.address!!))
IRDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(i.address!!))
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.address!!))
}
nextPc()
}
@@ -478,9 +485,9 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsLOADX(i: IRInstruction) {
when (i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(i.value!! + registers.getUW(i.reg2!!).toInt()))
IRDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(i.value!! + registers.getUW(i.reg2!!).toInt()))
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.value!! + registers.getUW(i.reg1!!).toInt()))
IRDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(i.address!! + registers.getUW(i.reg2!!).toInt()))
IRDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(i.address!! + registers.getUW(i.reg2!!).toInt()))
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.address!! + registers.getUW(i.reg1!!).toInt()))
}
nextPc()
}
@@ -488,15 +495,15 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsLOADIX(i: IRInstruction) {
when (i.type!!) {
IRDataType.BYTE -> {
val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!)
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg2!!)
registers.setUB(i.reg1!!, memory.getUB(pointer.toInt()))
}
IRDataType.WORD -> {
val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!)
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg2!!)
registers.setUW(i.reg1!!, memory.getUW(pointer.toInt()))
}
IRDataType.FLOAT -> {
val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg1!!)
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg1!!)
registers.setFloat(i.fpReg1!!, memory.getFloat(pointer.toInt()))
}
}
@@ -514,9 +521,9 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsSTOREM(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> memory.setUB(i.value!!, registers.getUB(i.reg1!!))
IRDataType.WORD -> memory.setUW(i.value!!, registers.getUW(i.reg1!!))
IRDataType.FLOAT -> memory.setFloat(i.value!!, registers.getFloat(i.fpReg1!!))
IRDataType.BYTE -> memory.setUB(i.address!!, registers.getUB(i.reg1!!))
IRDataType.WORD -> memory.setUW(i.address!!, registers.getUW(i.reg1!!))
IRDataType.FLOAT -> memory.setFloat(i.address!!, registers.getFloat(i.fpReg1!!))
}
nextPc()
}
@@ -532,9 +539,9 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsSTOREX(i: IRInstruction) {
when (i.type!!) {
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt() + i.value!!, registers.getUB(i.reg1!!))
IRDataType.WORD -> memory.setUW(registers.getUW(i.reg2!!).toInt() + i.value!!, registers.getUW(i.reg1!!))
IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + i.value!!, registers.getFloat(i.fpReg1!!))
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt() + i.address!!, registers.getUB(i.reg1!!))
IRDataType.WORD -> memory.setUW(registers.getUW(i.reg2!!).toInt() + i.address!!, registers.getUW(i.reg1!!))
IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + i.address!!, registers.getFloat(i.fpReg1!!))
}
nextPc()
}
@@ -542,15 +549,15 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsSTOREIX(i: IRInstruction) {
when (i.type!!) {
IRDataType.BYTE -> {
val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!)
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg2!!)
memory.setUB(pointer.toInt(), registers.getUB(i.reg1!!))
}
IRDataType.WORD -> {
val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!)
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg2!!)
memory.setUW(pointer.toInt(), registers.getUW(i.reg1!!))
}
IRDataType.FLOAT -> {
val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg1!!)
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg1!!)
memory.setFloat(pointer.toInt(), registers.getFloat(i.fpReg1!!))
}
}
@@ -559,9 +566,9 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsSTOREZM(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> memory.setUB(i.value!!, 0u)
IRDataType.WORD -> memory.setUW(i.value!!, 0u)
IRDataType.FLOAT -> memory.setFloat(i.value!!, 0f)
IRDataType.BYTE -> memory.setUB(i.address!!, 0u)
IRDataType.WORD -> memory.setUW(i.address!!, 0u)
IRDataType.FLOAT -> memory.setFloat(i.address!!, 0f)
}
nextPc()
}
@@ -577,9 +584,9 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsSTOREZX(i: IRInstruction) {
when (i.type!!) {
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg1!!).toInt() + i.value!!, 0u)
IRDataType.WORD -> memory.setUW(registers.getUW(i.reg1!!).toInt() + i.value!!, 0u)
IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + i.value!!, 0f)
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg1!!).toInt() + i.address!!, 0u)
IRDataType.WORD -> memory.setUW(registers.getUW(i.reg1!!).toInt() + i.address!!, 0u)
IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + i.address!!, 0f)
}
nextPc()
}
@@ -944,7 +951,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsINCM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> memory.setUB(address, (memory.getUB(address)+1u).toUByte())
IRDataType.WORD -> memory.setUW(address, (memory.getUW(address)+1u).toUShort())
@@ -964,9 +971,9 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsDECM(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> memory.setUB(i.value!!, (memory.getUB(i.value!!)-1u).toUByte())
IRDataType.WORD -> memory.setUW(i.value!!, (memory.getUW(i.value!!)-1u).toUShort())
IRDataType.FLOAT -> memory.setFloat(i.value!!, memory.getFloat(i.value!!)-1f)
IRDataType.BYTE -> memory.setUB(i.address!!, (memory.getUB(i.address!!)-1u).toUByte())
IRDataType.WORD -> memory.setUW(i.address!!, (memory.getUW(i.address!!)-1u).toUShort())
IRDataType.FLOAT -> memory.setFloat(i.address!!, memory.getFloat(i.address!!)-1f)
}
nextPc()
}
@@ -981,7 +988,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsNEGM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> memory.setUB(address, (-memory.getUB(address).toInt()).toUByte())
IRDataType.WORD -> memory.setUW(address, (-memory.getUW(address).toInt()).toUShort())
@@ -1006,11 +1013,11 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsADD(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> plusMinusMultConstByte("+", i.reg1!!, i.value!!.toUByte())
IRDataType.WORD -> plusMinusMultConstWord("+", i.reg1!!, i.value!!.toUShort())
IRDataType.BYTE -> plusMinusMultConstByte("+", i.reg1!!, i.immediate!!.toUByte())
IRDataType.WORD -> plusMinusMultConstWord("+", i.reg1!!, i.immediate!!.toUShort())
IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!)
val result = arithFloat(left, "+", i.fpValue!!)
val result = arithFloat(left, "+", i.immediateFp!!)
registers.setFloat(i.fpReg1!!, result)
}
}
@@ -1018,7 +1025,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsADDM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByteInplace("+", i.reg1!!, address)
IRDataType.WORD -> plusMinusMultAnyWordInplace("+", i.reg1!!, address)
@@ -1048,11 +1055,11 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsSUB(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> plusMinusMultConstByte("-", i.reg1!!, i.value!!.toUByte())
IRDataType.WORD -> plusMinusMultConstWord("-", i.reg1!!, i.value!!.toUShort())
IRDataType.BYTE -> plusMinusMultConstByte("-", i.reg1!!, i.immediate!!.toUByte())
IRDataType.WORD -> plusMinusMultConstWord("-", i.reg1!!, i.immediate!!.toUShort())
IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!)
val result = arithFloat(left, "-", i.fpValue!!)
val result = arithFloat(left, "-", i.immediateFp!!)
registers.setFloat(i.fpReg1!!, result)
}
}
@@ -1060,7 +1067,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsSUBM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByteInplace("-", i.reg1!!, address)
IRDataType.WORD -> plusMinusMultAnyWordInplace("-", i.reg1!!, address)
@@ -1090,11 +1097,11 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsMUL(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> plusMinusMultConstByte("*", i.reg1!!, i.value!!.toUByte())
IRDataType.WORD -> plusMinusMultConstWord("*", i.reg1!!, i.value!!.toUShort())
IRDataType.BYTE -> plusMinusMultConstByte("*", i.reg1!!, i.immediate!!.toUByte())
IRDataType.WORD -> plusMinusMultConstWord("*", i.reg1!!, i.immediate!!.toUShort())
IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!)
val result = arithFloat(left, "*", i.fpValue!!)
val result = arithFloat(left, "*", i.immediateFp!!)
registers.setFloat(i.fpReg1!!, result)
}
}
@@ -1102,7 +1109,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsMULM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByteInplace("*", i.reg1!!, address)
IRDataType.WORD -> plusMinusMultAnyWordInplace("*", i.reg1!!, address)
@@ -1127,15 +1134,15 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsDIV(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> divOrModConstByteUnsigned("/", i.reg1!!, i.value!!.toUByte())
IRDataType.WORD -> divOrModConstWordUnsigned("/", i.reg1!!, i.value!!.toUShort())
IRDataType.BYTE -> divOrModConstByteUnsigned("/", i.reg1!!, i.immediate!!.toUByte())
IRDataType.WORD -> divOrModConstWordUnsigned("/", i.reg1!!, i.immediate!!.toUShort())
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
}
nextPc()
}
private fun InsDIVM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> divModByteUnsignedInplace("/", i.reg1!!, address)
IRDataType.WORD -> divModWordUnsignedInplace("/", i.reg1!!, address)
@@ -1160,11 +1167,11 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsDIVS(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> divModConstByteSigned("/", i.reg1!!, i.value!!.toByte())
IRDataType.WORD -> divModConstWordSigned("/", i.reg1!!, i.value!!.toShort())
IRDataType.BYTE -> divModConstByteSigned("/", i.reg1!!, i.immediate!!.toByte())
IRDataType.WORD -> divModConstWordSigned("/", i.reg1!!, i.immediate!!.toShort())
IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!)
val result = arithFloat(left, "/", i.fpValue!!)
val result = arithFloat(left, "/", i.immediateFp!!)
registers.setFloat(i.fpReg1!!, result)
}
}
@@ -1172,7 +1179,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsDIVSM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> divModByteSignedInplace("/", i.reg1!!, address)
IRDataType.WORD -> divModWordSignedInplace("/", i.reg1!!, address)
@@ -1197,8 +1204,8 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsMOD(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> divOrModConstByteUnsigned("%", i.reg1!!, i.value!!.toUByte())
IRDataType.WORD -> divOrModConstWordUnsigned("%", i.reg1!!, i.value!!.toUShort())
IRDataType.BYTE -> divOrModConstByteUnsigned("%", i.reg1!!, i.immediate!!.toUByte())
IRDataType.WORD -> divOrModConstWordUnsigned("%", i.reg1!!, i.immediate!!.toUShort())
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
}
nextPc()
@@ -1215,8 +1222,8 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsDIVMOD(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> divAndModConstUByte(i.reg1!!, i.value!!.toUByte()) // output in r0+r1
IRDataType.WORD -> divAndModConstUWord(i.reg1!!, i.value!!.toUShort()) // output in r0+r1
IRDataType.BYTE -> divAndModConstUByte(i.reg1!!, i.immediate!!.toUByte()) // output in r0+r1
IRDataType.WORD -> divAndModConstUWord(i.reg1!!, i.immediate!!.toUShort()) // output in r0+r1
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
}
nextPc()
@@ -1619,15 +1626,15 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsAND(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) and i.value!!.toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) and i.value!!.toUShort())
IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) and i.immediate!!.toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) and i.immediate!!.toUShort())
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
}
nextPc()
}
private fun InsANDM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> {
val left = memory.getUB(address)
@@ -1656,15 +1663,15 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsOR(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) or i.value!!.toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) or i.value!!.toUShort())
IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) or i.immediate!!.toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) or i.immediate!!.toUShort())
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
}
nextPc()
}
private fun InsORM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> {
val left = memory.getUB(address)
@@ -1693,15 +1700,15 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsXOR(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) xor i.value!!.toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) xor i.value!!.toUShort())
IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) xor i.immediate!!.toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) xor i.immediate!!.toUShort())
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
}
nextPc()
}
private fun InsXORM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> {
val left = memory.getUB(address)
@@ -1728,7 +1735,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsINVM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> memory.setUB(address, memory.getUB(address).inv())
IRDataType.WORD -> memory.setUW(address, memory.getUW(address).inv())
@@ -1749,7 +1756,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsASRNM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
val operand = registers.getUB(i.reg1!!).toInt()
when(i.type!!) {
IRDataType.BYTE -> {
@@ -1785,7 +1792,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsASRM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> {
val value = memory.getSB(address).toInt()
@@ -1814,7 +1821,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsLSRNM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
val operand = registers.getUB(i.reg1!!).toInt()
when(i.type!!) {
IRDataType.BYTE -> {
@@ -1850,7 +1857,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsLSRM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> {
val value = memory.getUB(address).toInt()
@@ -1884,7 +1891,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsLSLNM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
val operand = registers.getUB(i.reg1!!).toInt()
when(i.type!!) {
IRDataType.BYTE -> {
@@ -1920,7 +1927,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsLSLM(i: IRInstruction) {
val address = i.value!!
val address = i.address!!
when(i.type!!) {
IRDataType.BYTE -> {
val value = memory.getUB(address).toInt()
@@ -1970,7 +1977,7 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsRORM(i: IRInstruction, useCarry: Boolean) {
val newStatusCarry: Boolean
val address = i.value!!
val address = i.address!!
when (i.type!!) {
IRDataType.BYTE -> {
val orig = memory.getUB(address)
@@ -2032,7 +2039,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
private fun InsROLM(i: IRInstruction, useCarry: Boolean) {
val address = i.value!!
val address = i.address!!
val newStatusCarry: Boolean
when (i.type!!) {
IRDataType.BYTE -> {
@@ -70,7 +70,7 @@ class VmProgramLoader {
programChunks.forEach {
it.instructions.forEach { ins ->
if (ins.labelSymbol != null && ins.opcode !in OpcodesThatBranch && ins.opcode !in OpcodesForCpuRegisters)
require(ins.value != null) { "instruction with labelSymbol for a var should have value set to var's memory address" }
require(ins.address != null) { "instruction with labelSymbol for a var should have value set to the memory address" }
}
}
@@ -102,7 +102,7 @@ class VmProgramLoader {
chunk.instructions.withIndex().forEach { (index, ins) ->
if(ins.opcode == Opcode.SYSCALL) {
// convert IR Syscall to VM Syscall
val vmSyscall = when(ins.value!!) {
val vmSyscall = when(ins.immediate!!) {
IMSyscall.SORT_UBYTE.number -> Syscall.SORT_UBYTE
IMSyscall.SORT_BYTE.number -> Syscall.SORT_BYTE
IMSyscall.SORT_UWORD.number -> Syscall.SORT_UWORD
@@ -124,7 +124,7 @@ class VmProgramLoader {
}
if(vmSyscall!=null)
chunk.instructions[index] = ins.copy(value = vmSyscall.ordinal)
chunk.instructions[index] = ins.copy(immediate = vmSyscall.ordinal)
}
val label = ins.labelSymbol
@@ -148,7 +148,7 @@ class VmProgramLoader {
val (symbol, indexStr) = label.split('+')
val index = indexStr.toInt()
val address = variableAddresses.getValue(symbol) + index
chunk.instructions[line] = chunk.instructions[line].copy(value = address)
chunk.instructions[line] = chunk.instructions[line].copy(address = address)
} else {
// placeholder is not a variable, so it must be a label of a code chunk instead
val target: IRCodeChunk? = chunks.firstOrNull { it.label==label }
@@ -159,15 +159,13 @@ class VmProgramLoader {
throw IRParseException("placeholder not found in variables nor labels: $label")
}
else if(opcode in OpcodesThatBranch) {
chunk.instructions[line] = chunk.instructions[line].copy(branchTarget = target, value = null)
} else if(opcode in OpcodesWithMemoryAddressAsValue) {
throw IRParseException("vm cannot yet load a label address as a value: ${chunk.instructions[line]}") // TODO
chunk.instructions[line] = chunk.instructions[line].copy(branchTarget = target, address = null)
} else {
throw IRParseException("vm cannot yet load a label address as a value: ${chunk.instructions[line]}") // TODO
}
}
} else {
chunk.instructions[line] = chunk.instructions[line].copy(value = replacement)
chunk.instructions[line] = chunk.instructions[line].copy(address = replacement)
}
}
}
+2 -2
View File
@@ -47,8 +47,8 @@ class TestVm: FunSpec( {
val startSub = IRSubroutine("testmain.testsub", emptyList(), null, Position.DUMMY)
val code = IRCodeChunk(startSub.label, null)
code += IRInstruction(Opcode.NOP)
code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=1, value=12345)
code += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1=1, value=1000)
code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=1, immediate=12345)
code += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1=1, address=1000)
code += IRInstruction(Opcode.RETURN)
startSub += code
block += startSub