vm: limit int instructions to just 2 register args

This commit is contained in:
Irmen de Jong 2022-05-11 22:35:02 +02:00
parent 4be7bc8323
commit 517cf61d11
10 changed files with 141 additions and 183 deletions

View File

@ -77,22 +77,19 @@ internal class VmCodeInstruction(
type: VmDataType?=null,
reg1: Int?=null, // 0-$ffff
reg2: Int?=null, // 0-$ffff
reg3: Int?=null, // 0-$ffff
fpReg1: Int?=null, // 0-$ffff
fpReg2: Int?=null, // 0-$ffff
value: Int?=null, // 0-$ffff
fpValue: Float?=null,
symbol: List<String>?=null // alternative to value
): 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 {
if(reg1!=null && (reg1<0 || reg1>65536))
throw IllegalArgumentException("reg1 out of bounds")
if(reg2!=null && (reg2<0 || reg2>65536))
throw IllegalArgumentException("reg2 out of bounds")
if(reg3!=null && (reg3<0 || reg3>65536))
throw IllegalArgumentException("reg3 out of bounds")
if(fpReg1!=null && (fpReg1<0 || fpReg1>65536))
throw IllegalArgumentException("fpReg1 out of bounds")
if(fpReg2!=null && (fpReg2<0 || fpReg2>65536))

View File

@ -115,7 +115,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
val andReg = codeGen.vmRegisters.nextFree()
val notNegativeLabel = codeGen.createLabelName()
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.NEG, 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 notNegativeLabel = codeGen.createLabelName()
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.NEG, VmDataType.WORD, reg1=resultRegister)
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 {
val msbReg = codeGen.vmRegisters.nextFree()
val lsbReg = codeGen.vmRegisters.nextFree()
val code = VmCodeChunk()
code += exprGen.translateExpression(call.args[0], msbReg, -1)
code += exprGen.translateExpression(call.args[1], lsbReg, -1)
code += VmCodeInstruction(Opcode.CONCAT, VmDataType.BYTE, reg1=resultRegister, reg2=msbReg, reg3=lsbReg)
code += exprGen.translateExpression(call.args[1], resultRegister, -1)
code += VmCodeInstruction(Opcode.CONCAT, VmDataType.BYTE, reg1=resultRegister, reg2=msbReg)
return code
}

View File

