mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
vm: limit int instructions to just 2 register args
This commit is contained in:
parent
4be7bc8323
commit
517cf61d11
@ -77,22 +77,19 @@ internal class VmCodeInstruction(
|
|||||||
type: VmDataType?=null,
|
type: VmDataType?=null,
|
||||||
reg1: Int?=null, // 0-$ffff
|
reg1: Int?=null, // 0-$ffff
|
||||||
reg2: Int?=null, // 0-$ffff
|
reg2: Int?=null, // 0-$ffff
|
||||||
reg3: Int?=null, // 0-$ffff
|
|
||||||
fpReg1: Int?=null, // 0-$ffff
|
fpReg1: Int?=null, // 0-$ffff
|
||||||
fpReg2: Int?=null, // 0-$ffff
|
fpReg2: Int?=null, // 0-$ffff
|
||||||
value: Int?=null, // 0-$ffff
|
value: Int?=null, // 0-$ffff
|
||||||
fpValue: Float?=null,
|
fpValue: Float?=null,
|
||||||
symbol: List<String>?=null // alternative to value
|
symbol: List<String>?=null // alternative to value
|
||||||
): VmCodeLine() {
|
): VmCodeLine() {
|
||||||
val ins = Instruction(opcode, type, reg1, reg2, reg3, fpReg1, fpReg2, value, fpValue, symbol)
|
val ins = Instruction(opcode, type, reg1, reg2, fpReg1, fpReg2, value, fpValue, symbol)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if(reg1!=null && (reg1<0 || reg1>65536))
|
if(reg1!=null && (reg1<0 || reg1>65536))
|
||||||
throw IllegalArgumentException("reg1 out of bounds")
|
throw IllegalArgumentException("reg1 out of bounds")
|
||||||
if(reg2!=null && (reg2<0 || reg2>65536))
|
if(reg2!=null && (reg2<0 || reg2>65536))
|
||||||
throw IllegalArgumentException("reg2 out of bounds")
|
throw IllegalArgumentException("reg2 out of bounds")
|
||||||
if(reg3!=null && (reg3<0 || reg3>65536))
|
|
||||||
throw IllegalArgumentException("reg3 out of bounds")
|
|
||||||
if(fpReg1!=null && (fpReg1<0 || fpReg1>65536))
|
if(fpReg1!=null && (fpReg1<0 || fpReg1>65536))
|
||||||
throw IllegalArgumentException("fpReg1 out of bounds")
|
throw IllegalArgumentException("fpReg1 out of bounds")
|
||||||
if(fpReg2!=null && (fpReg2<0 || fpReg2>65536))
|
if(fpReg2!=null && (fpReg2<0 || fpReg2>65536))
|
||||||
|
@ -115,7 +115,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
val andReg = codeGen.vmRegisters.nextFree()
|
val andReg = codeGen.vmRegisters.nextFree()
|
||||||
val notNegativeLabel = codeGen.createLabelName()
|
val notNegativeLabel = codeGen.createLabelName()
|
||||||
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=andReg, value=0x80)
|
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=andReg, value=0x80)
|
||||||
code += VmCodeInstruction(Opcode.AND, VmDataType.BYTE, reg1=andReg, reg2=resultRegister, reg3=andReg)
|
code += VmCodeInstruction(Opcode.AND, VmDataType.BYTE, reg1=andReg, reg2=resultRegister)
|
||||||
code += VmCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=andReg, symbol = notNegativeLabel)
|
code += VmCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=andReg, symbol = notNegativeLabel)
|
||||||
code += VmCodeInstruction(Opcode.NEG, VmDataType.BYTE, reg1=resultRegister)
|
code += VmCodeInstruction(Opcode.NEG, VmDataType.BYTE, reg1=resultRegister)
|
||||||
code += VmCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister)
|
code += VmCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister)
|
||||||
@ -125,7 +125,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
val andReg = codeGen.vmRegisters.nextFree()
|
val andReg = codeGen.vmRegisters.nextFree()
|
||||||
val notNegativeLabel = codeGen.createLabelName()
|
val notNegativeLabel = codeGen.createLabelName()
|
||||||
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=andReg, value=0x8000)
|
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=andReg, value=0x8000)
|
||||||
code += VmCodeInstruction(Opcode.AND, VmDataType.WORD, reg1=andReg, reg2=resultRegister, reg3=andReg)
|
code += VmCodeInstruction(Opcode.AND, VmDataType.WORD, reg1=andReg, reg2=resultRegister)
|
||||||
code += VmCodeInstruction(Opcode.BZ, VmDataType.WORD, reg1=andReg, symbol = notNegativeLabel)
|
code += VmCodeInstruction(Opcode.BZ, VmDataType.WORD, reg1=andReg, symbol = notNegativeLabel)
|
||||||
code += VmCodeInstruction(Opcode.NEG, VmDataType.WORD, reg1=resultRegister)
|
code += VmCodeInstruction(Opcode.NEG, VmDataType.WORD, reg1=resultRegister)
|
||||||
code += VmCodeLabel(notNegativeLabel)
|
code += VmCodeLabel(notNegativeLabel)
|
||||||
@ -230,11 +230,10 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
|
|
||||||
private fun funcMkword(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
private fun funcMkword(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
val msbReg = codeGen.vmRegisters.nextFree()
|
val msbReg = codeGen.vmRegisters.nextFree()
|
||||||
val lsbReg = codeGen.vmRegisters.nextFree()
|
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
code += exprGen.translateExpression(call.args[0], msbReg, -1)
|
code += exprGen.translateExpression(call.args[0], msbReg, -1)
|
||||||
code += exprGen.translateExpression(call.args[1], lsbReg, -1)
|
code += exprGen.translateExpression(call.args[1], resultRegister, -1)
|
||||||
code += VmCodeInstruction(Opcode.CONCAT, VmDataType.BYTE, reg1=resultRegister, reg2=msbReg, reg3=lsbReg)
|
code += VmCodeInstruction(Opcode.CONCAT, VmDataType.BYTE, reg1=resultRegister, reg2=msbReg)
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,11 +331,11 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
val valueReg = vmRegisters.nextFree()
|
val valueReg = vmRegisters.nextFree()
|
||||||
if(value>0) {
|
if(value>0) {
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value= value)
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value= value)
|
||||||
code += VmCodeInstruction(Opcode.ADD, dt, reg1 = reg, reg2 = reg, reg3 = valueReg)
|
code += VmCodeInstruction(Opcode.ADD, dt, reg1 = reg, reg2 = valueReg)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value= -value)
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value= -value)
|
||||||
code += VmCodeInstruction(Opcode.SUB, dt, reg1 = reg, reg2 = reg, reg3 = valueReg)
|
code += VmCodeInstruction(Opcode.SUB, dt, reg1 = reg, reg2 = valueReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -366,13 +366,13 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
if(value>0) {
|
if(value>0) {
|
||||||
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
|
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=value)
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=value)
|
||||||
code += VmCodeInstruction(Opcode.ADD, dt, reg1 = valueReg, reg2 = valueReg, reg3 = operandReg)
|
code += VmCodeInstruction(Opcode.ADD, dt, reg1 = valueReg, reg2 = operandReg)
|
||||||
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
|
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
|
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=-value)
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=-value)
|
||||||
code += VmCodeInstruction(Opcode.SUB, dt, reg1 = valueReg, reg2 = valueReg, reg3 = operandReg)
|
code += VmCodeInstruction(Opcode.SUB, dt, reg1 = valueReg, reg2 = operandReg)
|
||||||
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
|
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -409,7 +409,7 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
// just shift multiple bits
|
// just shift multiple bits
|
||||||
val pow2reg = vmRegisters.nextFree()
|
val pow2reg = vmRegisters.nextFree()
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
|
||||||
code += VmCodeInstruction(Opcode.LSLN, dt, reg1=reg, reg2=reg, reg3=pow2reg)
|
code += VmCodeInstruction(Opcode.LSLN, dt, reg1=reg, reg2=pow2reg)
|
||||||
} else {
|
} else {
|
||||||
if (factor == 0) {
|
if (factor == 0) {
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0)
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0)
|
||||||
@ -417,7 +417,7 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
else {
|
else {
|
||||||
val factorReg = vmRegisters.nextFree()
|
val factorReg = vmRegisters.nextFree()
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=factorReg, value= factor)
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=factorReg, value= factor)
|
||||||
code += VmCodeInstruction(Opcode.MUL, dt, reg1=reg, reg2=reg, reg3=factorReg)
|
code += VmCodeInstruction(Opcode.MUL, dt, reg1=reg, reg2=factorReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
@ -450,7 +450,7 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
// just shift multiple bits
|
// just shift multiple bits
|
||||||
val pow2reg = vmRegisters.nextFree()
|
val pow2reg = vmRegisters.nextFree()
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2)
|
||||||
code += VmCodeInstruction(Opcode.LSRN, dt, reg1=reg, reg2=reg, reg3=pow2reg)
|
code += VmCodeInstruction(Opcode.LSRN, dt, reg1=reg, reg2=pow2reg)
|
||||||
} else {
|
} else {
|
||||||
if (factor == 0) {
|
if (factor == 0) {
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
|
||||||
@ -458,7 +458,7 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
else {
|
else {
|
||||||
val factorReg = vmRegisters.nextFree()
|
val factorReg = vmRegisters.nextFree()
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=factorReg, value= factor)
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=factorReg, value= factor)
|
||||||
code += VmCodeInstruction(Opcode.DIV, dt, reg1=reg, reg2=reg, reg3=factorReg)
|
code += VmCodeInstruction(Opcode.DIV, dt, reg1=reg, reg2=factorReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
|
@ -185,7 +185,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val regMask = codeGen.vmRegisters.nextFree()
|
val regMask = codeGen.vmRegisters.nextFree()
|
||||||
val mask = if(vmDt==VmDataType.BYTE) 0x00ff else 0xffff
|
val mask = if(vmDt==VmDataType.BYTE) 0x00ff else 0xffff
|
||||||
code += VmCodeInstruction(Opcode.LOAD, vmDt, reg1=regMask, value=mask)
|
code += VmCodeInstruction(Opcode.LOAD, vmDt, reg1=regMask, value=mask)
|
||||||
code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=regMask)
|
code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=regMask)
|
||||||
}
|
}
|
||||||
"not" -> {
|
"not" -> {
|
||||||
val label = codeGen.createLabelName()
|
val label = codeGen.createLabelName()
|
||||||
@ -194,7 +194,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
code += VmCodeLabel(label)
|
code += VmCodeLabel(label)
|
||||||
val regMask = codeGen.vmRegisters.nextFree()
|
val regMask = codeGen.vmRegisters.nextFree()
|
||||||
code += VmCodeInstruction(Opcode.LOAD, vmDt, reg1=regMask, value=1)
|
code += VmCodeInstruction(Opcode.LOAD, vmDt, reg1=regMask, value=1)
|
||||||
code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=regMask)
|
code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=regMask)
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird prefix operator")
|
else -> throw AssemblyError("weird prefix operator")
|
||||||
}
|
}
|
||||||
@ -329,7 +329,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
} else {
|
} else {
|
||||||
if (greaterEquals) Opcode.SGE else Opcode.SGT
|
if (greaterEquals) Opcode.SGE else Opcode.SGT
|
||||||
}
|
}
|
||||||
code += VmCodeInstruction(ins, VmDataType.BYTE, reg1 = resultRegister, reg2 = resultRegister, reg3 = zeroRegister)
|
code += VmCodeInstruction(ins, VmDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
@ -339,7 +339,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
} else {
|
} else {
|
||||||
if (greaterEquals) Opcode.SGE else Opcode.SGT
|
if (greaterEquals) Opcode.SGE else Opcode.SGT
|
||||||
}
|
}
|
||||||
code += VmCodeInstruction(ins, vmDt, reg1 = resultRegister, reg2 = resultRegister, reg3 = rightResultReg)
|
code += VmCodeInstruction(ins, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
@ -365,7 +365,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
} else {
|
} else {
|
||||||
if (lessEquals) Opcode.SLE else Opcode.SLT
|
if (lessEquals) Opcode.SLE else Opcode.SLT
|
||||||
}
|
}
|
||||||
code += VmCodeInstruction(ins, VmDataType.BYTE, reg1 = resultRegister, reg2 = resultRegister, reg3 = zeroRegister)
|
code += VmCodeInstruction(ins, VmDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
@ -375,7 +375,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
} else {
|
} else {
|
||||||
if (lessEquals) Opcode.SLE else Opcode.SLT
|
if (lessEquals) Opcode.SLE else Opcode.SLT
|
||||||
}
|
}
|
||||||
code += VmCodeInstruction(ins, vmDt, reg1 = resultRegister, reg2 = resultRegister, reg3 = rightResultReg)
|
code += VmCodeInstruction(ins, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
@ -395,14 +395,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
code += VmCodeLabel(label)
|
code += VmCodeLabel(label)
|
||||||
val regMask = codeGen.vmRegisters.nextFree()
|
val regMask = codeGen.vmRegisters.nextFree()
|
||||||
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=regMask, value=1)
|
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=regMask, value=1)
|
||||||
code += VmCodeInstruction(Opcode.XOR, VmDataType.BYTE, reg1=resultRegister, reg2=resultRegister, reg3=regMask)
|
code += VmCodeInstruction(Opcode.XOR, VmDataType.BYTE, reg1=resultRegister, reg2=regMask)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
val opcode = if (notEquals) Opcode.SNE else Opcode.SEQ
|
val opcode = if (notEquals) Opcode.SNE else Opcode.SEQ
|
||||||
code += VmCodeInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = resultRegister, reg3 = rightResultReg)
|
code += VmCodeInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
@ -418,7 +418,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
val opc = if (signed) Opcode.ASRN else Opcode.LSRN
|
val opc = if (signed) Opcode.ASRN else Opcode.LSRN
|
||||||
code += VmCodeInstruction(opc, vmDt, reg1 = resultRegister, reg2 = resultRegister, reg3 = rightResultReg)
|
code += VmCodeInstruction(opc, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
@ -432,7 +432,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
code += VmCodeInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
|
code += VmCodeInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, rightResultReg)
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
@ -442,7 +442,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
|
code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=rightResultReg)
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,7 +451,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
code += VmCodeInstruction(Opcode.AND, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
|
code += VmCodeInstruction(Opcode.AND, vmDt, reg1=resultRegister, reg2=rightResultReg)
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +460,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
code += VmCodeInstruction(Opcode.OR, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
|
code += VmCodeInstruction(Opcode.OR, vmDt, reg1=resultRegister, reg2=rightResultReg)
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,7 +471,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
code += VmCodeInstruction(Opcode.MOD, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
|
code += VmCodeInstruction(Opcode.MOD, vmDt, reg1=resultRegister, reg2=rightResultReg)
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,7 +498,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
code += VmCodeInstruction(Opcode.DIV, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
|
code += VmCodeInstruction(Opcode.DIV, vmDt, reg1=resultRegister, reg2=rightResultReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
@ -536,7 +536,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
code += VmCodeInstruction(Opcode.MUL, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
|
code += VmCodeInstruction(Opcode.MUL, vmDt, reg1=resultRegister, reg2=rightResultReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
@ -564,7 +564,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
code += VmCodeInstruction(Opcode.SUB, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
|
code += VmCodeInstruction(Opcode.SUB, vmDt, reg1=resultRegister, reg2=rightResultReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
@ -600,7 +600,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
code += VmCodeInstruction(Opcode.ADD, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
|
code += VmCodeInstruction(Opcode.ADD, vmDt, reg1=resultRegister, reg2=rightResultReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
|
@ -3,7 +3,6 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- vm: get rid of the 3-register instructions just make them 2 registers? Result register is always same as second?
|
|
||||||
- vm: use more instructions in codegen: branching
|
- vm: use more instructions in codegen: branching
|
||||||
- vm: add more instructions operating directly on memory instead of only registers?
|
- vm: add more instructions operating directly on memory instead of only registers?
|
||||||
- in-place modifiying functions (rol, ror, ..) don't accept a memory address but require a memory-read expression. that is weird.
|
- in-place modifiying functions (rol, ror, ..) don't accept a memory address but require a memory-read expression. that is weird.
|
||||||
|
@ -25,29 +25,10 @@ main {
|
|||||||
|
|
||||||
ubyte @shared value = inline_candidate()
|
ubyte @shared value = inline_candidate()
|
||||||
|
|
||||||
float fl1 = 1.1
|
ubyte lowb = $31
|
||||||
float fl2 = 2.2
|
ubyte highb = $ea
|
||||||
floats.print_f(floats.pow(fl1,fl2))
|
uword result = mkword(highb, lowb)
|
||||||
|
txt.print_uwhex(result, true)
|
||||||
if fl1==fl2
|
|
||||||
txt.print("equals!?\n")
|
|
||||||
if fl1!=fl2
|
|
||||||
txt.print("not equals.\n")
|
|
||||||
fl1 = fl2
|
|
||||||
if fl1==fl2
|
|
||||||
txt.print("equals.\n")
|
|
||||||
if fl1!=fl2
|
|
||||||
txt.print("not equals!?\n")
|
|
||||||
|
|
||||||
if fl1 <= fl2
|
|
||||||
txt.print("yup\n")
|
|
||||||
if fl1 > fl2
|
|
||||||
txt.print("nope\n")
|
|
||||||
fl1 = 3.3
|
|
||||||
if fl1 <= fl2
|
|
||||||
txt.print("yup\n")
|
|
||||||
if fl1 > fl2
|
|
||||||
txt.print("nope\n")
|
|
||||||
|
|
||||||
; txt.print_ub(inline_candidate())
|
; txt.print_ub(inline_candidate())
|
||||||
; txt.nl()
|
; txt.nl()
|
||||||
|
@ -157,10 +157,10 @@ class Assembler {
|
|||||||
fpReg2 = fpReg3
|
fpReg2 = fpReg3
|
||||||
fpReg3 = null
|
fpReg3 = null
|
||||||
}
|
}
|
||||||
|
if(reg3!=null)
|
||||||
|
throw IllegalArgumentException("too many reg arguments $line")
|
||||||
if(fpReg3!=null)
|
if(fpReg3!=null)
|
||||||
throw IllegalArgumentException("too many fpreg arguments $line")
|
throw IllegalArgumentException("too many fpreg arguments $line")
|
||||||
// TODO also check reg3
|
|
||||||
|
|
||||||
|
|
||||||
if(type!=null && type !in formats)
|
if(type!=null && type !in formats)
|
||||||
throw IllegalArgumentException("invalid type code for $line")
|
throw IllegalArgumentException("invalid type code for $line")
|
||||||
@ -168,16 +168,12 @@ class Assembler {
|
|||||||
throw IllegalArgumentException("needs reg1 for $line")
|
throw IllegalArgumentException("needs reg1 for $line")
|
||||||
if(format.reg2 && reg2==null)
|
if(format.reg2 && reg2==null)
|
||||||
throw IllegalArgumentException("needs reg2 for $line")
|
throw IllegalArgumentException("needs reg2 for $line")
|
||||||
if(format.reg3 && reg3==null)
|
|
||||||
throw IllegalArgumentException("needs reg3 for $line")
|
|
||||||
if(format.value && value==null)
|
if(format.value && value==null)
|
||||||
throw IllegalArgumentException("needs value for $line")
|
throw IllegalArgumentException("needs value for $line")
|
||||||
if(!format.reg1 && reg1!=null)
|
if(!format.reg1 && reg1!=null)
|
||||||
throw IllegalArgumentException("invalid reg1 for $line")
|
throw IllegalArgumentException("invalid reg1 for $line")
|
||||||
if(!format.reg2 && reg2!=null)
|
if(!format.reg2 && reg2!=null)
|
||||||
throw IllegalArgumentException("invalid reg2 for $line")
|
throw IllegalArgumentException("invalid reg2 for $line")
|
||||||
if(!format.reg3 && reg3!=null)
|
|
||||||
throw IllegalArgumentException("invalid reg3 for $line")
|
|
||||||
if(value!=null && opcode !in OpcodesWithAddress) {
|
if(value!=null && opcode !in OpcodesWithAddress) {
|
||||||
when (type) {
|
when (type) {
|
||||||
VmDataType.BYTE -> {
|
VmDataType.BYTE -> {
|
||||||
@ -200,7 +196,7 @@ class Assembler {
|
|||||||
if(format.fpValue)
|
if(format.fpValue)
|
||||||
floatValue = value!!
|
floatValue = value!!
|
||||||
|
|
||||||
program.add(Instruction(opcode, type, reg1, reg2, reg3, fpReg1, fpReg2, value = intValue, fpValue = floatValue))
|
program.add(Instruction(opcode, type, reg1, reg2, fpReg1, fpReg2, value = intValue, fpValue = floatValue))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,16 +73,16 @@ bgt reg1, reg2, location - jump to location in program given by l
|
|||||||
bgts reg1, reg2, location - jump to location in program given by location, if reg1 > reg2 (signed)
|
bgts reg1, reg2, location - jump to location in program given by location, if reg1 > reg2 (signed)
|
||||||
bge reg1, reg2, location - jump to location in program given by location, if reg1 >= reg2 (unsigned)
|
bge reg1, reg2, location - jump to location in program given by location, if reg1 >= reg2 (unsigned)
|
||||||
bges reg1, reg2, location - jump to location in program given by location, if reg1 >= reg2 (signed)
|
bges reg1, reg2, location - jump to location in program given by location, if reg1 >= reg2 (signed)
|
||||||
seq reg1, reg2, reg3 - set reg=1 if reg2 == reg3, otherwise set reg1=0
|
seq reg1, reg2 - set reg=1 if reg1 == reg2, otherwise set reg1=0
|
||||||
sne reg1, reg2, reg3 - set reg=1 if reg2 != reg3, otherwise set reg1=0
|
sne reg1, reg2 - set reg=1 if reg1 != reg2, otherwise set reg1=0
|
||||||
slt reg1, reg2, reg3 - set reg=1 if reg2 < reg3 (unsigned), otherwise set reg1=0
|
slt reg1, reg2 - set reg=1 if reg1 < reg2 (unsigned), otherwise set reg1=0
|
||||||
slts reg1, reg2, reg3 - set reg=1 if reg2 < reg3 (signed), otherwise set reg1=0
|
slts reg1, reg2 - set reg=1 if reg1 < reg2 (signed), otherwise set reg1=0
|
||||||
sle reg1, reg2, reg3 - set reg=1 if reg2 <= reg3 (unsigned), otherwise set reg1=0
|
sle reg1, reg2 - set reg=1 if reg1 <= reg2 (unsigned), otherwise set reg1=0
|
||||||
sles reg1, reg2, reg3 - set reg=1 if reg2 <= reg3 (signed), otherwise set reg1=0
|
sles reg1, reg2 - set reg=1 if reg1 <= reg2 (signed), otherwise set reg1=0
|
||||||
sgt reg1, reg2, reg3 - set reg=1 if reg2 > reg3 (unsigned), otherwise set reg1=0
|
sgt reg1, reg2 - set reg=1 if reg1 > reg2 (unsigned), otherwise set reg1=0
|
||||||
sgts reg1, reg2, reg3 - set reg=1 if reg2 > reg3 (signed), otherwise set reg1=0
|
sgts reg1, reg2 - set reg=1 if reg1 > reg2 (signed), otherwise set reg1=0
|
||||||
sge reg1, reg2, reg3 - set reg=1 if reg2 >= reg3 (unsigned), otherwise set reg1=0
|
sge reg1, reg2 - set reg=1 if reg1 >= reg2 (unsigned), otherwise set reg1=0
|
||||||
sges reg1, reg2, reg3 - set reg=1 if reg2 >= reg3 (signed), otherwise set reg1=0
|
sges reg1, reg2 - set reg=1 if reg1 >= reg2 (signed), otherwise set reg1=0
|
||||||
|
|
||||||
|
|
||||||
ARITHMETIC
|
ARITHMETIC
|
||||||
@ -96,11 +96,11 @@ incm address - memory at address += 1
|
|||||||
dec reg1 - reg1 = reg1-1
|
dec reg1 - reg1 = reg1-1
|
||||||
decm address - memory at address -= 1
|
decm address - memory at address -= 1
|
||||||
neg reg1 - reg1 = sign negation of reg1
|
neg reg1 - reg1 = sign negation of reg1
|
||||||
add reg1, reg2, reg3 - reg1 = reg2+reg3 (unsigned + signed)
|
add reg1, reg2 - reg1 += reg2 (unsigned + signed)
|
||||||
sub reg1, reg2, reg3 - reg1 = reg2-reg3 (unsigned + signed)
|
sub reg1, reg2 - reg1 -= reg2 (unsigned + signed)
|
||||||
mul reg1, reg2, reg3 - unsigned multiply reg1=reg2*reg3 note: byte*byte->byte, no type extension to word!
|
mul reg1, reg2 - unsigned multiply reg1 *= reg2 note: byte*byte->byte, no type extension to word!
|
||||||
div reg1, reg2, reg3 - unsigned division reg1=reg2/reg3 note: division by zero yields max signed int $ff/$ffff
|
div reg1, reg2 - unsigned division reg1 /= reg2 note: division by zero yields max signed int $ff/$ffff
|
||||||
mod reg1, reg2, reg3 - remainder (modulo) of unsigned division reg1=reg2%reg3 note: division by zero yields max signed int $ff/$ffff
|
mod reg1, reg2 - remainder (modulo) of unsigned division reg1 %= reg2 note: division by zero yields max signed int $ff/$ffff
|
||||||
sqrt reg1, reg2 - reg1 is the square root of reg2
|
sqrt reg1, reg2 - reg1 is the square root of reg2
|
||||||
sgn reg1, reg2 - reg1 is the sign of reg2 (0, 1 or -1)
|
sgn reg1, reg2 - reg1 is the sign of reg2 (0, 1 or -1)
|
||||||
cmp reg1, reg2 - set processor status bits C, N, Z according to comparison of reg1 with reg2. (semantics taken from 6502/68000 CMP instruction)
|
cmp reg1, reg2 - set processor status bits C, N, Z according to comparison of reg1 with reg2. (semantics taken from 6502/68000 CMP instruction)
|
||||||
@ -113,12 +113,12 @@ LOGICAL/BITWISE
|
|||||||
---------------
|
---------------
|
||||||
All have type b or w.
|
All have type b or w.
|
||||||
|
|
||||||
and reg1, reg2, reg3 - reg1 = reg2 bitwise and reg3
|
and reg1, reg2 - reg1 = reg1 bitwise and reg2
|
||||||
or reg1, reg2, reg3 - reg1 = reg2 bitwise or reg3
|
or reg1, reg2 - reg1 = reg1 bitwise or reg2
|
||||||
xor reg1, reg2, reg3 - reg1 = reg2 bitwise xor reg3
|
xor reg1, reg2 - reg1 = reg1 bitwise xor reg2
|
||||||
lsrn reg1, reg2, reg3 - reg1 = multi-shift reg2 right by reg3 bits + set Carry to shifted bit
|
lsrn reg1, reg2 - reg1 = multi-shift reg1 right by reg2 bits + set Carry to shifted bit
|
||||||
asrn reg1, reg2, reg3 - reg1 = multi-shift reg2 right by reg3 bits (signed) + set Carry to shifted bit
|
asrn reg1, reg2 - reg1 = multi-shift reg1 right by reg2 bits (signed) + set Carry to shifted bit
|
||||||
lsln reg1, reg2, reg3 - reg1 = multi-shift reg2 left by reg3 bits + set Carry to shifted bit
|
lsln reg1, reg2 - reg1 = multi-shift reg1 left by reg2 bits + set Carry to shifted bit
|
||||||
lsr reg1 - shift reg1 right by 1 bits + set Carry to shifted bit
|
lsr reg1 - shift reg1 right by 1 bits + set Carry to shifted bit
|
||||||
asr reg1 - shift reg1 right by 1 bits (signed) + set Carry to shifted bit
|
asr reg1 - shift reg1 right by 1 bits (signed) + set Carry to shifted bit
|
||||||
lsl reg1 - shift reg1 left by 1 bits + set Carry to shifted bit
|
lsl reg1 - shift reg1 left by 1 bits + set Carry to shifted bit
|
||||||
@ -151,7 +151,7 @@ sec - set Carry status bit
|
|||||||
nop - do nothing
|
nop - do nothing
|
||||||
breakpoint - trigger a breakpoint
|
breakpoint - trigger a breakpoint
|
||||||
msig [b, w] reg1, reg2 - reg1 becomes the most significant byte (or word) of the word (or int) in reg2 (.w not yet implemented; requires 32 bits regs)
|
msig [b, w] reg1, reg2 - reg1 becomes the most significant byte (or word) of the word (or int) in reg2 (.w not yet implemented; requires 32 bits regs)
|
||||||
concat [b, w] reg1, reg2, reg3 - reg1 = concatenated lsb/lsw of reg2 and lsb/lsw of reg3 into new word or int (int not yet implemented; requires 32bits regs)
|
concat [b, w] reg1, reg2 - reg1 = concatenated lsb/lsw of reg1 (as lsb) and lsb/lsw of reg2 (as msb) into word or int (int not yet implemented; requires 32bits regs)
|
||||||
push [b, w] reg1 - push value in reg1 on the stack
|
push [b, w] reg1 - push value in reg1 on the stack
|
||||||
pop [b, w] reg1 - pop value from stack into reg1
|
pop [b, w] reg1 - pop value from stack into reg1
|
||||||
|
|
||||||
@ -289,7 +289,6 @@ data class Instruction(
|
|||||||
val type: VmDataType?=null,
|
val type: VmDataType?=null,
|
||||||
val reg1: Int?=null, // 0-$ffff
|
val reg1: Int?=null, // 0-$ffff
|
||||||
val reg2: Int?=null, // 0-$ffff
|
val reg2: Int?=null, // 0-$ffff
|
||||||
val reg3: Int?=null, // 0-$ffff
|
|
||||||
val fpReg1: Int?=null, // 0-$ffff
|
val fpReg1: Int?=null, // 0-$ffff
|
||||||
val fpReg2: Int?=null, // 0-$ffff
|
val fpReg2: Int?=null, // 0-$ffff
|
||||||
val value: Int?=null, // 0-$ffff
|
val value: Int?=null, // 0-$ffff
|
||||||
@ -302,17 +301,13 @@ data class Instruction(
|
|||||||
throw IllegalArgumentException("missing type")
|
throw IllegalArgumentException("missing type")
|
||||||
|
|
||||||
val format = formats.getValue(type)
|
val format = formats.getValue(type)
|
||||||
if(format.reg1 && reg1==null ||
|
if(format.reg1 && reg1==null || format.reg2 && reg2==null)
|
||||||
format.reg2 && reg2==null ||
|
|
||||||
format.reg3 && reg3==null)
|
|
||||||
throw IllegalArgumentException("missing a register (int)")
|
throw IllegalArgumentException("missing a register (int)")
|
||||||
|
|
||||||
if(format.fpReg1 && fpReg1==null || format.fpReg2 && fpReg2==null)
|
if(format.fpReg1 && fpReg1==null || format.fpReg2 && fpReg2==null)
|
||||||
throw IllegalArgumentException("missing a register (float)")
|
throw IllegalArgumentException("missing a register (float)")
|
||||||
|
|
||||||
if(!format.reg1 && reg1!=null ||
|
if(!format.reg1 && reg1!=null || !format.reg2 && reg2!=null)
|
||||||
!format.reg2 && reg2!=null ||
|
|
||||||
!format.reg3 && reg3!=null)
|
|
||||||
throw IllegalArgumentException("too many registers (int)")
|
throw IllegalArgumentException("too many registers (int)")
|
||||||
|
|
||||||
if(!format.fpReg1 && fpReg1!=null || !format.fpReg2 && fpReg2!=null)
|
if(!format.fpReg1 && fpReg1!=null || !format.fpReg2 && fpReg2!=null)
|
||||||
@ -346,10 +341,6 @@ data class Instruction(
|
|||||||
result.add("r$it")
|
result.add("r$it")
|
||||||
result.add(",")
|
result.add(",")
|
||||||
}
|
}
|
||||||
reg3?.let {
|
|
||||||
result.add("r$it")
|
|
||||||
result.add(",")
|
|
||||||
}
|
|
||||||
fpReg1?.let {
|
fpReg1?.let {
|
||||||
result.add("fr$it")
|
result.add("fr$it")
|
||||||
result.add(",")
|
result.add(",")
|
||||||
@ -376,7 +367,7 @@ data class Instruction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class InstructionFormat(val datatype: VmDataType?,
|
data class InstructionFormat(val datatype: VmDataType?,
|
||||||
val reg1: Boolean, val reg2: Boolean, val reg3: Boolean,
|
val reg1: Boolean, val reg2: Boolean,
|
||||||
val fpReg1: Boolean, val fpReg2: Boolean,
|
val fpReg1: Boolean, val fpReg2: Boolean,
|
||||||
val value: Boolean,
|
val value: Boolean,
|
||||||
val fpValue: Boolean) {
|
val fpValue: Boolean) {
|
||||||
@ -386,7 +377,6 @@ data class InstructionFormat(val datatype: VmDataType?,
|
|||||||
for(part in spec.split('|').map{ it.trim() }) {
|
for(part in spec.split('|').map{ it.trim() }) {
|
||||||
var reg1 = false
|
var reg1 = false
|
||||||
var reg2 = false
|
var reg2 = false
|
||||||
var reg3 = false
|
|
||||||
var fpreg1 = false
|
var fpreg1 = false
|
||||||
var fpreg2 = false
|
var fpreg2 = false
|
||||||
var value = false
|
var value = false
|
||||||
@ -397,7 +387,6 @@ data class InstructionFormat(val datatype: VmDataType?,
|
|||||||
when(splits.next()) {
|
when(splits.next()) {
|
||||||
"r1" -> reg1=true
|
"r1" -> reg1=true
|
||||||
"r2" -> reg2=true
|
"r2" -> reg2=true
|
||||||
"r3" -> reg3=true
|
|
||||||
"fr1" -> fpreg1=true
|
"fr1" -> fpreg1=true
|
||||||
"fr2" -> fpreg2=true
|
"fr2" -> fpreg2=true
|
||||||
"v" -> value = true
|
"v" -> value = true
|
||||||
@ -406,13 +395,13 @@ data class InstructionFormat(val datatype: VmDataType?,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(typespec=="N")
|
if(typespec=="N")
|
||||||
result[null] = InstructionFormat(null, reg1=reg1, reg2=reg2, reg3=reg3, fpReg1=fpreg1, fpReg2=fpreg2, value=value, fpValue=fpvalue)
|
result[null] = InstructionFormat(null, reg1=reg1, reg2=reg2, fpReg1=fpreg1, fpReg2=fpreg2, value=value, fpValue=fpvalue)
|
||||||
if('B' in typespec)
|
if('B' in typespec)
|
||||||
result[VmDataType.BYTE] = InstructionFormat(VmDataType.BYTE, reg1=reg1, reg2=reg2, reg3=reg3, fpReg1=fpreg1, fpReg2=fpreg2, value=value, fpValue=fpvalue)
|
result[VmDataType.BYTE] = InstructionFormat(VmDataType.BYTE, reg1=reg1, reg2=reg2, fpReg1=fpreg1, fpReg2=fpreg2, value=value, fpValue=fpvalue)
|
||||||
if('W' in typespec)
|
if('W' in typespec)
|
||||||
result[VmDataType.WORD] = InstructionFormat(VmDataType.WORD, reg1=reg1, reg2=reg2, reg3=reg3, fpReg1=fpreg1, fpReg2=fpreg2, value=value, fpValue=fpvalue)
|
result[VmDataType.WORD] = InstructionFormat(VmDataType.WORD, reg1=reg1, reg2=reg2, fpReg1=fpreg1, fpReg2=fpreg2, value=value, fpValue=fpvalue)
|
||||||
if('F' in typespec)
|
if('F' in typespec)
|
||||||
result[VmDataType.FLOAT] = InstructionFormat(VmDataType.FLOAT, reg1=reg1, reg2=reg2, reg3=reg3, fpReg1=fpreg1, fpReg2=fpreg2, value=value, fpValue=fpvalue)
|
result[VmDataType.FLOAT] = InstructionFormat(VmDataType.FLOAT, reg1=reg1, reg2=reg2, fpReg1=fpreg1, fpReg2=fpreg2, value=value, fpValue=fpvalue)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -456,38 +445,38 @@ val instructionFormats = mutableMapOf(
|
|||||||
Opcode.BLES to InstructionFormat.from("BW,r1,r2,v"),
|
Opcode.BLES to InstructionFormat.from("BW,r1,r2,v"),
|
||||||
Opcode.BGE 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.BGES to InstructionFormat.from("BW,r1,r2,v"),
|
||||||
Opcode.SEQ to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.SEQ to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.SNE to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.SNE to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.SLT to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.SLT to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.SLTS to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.SLTS to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.SGT to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.SGT to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.SGTS to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.SGTS to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.SLE to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.SLE to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.SLES to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.SLES to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.SGE to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.SGE to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.SGES to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.SGES to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.INC to InstructionFormat.from("BW,r1"),
|
Opcode.INC to InstructionFormat.from("BW,r1"),
|
||||||
Opcode.INCM to InstructionFormat.from("BW,v"),
|
Opcode.INCM to InstructionFormat.from("BW,v"),
|
||||||
Opcode.DEC to InstructionFormat.from("BW,r1"),
|
Opcode.DEC to InstructionFormat.from("BW,r1"),
|
||||||
Opcode.DECM to InstructionFormat.from("BW,v"),
|
Opcode.DECM to InstructionFormat.from("BW,v"),
|
||||||
Opcode.NEG to InstructionFormat.from("BW,r1 | F,fr1"),
|
Opcode.NEG to InstructionFormat.from("BW,r1 | F,fr1"),
|
||||||
Opcode.ADD to InstructionFormat.from("BW,r1,r2,r3 | F,fr1,fr2"),
|
Opcode.ADD to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
|
||||||
Opcode.SUB to InstructionFormat.from("BW,r1,r2,r3 | F,fr1,fr2"),
|
Opcode.SUB to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
|
||||||
Opcode.MUL to InstructionFormat.from("BW,r1,r2,r3 | F,fr1,fr2"),
|
Opcode.MUL to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
|
||||||
Opcode.DIV to InstructionFormat.from("BW,r1,r2,r3 | F,fr1,fr2"),
|
Opcode.DIV to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
|
||||||
Opcode.SQRT to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
|
Opcode.SQRT to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
|
||||||
Opcode.SGN to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
|
Opcode.SGN to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
|
||||||
Opcode.RND to InstructionFormat.from("BW,r1 | F,fr1"),
|
Opcode.RND to InstructionFormat.from("BW,r1 | F,fr1"),
|
||||||
Opcode.MOD to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.MOD to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.CMP to InstructionFormat.from("BW,r1,r2"),
|
Opcode.CMP to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.EXT to InstructionFormat.from("BW,r1"),
|
Opcode.EXT to InstructionFormat.from("BW,r1"),
|
||||||
Opcode.EXTS to InstructionFormat.from("BW,r1"),
|
Opcode.EXTS to InstructionFormat.from("BW,r1"),
|
||||||
Opcode.AND to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.AND to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.OR to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.OR to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.XOR to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.XOR to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.ASRN to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.ASRN to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.LSRN to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.LSRN to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.LSLN to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.LSLN to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.ASR to InstructionFormat.from("BW,r1"),
|
Opcode.ASR to InstructionFormat.from("BW,r1"),
|
||||||
Opcode.LSR to InstructionFormat.from("BW,r1"),
|
Opcode.LSR to InstructionFormat.from("BW,r1"),
|
||||||
Opcode.LSL to InstructionFormat.from("BW,r1"),
|
Opcode.LSL to InstructionFormat.from("BW,r1"),
|
||||||
@ -521,7 +510,7 @@ val instructionFormats = mutableMapOf(
|
|||||||
Opcode.MSIG to InstructionFormat.from("BW,r1,r2"),
|
Opcode.MSIG to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.PUSH to InstructionFormat.from("BW,r1"),
|
Opcode.PUSH to InstructionFormat.from("BW,r1"),
|
||||||
Opcode.POP to InstructionFormat.from("BW,r1"),
|
Opcode.POP to InstructionFormat.from("BW,r1"),
|
||||||
Opcode.CONCAT to InstructionFormat.from("BW,r1,r2,r3"),
|
Opcode.CONCAT to InstructionFormat.from("BW,r1,r2"),
|
||||||
Opcode.CLC to InstructionFormat.from("N"),
|
Opcode.CLC to InstructionFormat.from("N"),
|
||||||
Opcode.SEC to InstructionFormat.from("N"),
|
Opcode.SEC to InstructionFormat.from("N"),
|
||||||
Opcode.BREAKPOINT to InstructionFormat.from("N"),
|
Opcode.BREAKPOINT to InstructionFormat.from("N"),
|
||||||
|
@ -527,73 +527,73 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSEQ(i: Instruction) {
|
private fun InsSEQ(i: Instruction) {
|
||||||
val (resultReg: Int, left: Int, right: Int) = getSetOnConditionOperands(i)
|
val (left: Int, right: Int) = getSetOnConditionOperands(i)
|
||||||
val value = if(left==right) 1 else 0
|
val value = if(left==right) 1 else 0
|
||||||
setResultReg(resultReg, value, i.type!!)
|
setResultReg(i.reg1!!, value, i.type!!)
|
||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSNE(i: Instruction) {
|
private fun InsSNE(i: Instruction) {
|
||||||
val (resultReg: Int, left: Int, right: Int) = getSetOnConditionOperands(i)
|
val (left: Int, right: Int) = getSetOnConditionOperands(i)
|
||||||
val value = if(left!=right) 1 else 0
|
val value = if(left!=right) 1 else 0
|
||||||
setResultReg(resultReg, value, i.type!!)
|
setResultReg(i.reg1!!, value, i.type!!)
|
||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSLT(i: Instruction) {
|
private fun InsSLT(i: Instruction) {
|
||||||
val (resultReg, left, right) = getSetOnConditionOperandsU(i)
|
val (left, right) = getSetOnConditionOperandsU(i)
|
||||||
val value = if(left<right) 1 else 0
|
val value = if(left<right) 1 else 0
|
||||||
setResultReg(resultReg, value, i.type!!)
|
setResultReg(i.reg1!!, value, i.type!!)
|
||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSLTS(i: Instruction) {
|
private fun InsSLTS(i: Instruction) {
|
||||||
val (resultReg, left, right) = getSetOnConditionOperands(i)
|
val (left, right) = getSetOnConditionOperands(i)
|
||||||
val value = if(left<right) 1 else 0
|
val value = if(left<right) 1 else 0
|
||||||
setResultReg(resultReg, value, i.type!!)
|
setResultReg(i.reg1!!, value, i.type!!)
|
||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSGT(i: Instruction) {
|
private fun InsSGT(i: Instruction) {
|
||||||
val (resultReg, left, right) = getSetOnConditionOperandsU(i)
|
val (left, right) = getSetOnConditionOperandsU(i)
|
||||||
val value = if(left>right) 1 else 0
|
val value = if(left>right) 1 else 0
|
||||||
setResultReg(resultReg, value, i.type!!)
|
setResultReg(i.reg1!!, value, i.type!!)
|
||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSGTS(i: Instruction) {
|
private fun InsSGTS(i: Instruction) {
|
||||||
val (resultReg, left, right) = getSetOnConditionOperands(i)
|
val (left, right) = getSetOnConditionOperands(i)
|
||||||
val value = if(left>right) 1 else 0
|
val value = if(left>right) 1 else 0
|
||||||
setResultReg(resultReg, value, i.type!!)
|
setResultReg(i.reg1!!, value, i.type!!)
|
||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSLE(i: Instruction) {
|
private fun InsSLE(i: Instruction) {
|
||||||
val (resultReg, left, right) = getSetOnConditionOperandsU(i)
|
val (left, right) = getSetOnConditionOperandsU(i)
|
||||||
val value = if(left<=right) 1 else 0
|
val value = if(left<=right) 1 else 0
|
||||||
setResultReg(resultReg, value, i.type!!)
|
setResultReg(i.reg1!!, value, i.type!!)
|
||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSLES(i: Instruction) {
|
private fun InsSLES(i: Instruction) {
|
||||||
val (resultReg, left, right) = getSetOnConditionOperands(i)
|
val (left, right) = getSetOnConditionOperands(i)
|
||||||
val value = if(left<=right) 1 else 0
|
val value = if(left<=right) 1 else 0
|
||||||
setResultReg(resultReg, value, i.type!!)
|
setResultReg(i.reg1!!, value, i.type!!)
|
||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSGE(i: Instruction) {
|
private fun InsSGE(i: Instruction) {
|
||||||
val (resultReg, left, right) = getSetOnConditionOperandsU(i)
|
val (left, right) = getSetOnConditionOperandsU(i)
|
||||||
val value = if(left>=right) 1 else 0
|
val value = if(left>=right) 1 else 0
|
||||||
setResultReg(resultReg, value, i.type!!)
|
setResultReg(i.reg1!!, value, i.type!!)
|
||||||
pc++
|
pc++
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSGES(i: Instruction) {
|
private fun InsSGES(i: Instruction) {
|
||||||
val (resultReg, left, right) = getSetOnConditionOperands(i)
|
val (left, right) = getSetOnConditionOperands(i)
|
||||||
val value = if(left>=right) 1 else 0
|
val value = if(left>=right) 1 else 0
|
||||||
setResultReg(resultReg, value, i.type!!)
|
setResultReg(i.reg1!!, value, i.type!!)
|
||||||
pc++
|
pc++
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -645,8 +645,8 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
|
|
||||||
private fun InsADD(i: Instruction) {
|
private fun InsADD(i: Instruction) {
|
||||||
when(i.type!!) {
|
when(i.type!!) {
|
||||||
VmDataType.BYTE -> arithByte("+", i.reg1!!, i.reg2!!, i.reg3!!)
|
VmDataType.BYTE -> arithByte("+", i.reg1!!, i.reg2!!)
|
||||||
VmDataType.WORD -> arithWord("+", i.reg1!!, i.reg2!!, i.reg3!!)
|
VmDataType.WORD -> arithWord("+", i.reg1!!, i.reg2!!)
|
||||||
VmDataType.FLOAT -> arithFloat("+", i.fpReg1!!, i.fpReg2!!)
|
VmDataType.FLOAT -> arithFloat("+", i.fpReg1!!, i.fpReg2!!)
|
||||||
}
|
}
|
||||||
pc++
|
pc++
|
||||||
@ -654,16 +654,16 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
|
|
||||||
private fun InsSUB(i: Instruction) {
|
private fun InsSUB(i: Instruction) {
|
||||||
when(i.type!!) {
|
when(i.type!!) {
|
||||||
VmDataType.BYTE -> arithByte("-", i.reg1!!, i.reg2!!, i.reg3!!)
|
VmDataType.BYTE -> arithByte("-", i.reg1!!, i.reg2!!)
|
||||||
VmDataType.WORD -> arithWord("-", i.reg1!!, i.reg2!!, i.reg3!!)
|
VmDataType.WORD -> arithWord("-", i.reg1!!, i.reg2!!)
|
||||||
VmDataType.FLOAT -> arithFloat("-", i.fpReg1!!, i.fpReg2!!)
|
VmDataType.FLOAT -> arithFloat("-", i.fpReg1!!, i.fpReg2!!)
|
||||||
}
|
}
|
||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
private fun InsMUL(i: Instruction) {
|
private fun InsMUL(i: Instruction) {
|
||||||
when(i.type!!) {
|
when(i.type!!) {
|
||||||
VmDataType.BYTE -> arithByte("*", i.reg1!!, i.reg2!!, i.reg3!!)
|
VmDataType.BYTE -> arithByte("*", i.reg1!!, i.reg2!!)
|
||||||
VmDataType.WORD -> arithWord("*", i.reg1!!, i.reg2!!, i.reg3!!)
|
VmDataType.WORD -> arithWord("*", i.reg1!!, i.reg2!!)
|
||||||
VmDataType.FLOAT -> arithFloat("*", i.fpReg1!!, i.fpReg2!!)
|
VmDataType.FLOAT -> arithFloat("*", i.fpReg1!!, i.fpReg2!!)
|
||||||
}
|
}
|
||||||
pc++
|
pc++
|
||||||
@ -671,8 +671,8 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
|
|
||||||
private fun InsDIV(i: Instruction) {
|
private fun InsDIV(i: Instruction) {
|
||||||
when(i.type!!) {
|
when(i.type!!) {
|
||||||
VmDataType.BYTE -> arithByte("/", i.reg1!!, i.reg2!!, i.reg3!!)
|
VmDataType.BYTE -> arithByte("/", i.reg1!!, i.reg2!!)
|
||||||
VmDataType.WORD -> arithWord("/", i.reg1!!, i.reg2!!, i.reg3!!)
|
VmDataType.WORD -> arithWord("/", i.reg1!!, i.reg2!!)
|
||||||
VmDataType.FLOAT -> arithFloat("/", i.fpReg1!!, i.fpReg2!!)
|
VmDataType.FLOAT -> arithFloat("/", i.fpReg1!!, i.fpReg2!!)
|
||||||
}
|
}
|
||||||
pc++
|
pc++
|
||||||
@ -680,8 +680,8 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
|
|
||||||
private fun InsMOD(i: Instruction) {
|
private fun InsMOD(i: Instruction) {
|
||||||
when(i.type!!) {
|
when(i.type!!) {
|
||||||
VmDataType.BYTE -> arithByte("%", i.reg1!!, i.reg2!!, i.reg3!!)
|
VmDataType.BYTE -> arithByte("%", i.reg1!!, i.reg2!!)
|
||||||
VmDataType.WORD -> arithWord("%", i.reg1!!, i.reg2!!, i.reg3!!)
|
VmDataType.WORD -> arithWord("%", i.reg1!!, i.reg2!!)
|
||||||
VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||||
}
|
}
|
||||||
pc++
|
pc++
|
||||||
@ -744,9 +744,9 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun arithByte(operator: String, reg1: Int, reg2: Int, reg3: Int) {
|
private fun arithByte(operator: String, reg1: Int, reg2: Int) {
|
||||||
val left = registers.getUB(reg2)
|
val left = registers.getUB(reg1)
|
||||||
val right = registers.getUB(reg3)
|
val right = registers.getUB(reg2)
|
||||||
val result = when(operator) {
|
val result = when(operator) {
|
||||||
"+" -> left + right
|
"+" -> left + right
|
||||||
"-" -> left - right
|
"-" -> left - right
|
||||||
@ -764,9 +764,9 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
registers.setUB(reg1, result.toUByte())
|
registers.setUB(reg1, result.toUByte())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun arithWord(operator: String, reg1: Int, reg2: Int, reg3: Int) {
|
private fun arithWord(operator: String, reg1: Int, reg2: Int) {
|
||||||
val left = registers.getUW(reg2)
|
val left = registers.getUW(reg1)
|
||||||
val right = registers.getUW(reg3)
|
val right = registers.getUW(reg2)
|
||||||
val result = when(operator) {
|
val result = when(operator) {
|
||||||
"+" -> left + right
|
"+" -> left + right
|
||||||
"-" -> left - right
|
"-" -> left - right
|
||||||
@ -1019,9 +1019,9 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
private fun InsCONCAT(i: Instruction) {
|
private fun InsCONCAT(i: Instruction) {
|
||||||
when(i.type!!) {
|
when(i.type!!) {
|
||||||
VmDataType.BYTE -> {
|
VmDataType.BYTE -> {
|
||||||
|
val lsb = registers.getUB(i.reg1!!)
|
||||||
val msb = registers.getUB(i.reg2!!)
|
val msb = registers.getUB(i.reg2!!)
|
||||||
val lsb = registers.getUB(i.reg3!!)
|
registers.setUW(i.reg1, ((msb.toInt() shl 8) or lsb.toInt()).toUShort())
|
||||||
registers.setUW(i.reg1!!, ((msb.toInt() shl 8) or lsb.toInt()).toUShort())
|
|
||||||
}
|
}
|
||||||
VmDataType.WORD -> TODO("concat.w not yet supported, requires 32-bits registers")
|
VmDataType.WORD -> TODO("concat.w not yet supported, requires 32-bits registers")
|
||||||
VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||||
@ -1180,8 +1180,8 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
|
|
||||||
private fun getLogicalOperandsU(i: Instruction): Pair<UInt, UInt> {
|
private fun getLogicalOperandsU(i: Instruction): Pair<UInt, UInt> {
|
||||||
return when(i.type) {
|
return when(i.type) {
|
||||||
VmDataType.BYTE -> Pair(registers.getUB(i.reg2!!).toUInt(), registers.getUB(i.reg3!!).toUInt())
|
VmDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), registers.getUB(i.reg2!!).toUInt())
|
||||||
VmDataType.WORD -> Pair(registers.getUW(i.reg2!!).toUInt(), registers.getUW(i.reg3!!).toUInt())
|
VmDataType.WORD -> Pair(registers.getUW(i.reg1!!).toUInt(), registers.getUW(i.reg2!!).toUInt())
|
||||||
VmDataType.FLOAT -> {
|
VmDataType.FLOAT -> {
|
||||||
throw IllegalArgumentException("can't use float here")
|
throw IllegalArgumentException("can't use float here")
|
||||||
}
|
}
|
||||||
@ -1191,8 +1191,8 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
|
|
||||||
private fun getLogicalOperandsS(i: Instruction): Pair<Int, Int> {
|
private fun getLogicalOperandsS(i: Instruction): Pair<Int, Int> {
|
||||||
return when(i.type) {
|
return when(i.type) {
|
||||||
VmDataType.BYTE -> Pair(registers.getSB(i.reg2!!).toInt(), registers.getSB(i.reg3!!).toInt())
|
VmDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt())
|
||||||
VmDataType.WORD -> Pair(registers.getSW(i.reg2!!).toInt(), registers.getSW(i.reg3!!).toInt())
|
VmDataType.WORD -> Pair(registers.getSW(i.reg1!!).toInt(), registers.getSW(i.reg2!!).toInt())
|
||||||
VmDataType.FLOAT -> {
|
VmDataType.FLOAT -> {
|
||||||
throw IllegalArgumentException("can't use float here")
|
throw IllegalArgumentException("can't use float here")
|
||||||
}
|
}
|
||||||
@ -1200,10 +1200,10 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSetOnConditionOperands(ins: Instruction): Triple<Int, Int, Int> {
|
private fun getSetOnConditionOperands(ins: Instruction): Pair<Int, Int> {
|
||||||
return when(ins.type) {
|
return when(ins.type) {
|
||||||
VmDataType.BYTE -> Triple(ins.reg1!!, registers.getSB(ins.reg2!!).toInt(), registers.getSB(ins.reg3!!).toInt())
|
VmDataType.BYTE -> Pair(registers.getSB(ins.reg1!!).toInt(), registers.getSB(ins.reg2!!).toInt())
|
||||||
VmDataType.WORD -> Triple(ins.reg1!!, registers.getSW(ins.reg2!!).toInt(), registers.getSW(ins.reg3!!).toInt())
|
VmDataType.WORD -> Pair(registers.getSW(ins.reg1!!).toInt(), registers.getSW(ins.reg2!!).toInt())
|
||||||
VmDataType.FLOAT -> {
|
VmDataType.FLOAT -> {
|
||||||
throw IllegalArgumentException("can't use float here")
|
throw IllegalArgumentException("can't use float here")
|
||||||
}
|
}
|
||||||
@ -1211,10 +1211,10 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSetOnConditionOperandsU(ins: Instruction): Triple<Int, UInt, UInt> {
|
private fun getSetOnConditionOperandsU(ins: Instruction): Pair<UInt, UInt> {
|
||||||
return when(ins.type) {
|
return when(ins.type) {
|
||||||
VmDataType.BYTE -> Triple(ins.reg1!!, registers.getUB(ins.reg2!!).toUInt(), registers.getUB(ins.reg3!!).toUInt())
|
VmDataType.BYTE -> Pair(registers.getUB(ins.reg1!!).toUInt(), registers.getUB(ins.reg2!!).toUInt())
|
||||||
VmDataType.WORD -> Triple(ins.reg1!!, registers.getUW(ins.reg2!!).toUInt(), registers.getUW(ins.reg3!!).toUInt())
|
VmDataType.WORD -> Pair(registers.getUW(ins.reg1!!).toUInt(), registers.getUW(ins.reg2!!).toUInt())
|
||||||
VmDataType.FLOAT -> {
|
VmDataType.FLOAT -> {
|
||||||
throw IllegalArgumentException("can't use float here")
|
throw IllegalArgumentException("can't use float here")
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ class TestInstructions: FunSpec({
|
|||||||
ins.type shouldBe null
|
ins.type shouldBe null
|
||||||
ins.reg1 shouldBe null
|
ins.reg1 shouldBe null
|
||||||
ins.reg2 shouldBe null
|
ins.reg2 shouldBe null
|
||||||
ins.reg3 shouldBe null
|
|
||||||
ins.value shouldBe null
|
ins.value shouldBe null
|
||||||
ins.symbol shouldBe null
|
ins.symbol shouldBe null
|
||||||
ins.toString() shouldBe "nop"
|
ins.toString() shouldBe "nop"
|
||||||
@ -28,7 +27,6 @@ class TestInstructions: FunSpec({
|
|||||||
ins.type shouldBe VmDataType.BYTE
|
ins.type shouldBe VmDataType.BYTE
|
||||||
ins.reg1 shouldBe 42
|
ins.reg1 shouldBe 42
|
||||||
ins.reg2 shouldBe null
|
ins.reg2 shouldBe null
|
||||||
ins.reg3 shouldBe null
|
|
||||||
ins.value shouldBe 9999
|
ins.value shouldBe 9999
|
||||||
ins.symbol shouldBe null
|
ins.symbol shouldBe null
|
||||||
ins.toString() shouldBe "bz.b r42,9999"
|
ins.toString() shouldBe "bz.b r42,9999"
|
||||||
@ -40,7 +38,6 @@ class TestInstructions: FunSpec({
|
|||||||
ins.type shouldBe VmDataType.WORD
|
ins.type shouldBe VmDataType.WORD
|
||||||
ins.reg1 shouldBe 11
|
ins.reg1 shouldBe 11
|
||||||
ins.reg2 shouldBe null
|
ins.reg2 shouldBe null
|
||||||
ins.reg3 shouldBe null
|
|
||||||
ins.value shouldBe null
|
ins.value shouldBe null
|
||||||
ins.symbol shouldBe listOf("a","b","c")
|
ins.symbol shouldBe listOf("a","b","c")
|
||||||
ins.toString() shouldBe "bz.w r11,_a.b.c"
|
ins.toString() shouldBe "bz.w r11,_a.b.c"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user