private void LoadRegisterImmediate(ulong opcode, Width width, BitExtension extension, string log)
        {
            this.Log(LogLevel.Noisy, "({0}) at PC={1:X}", log, PC.RawValue);
            // rD = Sext/Zext(Mem8/16/32(rs1))
            // rs1 += Imm[11:0]
            // It seems that Imm should be extended, but the docs do not confirm it explicitly
            var imm      = (int)BitHelper.SignExtend((uint)BitHelper.GetValue(opcode, 20, 12), 12);
            var rD       = (int)BitHelper.GetValue(opcode, 7, 5);
            var rs1      = (int)BitHelper.GetValue(opcode, 15, 5);
            var rs1Value = (long)GetRegisterUnsafe(rs1).RawValue;

            SetRegisterUnsafe(rD, GetMemValue(width, extension, (ulong)rs1Value));
            SetRegisterUnsafe(rs1, (ulong)(rs1Value + imm));
        }
        private void LoadRegisterRegister(ulong opcode, Width width, BitExtension extension, string log, bool postIncrement = false)
        {
            this.Log(LogLevel.Noisy, "({0}) at PC={1:X}", log, PC.RawValue);
            // with post-increment:
            // rD = Sext/Zext(Mem8/16/32(rs1))
            // rs1 += rs2
            // without post-increment:
            // rD = Sext/Zext(Mem8/16/32(rs1 + rs2))
            var rD       = (int)BitHelper.GetValue(opcode, 7, 5);
            var rs1      = (int)BitHelper.GetValue(opcode, 15, 5);
            var rs1Value = GetRegisterUnsafe(rs1).RawValue;
            var rs2      = (int)BitHelper.GetValue(opcode, 20, 5);
            var rs2Value = GetRegisterUnsafe(rs2).RawValue;

            SetRegisterUnsafe(rD, GetMemValue(width, extension, postIncrement ? rs1Value : rs1Value + rs2Value));
            if (postIncrement)
            {
                SetRegisterUnsafe(rs1, rs1Value + rs2Value);
            }
        }
        private ulong GetMemValue(Width width, BitExtension extension, ulong address)
        {
            var mem = 0UL;

            switch (width)
            {
            case Width.Byte:
                mem = extension == BitExtension.Sign ? BitHelper.SignExtend(ReadByteFromBus(address), 8) : ReadByteFromBus(address);
                break;

            case Width.HalfWord:
                mem = extension == BitExtension.Sign ? BitHelper.SignExtend(ReadWordFromBus(address), 16) : ReadWordFromBus(address);
                break;

            case Width.Word:
                mem = ReadDoubleWordFromBus(address);
                break;

            default:
                this.Log(LogLevel.Error, "Encountered an unexpected option: {0}", width);
                break;
            }
            return(mem);
        }