@ -331,11 +331,11 @@ class CodeGen(internal val program: PtProgram,
val valueReg = vmRegisters.nextFree()
if(value>0) {
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 {
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) {
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=value)
code += VmCodeInstruction(Opcode.ADD, dt, reg1 = valueReg, reg2 = valueReg, reg3 = operandReg)
code += VmCodeInstruction(Opcode.ADD, dt, reg1 = valueReg, reg2 = operandReg)
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
}
else {
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=-value)
code += VmCodeInstruction(Opcode.SUB, dt, reg1 = valueReg, reg2 = valueReg, reg3 = operandReg)
code += VmCodeInstruction(Opcode.SUB, dt, reg1 = valueReg, reg2 = operandReg)
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
}
}
@ -409,7 +409,7 @@ class CodeGen(internal val program: PtProgram,
// just shift multiple bits
val pow2reg = vmRegisters.nextFree()
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 {
if (factor == 0) {
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0)
@ -417,7 +417,7 @@ class CodeGen(internal val program: PtProgram,
else {
val factorReg = vmRegisters.nextFree()
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
@ -450,7 +450,7 @@ class CodeGen(internal val program: PtProgram,
// just shift multiple bits
val pow2reg = vmRegisters.nextFree()
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 {
if (factor == 0) {
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
@ -458,7 +458,7 @@ class CodeGen(internal val program: PtProgram,
else {
val factorReg = vmRegisters.nextFree()
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

View File

@ -185,7 +185,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val regMask = codeGen.vmRegisters.nextFree()
val mask = if(vmDt==VmDataType.BYTE) 0x00ff else 0xffff
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" -> {
val label = codeGen.createLabelName()
@ -194,7 +194,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += VmCodeLabel(label)
val regMask = codeGen.vmRegisters.nextFree()
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")
}
@ -329,7 +329,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
} else {
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 {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
@ -339,7 +339,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
} else {
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
}
@ -365,7 +365,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
} else {
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 {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
@ -375,7 +375,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
} else {
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
}
@ -395,14 +395,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += VmCodeLabel(label)
val regMask = codeGen.vmRegisters.nextFree()
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 {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
val opcode = if (notEquals) Opcode.SNE else Opcode.SEQ
code += VmCodeInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = resultRegister, reg3 = rightResultReg)
code += VmCodeInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
return code
}
@ -418,7 +418,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
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
}
@ -432,7 +432,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
code += VmCodeInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, rightResultReg)
}
return code
}
@ -442,7 +442,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=rightResultReg)
return code
}
@ -451,7 +451,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.AND, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
code += VmCodeInstruction(Opcode.AND, vmDt, reg1=resultRegister, reg2=rightResultReg)
return code
}
@ -460,7 +460,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.OR, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
code += VmCodeInstruction(Opcode.OR, vmDt, reg1=resultRegister, reg2=rightResultReg)
return code
}
@ -471,7 +471,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.MOD, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
code += VmCodeInstruction(Opcode.MOD, vmDt, reg1=resultRegister, reg2=rightResultReg)
return code
}
@ -498,7 +498,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.DIV, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
code += VmCodeInstruction(Opcode.DIV, vmDt, reg1=resultRegister, reg2=rightResultReg)
}
}
return code
@ -536,7 +536,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.MUL, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
code += VmCodeInstruction(Opcode.MUL, vmDt, reg1=resultRegister, reg2=rightResultReg)
}
}
return code
@ -564,7 +564,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.SUB, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
code += VmCodeInstruction(Opcode.SUB, vmDt, reg1=resultRegister, reg2=rightResultReg)
}
}
return code
@ -600,7 +600,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.ADD, vmDt, reg1=resultRegister, reg2=resultRegister, reg3=rightResultReg)
code += VmCodeInstruction(Opcode.ADD, vmDt, reg1=resultRegister, reg2=rightResultReg)
}
}
return code

View File

@ -3,7 +3,6 @@ TODO
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: 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.

View File

