vm: implemented in-place bit rotate instructions

This commit is contained in:
Irmen de Jong 2022-05-23 20:26:44 +02:00
parent b646f50265
commit e09f054058
4 changed files with 95 additions and 15 deletions

View File

@ -772,7 +772,6 @@ class CodeGen(internal val program: PtProgram,
}
private fun translate(sub: PtSub): VmCodeChunk {
// TODO actually inline subroutines marked as inline (but at this time only asmsub can be inline)
val code = VmCodeChunk()
code += VmCodeComment("SUB: ${sub.scopedName} -> ${sub.returntype}")
code += VmCodeLabel(sub.scopedName)

View File

@ -3,7 +3,6 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- vm: implement the 4 rol/ror memory in-place instructions
...

View File

@ -120,31 +120,33 @@ LOGICAL/BITWISE
All have type b or w.
and reg1, reg2 - reg1 = reg1 bitwise and reg2
andm reg1 address - memory = memory bitwise and reg1
or reg1, reg2 - reg1 = reg1 bitwise or reg2
orm reg1, address - memory = memory bitwise or reg1
xor reg1, reg2 - reg1 = reg1 bitwise xor reg2
xorm reg1, address - memory = memory bitwise xor reg1
not reg1 - reg1 = boolean not of reg1 (0->1 , ~0 -> 0)
notm address - memory = boolean not of that memory (0->1 , ~0 -> 0)
lsrn reg1, reg2 - reg1 = multi-shift reg1 right by reg2 bits + set Carry to shifted bit
lsrnm reg1, address - multi-shift memoryright by reg1 bits + set Carry to shifted bit
asrn reg1, reg2 - reg1 = multi-shift reg1 right by reg2 bits (signed) + set Carry to shifted bit
asrnm reg1, address - multi-shift memory right by reg1 bits (signed) + set Carry to shifted bit
lsln reg1, reg2 - reg1 = multi-shift reg1 left by reg2 bits + set Carry to shifted bit
lslnm reg1, address - multi-shift memory left by reg1 bits + set Carry to shifted bit
lsr reg1 - shift reg1 right by 1 bits + set Carry to shifted bit
lsrm address - shift memory right by 1 bits + set Carry to shifted bit
asr reg1 - shift reg1 right by 1 bits (signed) + set Carry to shifted bit
asrm address - shift memory right by 1 bits (signed) + set Carry to shifted bit
lsl reg1 - shift reg1 left by 1 bits + set Carry to shifted bit
lslm address - shift memory left by 1 bits + set Carry to shifted bit
ror reg1 - rotate reg1 right by 1 bits, not using carry + set Carry to shifted bit
roxr reg1 - rotate reg1 right by 1 bits, using carry + set Carry to shifted bit
rol reg1 - rotate reg1 left by 1 bits, not using carry + set Carry to shifted bit
roxl reg1 - rotate reg1 left by 1 bits, using carry, + set Carry to shifted bit
TODO: add memory-rotate instructions?
andm reg1 address - memory = memory bitwise and reg1
orm reg1, address - memory = memory bitwise or reg1
xorm reg1, address - memory = memory bitwise xor reg1
notm address - memory = boolean not of that memory (0->1 , ~0 -> 0)
lsrnm reg1, address - multi-shift memoryright by reg1 bits + set Carry to shifted bit
asrnm reg1, address - multi-shift memory right by reg1 bits (signed) + set Carry to shifted bit
lslnm reg1, address - multi-shift memory left by reg1 bits + set Carry to shifted bit
lsrm address - shift memory right by 1 bits + set Carry to shifted bit
asrm address - shift memory right by 1 bits (signed) + set Carry to shifted bit
lslm address - shift memory left by 1 bits + set Carry to shifted bit
rorm address - rotate memory right by 1 bits, not using carry + set Carry to shifted bit
roxrm address - rotate memory right by 1 bits, using carry + set Carry to shifted bit
rolm address - rotate memory left by 1 bits, not using carry + set Carry to shifted bit
roxlm address - rotate memory left by 1 bits, using carry, + set Carry to shifted bit
FLOATING POINT CONVERSIONS AND FUNCTIONS
@ -269,9 +271,13 @@ enum class Opcode {
LSL,
LSLM,
ROR,
RORM,
ROXR,
ROXRM,
ROL,
ROLM,
ROXL,
ROXLM,
FFROMUB,
FFROMSB,
@ -328,7 +334,11 @@ val OpcodesWithAddress = setOf(
Opcode.LSLM,
Opcode.LSLNM,
Opcode.LSRNM,
Opcode.ASRNM
Opcode.ASRNM,
Opcode.ROLM,
Opcode.RORM,
Opcode.ROXLM,
Opcode.ROXRM
)
@ -554,9 +564,13 @@ val instructionFormats = mutableMapOf(
Opcode.LSL to InstructionFormat.from("BW,r1"),
Opcode.LSLM to InstructionFormat.from("BW,v"),
Opcode.ROR to InstructionFormat.from("BW,r1"),
Opcode.RORM to InstructionFormat.from("BW,v"),
Opcode.ROXR to InstructionFormat.from("BW,r1"),
Opcode.ROXRM to InstructionFormat.from("BW,v"),
Opcode.ROL to InstructionFormat.from("BW,r1"),
Opcode.ROLM to InstructionFormat.from("BW,v"),
Opcode.ROXL to InstructionFormat.from("BW,r1"),
Opcode.ROXLM to InstructionFormat.from("BW,v"),
Opcode.FFROMUB to InstructionFormat.from("F,fr1,r1"),
Opcode.FFROMSB to InstructionFormat.from("F,fr1,r1"),

View File

@ -175,9 +175,13 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
Opcode.LSRM -> InsLSRM(ins)
Opcode.LSLM -> InsLSLM(ins)
Opcode.ROR -> InsROR(ins, false)
Opcode.RORM -> InsRORM(ins, false)
Opcode.ROXR -> InsROR(ins, true)
Opcode.ROXRM -> InsRORM(ins, true)
Opcode.ROL -> InsROL(ins, false)
Opcode.ROLM -> InsROLM(ins, false)
Opcode.ROXL -> InsROL(ins, true)
Opcode.ROXLM -> InsROLM(ins, true)
Opcode.MSIG -> InsMSIG(ins)
Opcode.CONCAT -> InsCONCAT(ins)
Opcode.PUSH -> InsPUSH(ins)
@ -1399,6 +1403,38 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
statusCarry = newStatusCarry
}
private fun InsRORM(i: Instruction, useCarry: Boolean) {
val newStatusCarry: Boolean
val address = i.value!!
when (i.type!!) {
VmDataType.BYTE -> {
val orig = memory.getUB(address)
newStatusCarry = (orig.toInt() and 1) != 0
val rotated: UByte = if (useCarry) {
val carry = if (statusCarry) 0x80u else 0x00u
(orig.toUInt().rotateRight(1) or carry).toUByte()
} else
orig.rotateRight(1)
memory.setUB(address, rotated)
}
VmDataType.WORD -> {
val orig = memory.getUW(address)
newStatusCarry = (orig.toInt() and 1) != 0
val rotated: UShort = if (useCarry) {
val carry = if (statusCarry) 0x8000u else 0x0000u
(orig.toUInt().rotateRight(1) or carry).toUShort()
} else
orig.rotateRight(1)
memory.setUW(address, rotated)
}
VmDataType.FLOAT -> {
throw IllegalArgumentException("can't ROR a float")
}
}
pc++
statusCarry = newStatusCarry
}
private fun InsROL(i: Instruction, useCarry: Boolean) {
val newStatusCarry: Boolean
when (i.type!!) {
@ -1430,6 +1466,38 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
statusCarry = newStatusCarry
}
private fun InsROLM(i: Instruction, useCarry: Boolean) {
val address = i.value!!
val newStatusCarry: Boolean
when (i.type!!) {
VmDataType.BYTE -> {
val orig = memory.getUB(address)
newStatusCarry = (orig.toInt() and 0x80) != 0
val rotated: UByte = if (useCarry) {
val carry = if (statusCarry) 1u else 0u
(orig.toUInt().rotateLeft(1) or carry).toUByte()
} else
orig.rotateLeft(1)
memory.setUB(address, rotated)
}
VmDataType.WORD -> {
val orig = memory.getUW(address)
newStatusCarry = (orig.toInt() and 0x8000) != 0
val rotated: UShort = if (useCarry) {
val carry = if (statusCarry) 1u else 0u
(orig.toUInt().rotateLeft(1) or carry).toUShort()
} else
orig.rotateLeft(1)
memory.setUW(address, rotated)
}
VmDataType.FLOAT -> {
throw IllegalArgumentException("can't ROL a float")
}
}
pc++
statusCarry = newStatusCarry
}
private fun InsMSIG(i: Instruction) {
when(i.type!!) {
VmDataType.BYTE -> {