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); }