mirror of
https://github.com/irmen/prog8.git
synced 2025-02-18 05:30:34 +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 {
|
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()
|
val code = VmCodeChunk()
|
||||||
code += VmCodeComment("SUB: ${sub.scopedName} -> ${sub.returntype}")
|
code += VmCodeComment("SUB: ${sub.scopedName} -> ${sub.returntype}")
|
||||||
code += VmCodeLabel(sub.scopedName)
|
code += VmCodeLabel(sub.scopedName)
|
||||||
|
@ -3,7 +3,6 @@ TODO
|
|||||||
|
|
||||||
For next release
|
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.
|
All have type b or w.
|
||||||
|
|
||||||
and reg1, reg2 - reg1 = reg1 bitwise and reg2
|
and reg1, reg2 - reg1 = reg1 bitwise and reg2
|
||||||
andm reg1 address - memory = memory bitwise and reg1
|
|
||||||
or reg1, reg2 - reg1 = reg1 bitwise or reg2
|
or reg1, reg2 - reg1 = reg1 bitwise or reg2
|
||||||
orm reg1, address - memory = memory bitwise or reg1
|
|
||||||
xor reg1, reg2 - reg1 = reg1 bitwise xor reg2
|
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)
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
roxl reg1 - rotate reg1 left by 1 bits, using carry, + set Carry to shifted bit
|
||||||
|
andm reg1 address - memory = memory bitwise and reg1
|
||||||
TODO: add memory-rotate instructions?
|
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
|
FLOATING POINT CONVERSIONS AND FUNCTIONS
|
||||||
@ -269,9 +271,13 @@ enum class Opcode {
|
|||||||
LSL,
|
LSL,
|
||||||
LSLM,
|
LSLM,
|
||||||
ROR,
|
ROR,
|
||||||
|
RORM,
|
||||||
ROXR,
|
ROXR,
|
||||||
|
ROXRM,
|
||||||
ROL,
|
ROL,
|
||||||
|
ROLM,
|
||||||
ROXL,
|
ROXL,
|
||||||
|
ROXLM,
|
||||||
|
|
||||||
FFROMUB,
|
FFROMUB,
|
||||||
FFROMSB,
|
FFROMSB,
|
||||||
@ -328,7 +334,11 @@ val OpcodesWithAddress = setOf(
|
|||||||
Opcode.LSLM,
|
Opcode.LSLM,
|
||||||
Opcode.LSLNM,
|
Opcode.LSLNM,
|
||||||
Opcode.LSRNM,
|
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.LSL to InstructionFormat.from("BW,r1"),
|
||||||
Opcode.LSLM to InstructionFormat.from("BW,v"),
|
Opcode.LSLM to InstructionFormat.from("BW,v"),
|
||||||
Opcode.ROR to InstructionFormat.from("BW,r1"),
|
Opcode.ROR to InstructionFormat.from("BW,r1"),
|
||||||
|
Opcode.RORM to InstructionFormat.from("BW,v"),
|
||||||
Opcode.ROXR to InstructionFormat.from("BW,r1"),
|
Opcode.ROXR to InstructionFormat.from("BW,r1"),
|
||||||
|
Opcode.ROXRM to InstructionFormat.from("BW,v"),
|
||||||
Opcode.ROL to InstructionFormat.from("BW,r1"),
|
Opcode.ROL to InstructionFormat.from("BW,r1"),
|
||||||
|
Opcode.ROLM to InstructionFormat.from("BW,v"),
|
||||||
Opcode.ROXL to InstructionFormat.from("BW,r1"),
|
Opcode.ROXL to InstructionFormat.from("BW,r1"),
|
||||||
|
Opcode.ROXLM to InstructionFormat.from("BW,v"),
|
||||||
|
|
||||||
Opcode.FFROMUB to InstructionFormat.from("F,fr1,r1"),
|
Opcode.FFROMUB to InstructionFormat.from("F,fr1,r1"),
|
||||||
Opcode.FFROMSB 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.LSRM -> InsLSRM(ins)
|
||||||
Opcode.LSLM -> InsLSLM(ins)
|
Opcode.LSLM -> InsLSLM(ins)
|
||||||
Opcode.ROR -> InsROR(ins, false)
|
Opcode.ROR -> InsROR(ins, false)
|
||||||
|
Opcode.RORM -> InsRORM(ins, false)
|
||||||
Opcode.ROXR -> InsROR(ins, true)
|
Opcode.ROXR -> InsROR(ins, true)
|
||||||
|
Opcode.ROXRM -> InsRORM(ins, true)
|
||||||
Opcode.ROL -> InsROL(ins, false)
|
Opcode.ROL -> InsROL(ins, false)
|
||||||
|
Opcode.ROLM -> InsROLM(ins, false)
|
||||||
Opcode.ROXL -> InsROL(ins, true)
|
Opcode.ROXL -> InsROL(ins, true)
|
||||||
|
Opcode.ROXLM -> InsROLM(ins, true)
|
||||||
Opcode.MSIG -> InsMSIG(ins)
|
Opcode.MSIG -> InsMSIG(ins)
|
||||||
Opcode.CONCAT -> InsCONCAT(ins)
|
Opcode.CONCAT -> InsCONCAT(ins)
|
||||||
Opcode.PUSH -> InsPUSH(ins)
|
Opcode.PUSH -> InsPUSH(ins)
|
||||||
@ -1399,6 +1403,38 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
statusCarry = newStatusCarry
|
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) {
|
private fun InsROL(i: Instruction, useCarry: Boolean) {
|
||||||
val newStatusCarry: Boolean
|
val newStatusCarry: Boolean
|
||||||
when (i.type!!) {
|
when (i.type!!) {
|
||||||
@ -1430,6 +1466,38 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
statusCarry = newStatusCarry
|
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) {
|
private fun InsMSIG(i: Instruction) {
|
||||||
when(i.type!!) {
|
when(i.type!!) {
|
||||||
VmDataType.BYTE -> {
|
VmDataType.BYTE -> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user