mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
vm: implemented in-place bit rotate instructions
This commit is contained in:
parent
b646f50265
commit
e09f054058
@ -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)
|
||||
|
@ -3,7 +3,6 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- vm: implement the 4 rol/ror memory in-place instructions
|
||||
...
|
||||
|
||||
|
||||
|
@ -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"),
|
||||
|
@ -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 -> {
|
||||
|
Loading…
Reference in New Issue
Block a user