@ -25,29 +25,10 @@ main {
ubyte @shared value = inline_candidate()
float fl1 = 1.1
float fl2 = 2.2
floats.print_f(floats.pow(fl1,fl2))
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")
ubyte lowb = $31
ubyte highb = $ea
uword result = mkword(highb, lowb)
txt.print_uwhex(result, true)
; txt.print_ub(inline_candidate())
; txt.nl()

View File

@ -157,10 +157,10 @@ class Assembler {
fpReg2 = fpReg3
fpReg3 = null
}
if(reg3!=null)
throw IllegalArgumentException("too many reg arguments $line")
if(fpReg3!=null)
throw IllegalArgumentException("too many fpreg arguments $line")
// TODO also check reg3
if(type!=null && type !in formats)
throw IllegalArgumentException("invalid type code for $line")
@ -168,16 +168,12 @@ class Assembler {
throw IllegalArgumentException("needs reg1 for $line")
if(format.reg2 && reg2==null)
throw IllegalArgumentException("needs reg2 for $line")
if(format.reg3 && reg3==null)
throw IllegalArgumentException("needs reg3 for $line")
if(format.value && value==null)
throw IllegalArgumentException("needs value for $line")
if(!format.reg1 && reg1!=null)
throw IllegalArgumentException("invalid reg1 for $line")
if(!format.reg2 && reg2!=null)
throw IllegalArgumentException("invalid reg2 for $line")
if(!format.reg3 && reg3!=null)
throw IllegalArgumentException("invalid reg3 for $line")
if(value!=null && opcode !in OpcodesWithAddress) {
when (type) {
VmDataType.BYTE -> {
@ -200,7 +196,7 @@ class Assembler {
if(format.fpValue)
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))
}
}

View File

@ -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)
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)
seq reg1, reg2, reg3 - set reg=1 if reg2 == reg3, otherwise set reg1=0
sne reg1, reg2, reg3 - set reg=1 if reg2 != reg3, otherwise set reg1=0
slt reg1, reg2, reg3 - set reg=1 if reg2 < reg3 (unsigned), otherwise set reg1=0
slts reg1, reg2, reg3 - set reg=1 if reg2 < reg3 (signed), otherwise set reg1=0
sle reg1, reg2, reg3 - set reg=1 if reg2 <= reg3 (unsigned), otherwise set reg1=0
sles reg1, reg2, reg3 - set reg=1 if reg2 <= reg3 (signed), otherwise set reg1=0
sgt reg1, reg2, reg3 - set reg=1 if reg2 > reg3 (unsigned), otherwise set reg1=0
sgts reg1, reg2, reg3 - set reg=1 if reg2 > reg3 (signed), otherwise set reg1=0
sge reg1, reg2, reg3 - set reg=1 if reg2 >= reg3 (unsigned), otherwise set reg1=0
sges reg1, reg2, reg3 - set reg=1 if reg2 >= reg3 (signed), otherwise set reg1=0
seq reg1, reg2 - set reg=1 if reg1 == reg2, otherwise set reg1=0
sne reg1, reg2 - set reg=1 if reg1 != reg2, otherwise set reg1=0
slt reg1, reg2 - set reg=1 if reg1 < reg2 (unsigned), otherwise set reg1=0
slts reg1, reg2 - set reg=1 if reg1 < reg2 (signed), otherwise set reg1=0
sle reg1, reg2 - set reg=1 if reg1 <= reg2 (unsigned), otherwise set reg1=0
sles reg1, reg2 - set reg=1 if reg1 <= reg2 (signed), otherwise set reg1=0
sgt reg1, reg2 - set reg=1 if reg1 > reg2 (unsigned), otherwise set reg1=0
sgts reg1, reg2 - set reg=1 if reg1 > reg2 (signed), otherwise set reg1=0
sge reg1, reg2 - set reg=1 if reg1 >= reg2 (unsigned), otherwise set reg1=0
sges reg1, reg2 - set reg=1 if reg1 >= reg2 (signed), otherwise set reg1=0
ARITHMETIC
@ -96,11 +96,11 @@ incm address - memory at address += 1
dec reg1 - reg1 = reg1-1
decm address - memory at address -= 1
neg reg1 - reg1 = sign negation of reg1
add reg1, reg2, reg3 - reg1 = reg2+reg3 (unsigned + signed)
sub reg1, reg2, reg3 - reg1 = reg2-reg3 (unsigned + signed)
mul reg1, reg2, reg3 - unsigned multiply reg1=reg2*reg3 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
mod reg1, reg2, reg3 - remainder (modulo) of unsigned division reg1=reg2%reg3 note: division by zero yields max signed int $ff/$ffff
add reg1, reg2 - reg1 += reg2 (unsigned + signed)
sub reg1, reg2 - reg1 -= reg2 (unsigned + signed)
mul reg1, reg2 - unsigned multiply reg1 *= reg2 note: byte*byte->byte, no type extension to word!
div reg1, reg2 - unsigned division reg1 /= reg2 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
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)
@ -113,12 +113,12 @@ LOGICAL/BITWISE
---------------
All have type b or w.
and reg1, reg2, reg3 - reg1 = reg2 bitwise and reg3
or reg1, reg2, reg3 - reg1 = reg2 bitwise or reg3
xor reg1, reg2, reg3 - reg1 = reg2 bitwise xor reg3
lsrn reg1, reg2, reg3 - reg1 = multi-shift reg2 right by reg3 bits + set Carry to shifted bit
asrn reg1, reg2, reg3 - reg1 = multi-shift reg2 right by reg3 bits (signed) + set Carry to shifted bit
lsln reg1, reg2, reg3 - reg1 = multi-shift reg2 left by reg3 bits + set Carry to shifted bit
and reg1, reg2 - reg1 = reg1 bitwise and reg2
or reg1, reg2 - reg1 = reg1 bitwise or reg2
xor reg1, reg2 - reg1 = reg1 bitwise xor reg2
lsrn reg1, reg2 - reg1 = multi-shift reg1 right by reg2 bits + 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 - 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
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
@ -151,7 +151,7 @@ sec - set Carry status bit
nop - do nothing
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)
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
pop [b, w] reg1 - pop value from stack into reg1
@ -289,7 +289,6 @@ data class Instruction(
val type: VmDataType?=null,
val reg1: Int?=null, // 0-$ffff
val reg2: Int?=null, // 0-$ffff
val reg3: Int?=null, // 0-$ffff
val fpReg1: Int?=null, // 0-$ffff
val fpReg2: Int?=null, // 0-$ffff
val value: Int?=null, // 0-$ffff
@ -302,17 +301,13 @@ data class Instruction(
throw IllegalArgumentException("missing type")
val format = formats.getValue(type)
if(format.reg1 && reg1==null ||
format.reg2 && reg2==null ||
format.reg3 && reg3==null)
if(format.reg1 && reg1==null || format.reg2 && reg2==null)
throw IllegalArgumentException("missing a register (int)")
if(format.fpReg1 && fpReg1==null || format.fpReg2 && fpReg2==null)
throw IllegalArgumentException("missing a register (float)")
if(!format.reg1 && reg1!=null ||
!format.reg2 && reg2!=null ||
!format.reg3 && reg3!=null)
if(!format.reg1 && reg1!=null || !format.reg2 && reg2!=null)
throw IllegalArgumentException("too many registers (int)")
if(!format.fpReg1 && fpReg1!=null || !format.fpReg2 && fpReg2!=null)
@ -346,10 +341,6 @@ data class Instruction(
result.add("r$it")
result.add(",")
}
reg3?.let {
result.add("r$it")
result.add(",")
}
fpReg1?.let {
result.add("fr$it")
result.add(",")
@ -376,7 +367,7 @@ data class Instruction(
}
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 value: Boolean,
val fpValue: Boolean) {
@ -386,7 +377,6 @@ data class InstructionFormat(val datatype: VmDataType?,
for(part in spec.split('|').map{ it.trim() }) {
var reg1 = false
var reg2 = false
var reg3 = false
var fpreg1 = false
var fpreg2 = false
var value = false
@ -397,7 +387,6 @@ data class InstructionFormat(val datatype: VmDataType?,
when(splits.next()) {
"r1" -> reg1=true
"r2" -> reg2=true
"r3" -> reg3=true
"fr1" -> fpreg1=true
"fr2" -> fpreg2=true
"v" -> value = true
@ -406,13 +395,13 @@ data class InstructionFormat(val datatype: VmDataType?,
}
}
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)
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)
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)
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
}
@ -456,38 +445,38 @@ val instructionFormats = mutableMapOf(
Opcode.BLES 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.SEQ to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.SNE to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.SLT to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.SLTS to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.SGT to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.SGTS to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.SLE to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.SLES to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.SGE to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.SGES to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.SEQ to InstructionFormat.from("BW,r1,r2"),
Opcode.SNE to InstructionFormat.from("BW,r1,r2"),
Opcode.SLT to InstructionFormat.from("BW,r1,r2"),
Opcode.SLTS to InstructionFormat.from("BW,r1,r2"),
Opcode.SGT to InstructionFormat.from("BW,r1,r2"),
Opcode.SGTS to InstructionFormat.from("BW,r1,r2"),
Opcode.SLE to InstructionFormat.from("BW,r1,r2"),
Opcode.SLES to InstructionFormat.from("BW,r1,r2"),
Opcode.SGE to InstructionFormat.from("BW,r1,r2"),
Opcode.SGES to InstructionFormat.from("BW,r1,r2"),
Opcode.INC to InstructionFormat.from("BW,r1"),
Opcode.INCM to InstructionFormat.from("BW,v"),
Opcode.DEC to InstructionFormat.from("BW,r1"),
Opcode.DECM to InstructionFormat.from("BW,v"),
Opcode.NEG to InstructionFormat.from("BW,r1 | F,fr1"),
Opcode.ADD to InstructionFormat.from("BW,r1,r2,r3 | F,fr1,fr2"),
Opcode.SUB to InstructionFormat.from("BW,r1,r2,r3 | F,fr1,fr2"),
Opcode.MUL to InstructionFormat.from("BW,r1,r2,r3 | F,fr1,fr2"),
Opcode.DIV to InstructionFormat.from("BW,r1,r2,r3 | 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.RND to InstructionFormat.from("BW,r1 | F,fr1"),
Opcode.MOD to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.NEG to InstructionFormat.from("BW,r1 | F,fr1"),
Opcode.ADD to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
Opcode.SUB to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
Opcode.MUL to InstructionFormat.from("BW,r1,r2 | 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.SGN to InstructionFormat.from("BW,r1,r2 | F,fr1,fr2"),
Opcode.RND to InstructionFormat.from("BW,r1 | F,fr1"),
Opcode.MOD to InstructionFormat.from("BW,r1,r2"),
Opcode.CMP to InstructionFormat.from("BW,r1,r2"),
Opcode.EXT to InstructionFormat.from("BW,r1"),
Opcode.EXTS to InstructionFormat.from("BW,r1"),
Opcode.AND to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.OR to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.XOR to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.ASRN to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.LSRN to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.LSLN to InstructionFormat.from("BW,r1,r2,r3"),
Opcode.AND to InstructionFormat.from("BW,r1,r2"),
Opcode.OR to InstructionFormat.from("BW,r1,r2"),
Opcode.XOR to InstructionFormat.from("BW,r1,r2"),
Opcode.ASRN to InstructionFormat.from("BW,r1,r2"),
Opcode.LSRN to InstructionFormat.from("BW,r1,r2"),
Opcode.LSLN to InstructionFormat.from("BW,r1,r2"),
Opcode.ASR to InstructionFormat.from("BW,r1"),
Opcode.LSR 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.PUSH 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.SEC to InstructionFormat.from("N"),
Opcode.BREAKPOINT to InstructionFormat.from("N"),

View File

@ -527,73 +527,73 @@ class VirtualMachine(val memory: Memory, program: List<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
setResultReg(resultReg, value, i.type!!)
setResultReg(i.reg1!!, value, i.type!!)
pc++
}
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
setResultReg(resultReg, value, i.type!!)
setResultReg(i.reg1!!, value, i.type!!)
pc++
}
private fun InsSLT(i: Instruction) {
val (resultReg, left, right) = getSetOnConditionOperandsU(i)
val (left, right) = getSetOnConditionOperandsU(i)
val value = if(left<right) 1 else 0
setResultReg(resultReg, value, i.type!!)
setResultReg(i.reg1!!, value, i.type!!)
pc++
}
private fun InsSLTS(i: Instruction) {
val (resultReg, left, right) = getSetOnConditionOperands(i)
val (left, right) = getSetOnConditionOperands(i)
val value = if(left<right) 1 else 0
setResultReg(resultReg, value, i.type!!)
setResultReg(i.reg1!!, value, i.type!!)
pc++
}
private fun InsSGT(i: Instruction) {
val (resultReg, left, right) = getSetOnConditionOperandsU(i)
val (left, right) = getSetOnConditionOperandsU(i)
val value = if(left>right) 1 else 0
setResultReg(resultReg, value, i.type!!)
setResultReg(i.reg1!!, value, i.type!!)
pc++
}
private fun InsSGTS(i: Instruction) {
val (resultReg, left, right) = getSetOnConditionOperands(i)
val (left, right) = getSetOnConditionOperands(i)
val value = if(left>right) 1 else 0
setResultReg(resultReg, value, i.type!!)
setResultReg(i.reg1!!, value, i.type!!)
pc++
}
private fun InsSLE(i: Instruction) {
val (resultReg, left, right) = getSetOnConditionOperandsU(i)
val (left, right) = getSetOnConditionOperandsU(i)
val value = if(left<=right) 1 else 0
setResultReg(resultReg, value, i.type!!)
setResultReg(i.reg1!!, value, i.type!!)
pc++
}
private fun InsSLES(i: Instruction) {
val (resultReg, left, right) = getSetOnConditionOperands(i)
val (left, right) = getSetOnConditionOperands(i)
val value = if(left<=right) 1 else 0
setResultReg(resultReg, value, i.type!!)
setResultReg(i.reg1!!, value, i.type!!)
pc++
}
private fun InsSGE(i: Instruction) {
val (resultReg, left, right) = getSetOnConditionOperandsU(i)
val (left, right) = getSetOnConditionOperandsU(i)
val value = if(left>=right) 1 else 0
setResultReg(resultReg, value, i.type!!)
setResultReg(i.reg1!!, value, i.type!!)
pc++
}
private fun InsSGES(i: Instruction) {
val (resultReg, left, right) = getSetOnConditionOperands(i)
val (left, right) = getSetOnConditionOperands(i)
val value = if(left>=right) 1 else 0
setResultReg(resultReg, value, i.type!!)
setResultReg(i.reg1!!, value, i.type!!)
pc++
}
@ -645,8 +645,8 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
private fun InsADD(i: Instruction) {
when(i.type!!) {
VmDataType.BYTE -> arithByte("+", i.reg1!!, i.reg2!!, i.reg3!!)
VmDataType.WORD -> arithWord("+", i.reg1!!, i.reg2!!, i.reg3!!)
VmDataType.BYTE -> arithByte("+", i.reg1!!, i.reg2!!)
VmDataType.WORD -> arithWord("+", i.reg1!!, i.reg2!!)
VmDataType.FLOAT -> arithFloat("+", i.fpReg1!!, i.fpReg2!!)
}
pc++
@ -654,16 +654,16 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
private fun InsSUB(i: Instruction) {
when(i.type!!) {
VmDataType.BYTE -> arithByte("-", i.reg1!!, i.reg2!!, i.reg3!!)
VmDataType.WORD -> arithWord("-", i.reg1!!, i.reg2!!, i.reg3!!)
VmDataType.BYTE -> arithByte("-", i.reg1!!, i.reg2!!)
VmDataType.WORD -> arithWord("-", i.reg1!!, i.reg2!!)
VmDataType.FLOAT -> arithFloat("-", i.fpReg1!!, i.fpReg2!!)
}
pc++
}
private fun InsMUL(i: Instruction) {
when(i.type!!) {
VmDataType.BYTE -> arithByte("*", i.reg1!!, i.reg2!!, i.reg3!!)
VmDataType.WORD -> arithWord("*", i.reg1!!, i.reg2!!, i.reg3!!)
VmDataType.BYTE -> arithByte("*", i.reg1!!, i.reg2!!)
VmDataType.WORD -> arithWord("*", i.reg1!!, i.reg2!!)
VmDataType.FLOAT -> arithFloat("*", i.fpReg1!!, i.fpReg2!!)
}
pc++
@ -671,8 +671,8 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
private fun InsDIV(i: Instruction) {
when(i.type!!) {
VmDataType.BYTE -> arithByte("/", i.reg1!!, i.reg2!!, i.reg3!!)
VmDataType.WORD -> arithWord("/", i.reg1!!, i.reg2!!, i.reg3!!)
VmDataType.BYTE -> arithByte("/", i.reg1!!, i.reg2!!)
VmDataType.WORD -> arithWord("/", i.reg1!!, i.reg2!!)
VmDataType.FLOAT -> arithFloat("/", i.fpReg1!!, i.fpReg2!!)
}
pc++
@ -680,8 +680,8 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
private fun InsMOD(i: Instruction) {
when(i.type!!) {
VmDataType.BYTE -> arithByte("%", i.reg1!!, i.reg2!!, i.reg3!!)
VmDataType.WORD -> arithWord("%", i.reg1!!, i.reg2!!, i.reg3!!)
VmDataType.BYTE -> arithByte("%", i.reg1!!, i.reg2!!)
VmDataType.WORD -> arithWord("%", i.reg1!!, i.reg2!!)
VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
}
pc++
@ -744,9 +744,9 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++
}
private fun arithByte(operator: String, reg1: Int, reg2: Int, reg3: Int) {
val left = registers.getUB(reg2)
val right = registers.getUB(reg3)
private fun arithByte(operator: String, reg1: Int, reg2: Int) {
val left = registers.getUB(reg1)
val right = registers.getUB(reg2)
val result = when(operator) {
"+" -> left + right
"-" -> left - right
@ -764,9 +764,9 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
registers.setUB(reg1, result.toUByte())
}
private fun arithWord(operator: String, reg1: Int, reg2: Int, reg3: Int) {
val left = registers.getUW(reg2)
val right = registers.getUW(reg3)
private fun arithWord(operator: String, reg1: Int, reg2: Int) {
val left = registers.getUW(reg1)
val right = registers.getUW(reg2)
val result = when(operator) {
"+" -> left + right
"-" -> left - right
@ -1019,9 +1019,9 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
private fun InsCONCAT(i: Instruction) {
when(i.type!!) {
VmDataType.BYTE -> {
val lsb = registers.getUB(i.reg1!!)
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.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> {
return when(i.type) {
VmDataType.BYTE -> Pair(registers.getUB(i.reg2!!).toUInt(), registers.getUB(i.reg3!!).toUInt())
VmDataType.WORD -> Pair(registers.getUW(i.reg2!!).toUInt(), registers.getUW(i.reg3!!).toUInt())
VmDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), registers.getUB(i.reg2!!).toUInt())
VmDataType.WORD -> Pair(registers.getUW(i.reg1!!).toUInt(), registers.getUW(i.reg2!!).toUInt())
VmDataType.FLOAT -> {
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> {
return when(i.type) {
VmDataType.BYTE -> Pair(registers.getSB(i.reg2!!).toInt(), registers.getSB(i.reg3!!).toInt())
VmDataType.WORD -> Pair(registers.getSW(i.reg2!!).toInt(), registers.getSW(i.reg3!!).toInt())
VmDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt())
VmDataType.WORD -> Pair(registers.getSW(i.reg1!!).toInt(), registers.getSW(i.reg2!!).toInt())
VmDataType.FLOAT -> {
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) {
VmDataType.BYTE -> Triple(ins.reg1!!, registers.getSB(ins.reg2!!).toInt(), registers.getSB(ins.reg3!!).toInt())
VmDataType.WORD -> Triple(ins.reg1!!, registers.getSW(ins.reg2!!).toInt(), registers.getSW(ins.reg3!!).toInt())
VmDataType.BYTE -> Pair(registers.getSB(ins.reg1!!).toInt(), registers.getSB(ins.reg2!!).toInt())
VmDataType.WORD -> Pair(registers.getSW(ins.reg1!!).toInt(), registers.getSW(ins.reg2!!).toInt())
VmDataType.FLOAT -> {
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) {
VmDataType.BYTE -> Triple(ins.reg1!!, registers.getUB(ins.reg2!!).toUInt(), registers.getUB(ins.reg3!!).toUInt())
VmDataType.WORD -> Triple(ins.reg1!!, registers.getUW(ins.reg2!!).toUInt(), registers.getUW(ins.reg3!!).toUInt())
VmDataType.BYTE -> Pair(registers.getUB(ins.reg1!!).toUInt(), registers.getUB(ins.reg2!!).toUInt())
VmDataType.WORD -> Pair(registers.getUW(ins.reg1!!).toUInt(), registers.getUW(ins.reg2!!).toUInt())
VmDataType.FLOAT -> {
throw IllegalArgumentException("can't use float here")
}

View File

@ -16,7 +16,6 @@ class TestInstructions: FunSpec({
ins.type shouldBe null
ins.reg1 shouldBe null
ins.reg2 shouldBe null
ins.reg3 shouldBe null
ins.value shouldBe null
ins.symbol shouldBe null
ins.toString() shouldBe "nop"
@ -28,7 +27,6 @@ class TestInstructions: FunSpec({
ins.type shouldBe VmDataType.BYTE
ins.reg1 shouldBe 42
ins.reg2 shouldBe null
ins.reg3 shouldBe null
ins.value shouldBe 9999
ins.symbol shouldBe null
ins.toString() shouldBe "bz.b r42,9999"
@ -40,7 +38,6 @@ class TestInstructions: FunSpec({
ins.type shouldBe VmDataType.WORD
ins.reg1 shouldBe 11
ins.reg2 shouldBe null
ins.reg3 shouldBe null
ins.value shouldBe null
ins.symbol shouldBe listOf("a","b","c")
ins.toString() shouldBe "bz.w r11,_a.b.c"