mirror of
https://github.com/irmen/prog8.git
synced 2026-04-21 02:16:41 +00:00
tweaking IR instruction formats
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
})
|
||||
@@ -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
|
||||
}
|
||||
})
|
||||
@@ -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 ; \
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user