(lotsofbug)

This commit is contained in:
2026-06-26 17:09:26 +08:00
parent faa8458e2c
commit e8ee6ff091
20 changed files with 454 additions and 393 deletions

View File

@@ -26,12 +26,12 @@
"Xwt": "1.0.0",
"Xwt.Gtk3": "1.0.0",
"libtftp": "1.0.0",
"AntShell.Reference": "1.0.9672.29300",
"AntShell.Reference": "1.0.9673.25382",
"BigGustave.Reference": "1.0.0.0",
"CookComputing.XmlRpcV2": "2.5.0.0",
"CoSimulationPlugin.Reference": "1.0.0.0",
"crypto.Reference": "1.9.0.0",
"CxxDemangler.Reference": "1.0.9672.29287",
"CxxDemangler.Reference": "1.0.9673.25375",
"ELFSharp.Reference": "0.1.1.0",
"FdtSharp.Reference": "0.1.0.0",
"Infrastructure.Reference": "1.0.0.0",
@@ -1954,10 +1954,10 @@
}
}
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"runtime": {
"AntShell.dll": {
"assemblyVersion": "1.0.9672.29300",
"assemblyVersion": "1.0.9673.25382",
"fileVersion": "0.0.0.0"
}
}
@@ -1994,10 +1994,10 @@
}
}
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"runtime": {
"CxxDemangler.dll": {
"assemblyVersion": "1.0.9672.29287",
"assemblyVersion": "1.0.9673.25375",
"fileVersion": "0.0.0.0"
}
}
@@ -3134,7 +3134,7 @@
"serviceable": false,
"sha512": ""
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"type": "reference",
"serviceable": false,
"sha512": ""
@@ -3159,7 +3159,7 @@
"serviceable": false,
"sha512": ""
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"type": "reference",
"serviceable": false,
"sha512": ""

View File

@@ -1,7 +1,7 @@
// MIPS32简单测试平台
// MIPS64简单测试平台
cpu: CPU.Mips @ sysbus
cpuType: "mipsel"
cpuType: "mips64"
mem: Memory.MappedMemory @ {
sysbus 0x00000000;

View File

@@ -15,65 +15,43 @@ using Endianess = ELFSharp.ELF.Endianess;
namespace Antmicro.Renode.Peripherals.CPU
{
/// <summary>
/// MIPS32 CPU implementation for Renode
/// 基于龙芯1E300架构的MIPS32处理器
/// </summary>
public partial class Mips : TranslationCPU
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="cpuType">CPU类型字符串例如 "mips"</param>
/// <param name="machine">所属的机器实例</param>
/// <param name="endianness">字节序(默认小端序)</param>
public Mips(string cpuType, IMachine machine, Endianess endianness = Endianess.LittleEndian)
: base(cpuType, machine, endianness)
: base(cpuType, machine, endianness,
cpuType != null && cpuType.IndexOf("64", StringComparison.OrdinalIgnoreCase) >= 0
? CpuBitness.Bits64
: CpuBitness.Bits32)
{
// 初始化
isMips64 = cpuType != null && cpuType.IndexOf("64", StringComparison.OrdinalIgnoreCase) >= 0;
}
/// <summary>
/// CPU架构名称
/// </summary>
public override string Architecture
{
get { return "mips"; }
}
/// <summary>
/// GDB调试器识别的架构名称
/// </summary>
public override string GDBArchitecture
{
get { return "mips"; }
get { return isMips64 ? "mips:isa64" : "mips"; }
}
/// <summary>
/// GDB特性描述符列表目前为空
/// </summary>
public override List<GDBFeatureDescriptor> GDBFeatures
{
get { return new List<GDBFeatureDescriptor>(); }
}
/// <summary>
/// 解码中断号到中断类型
/// </summary>
protected override Interrupt DecodeInterrupt(int number)
{
switch(number)
{
case 0:
return Interrupt.Hard; // 硬件中断
return Interrupt.Hard;
default:
throw InvalidInterruptNumberException;
}
}
/// <summary>
/// 获取异常描述信息
/// </summary>
protected override string GetExceptionDescription(ulong exceptionIndex)
{
return ExceptionDescriptionsMap.TryGetValue(exceptionIndex, out var result)
@@ -81,27 +59,26 @@ namespace Antmicro.Renode.Peripherals.CPU
: base.GetExceptionDescription(exceptionIndex);
}
/// <summary>
/// MIPS异常描述映射表
/// </summary>
private readonly bool isMips64;
private readonly Dictionary<ulong, string> ExceptionDescriptionsMap = new Dictionary<ulong, string>
{
{0x00, "Interrupt"}, // 中断
{0x01, "TLB modification exception"}, // TLB修改异常
{0x02, "TLB exception (load/fetch)"}, // TLB异常加载/取指)
{0x03, "TLB exception (store)"}, // TLB异常存储
{0x04, "Address error (load/fetch)"}, // 地址错误(加载/取指)
{0x05, "Address error (store)"}, // 地址错误(存储)
{0x06, "Bus error (instruction fetch)"}, // 总线错误(取指)
{0x07, "Bus error (data load/store)"}, // 总线错误(数据访问)
{0x08, "Syscall"}, // 系统调用
{0x09, "Breakpoint"}, // 断点
{0x0A, "Reserved instruction"}, // 保留指令
{0x0B, "Coprocessor unusable"}, // 协处理器不可用
{0x0C, "Arithmetic overflow"}, // 算术溢出
{0x0D, "Trap"}, // 陷阱
{0x0F, "Floating point exception"}, // 浮点异常
{0x17, "Watch"}, // 监视点
{0x00, "Interrupt"},
{0x01, "TLB modification exception"},
{0x02, "TLB exception (load/fetch)"},
{0x03, "TLB exception (store)"},
{0x04, "Address error (load/fetch)"},
{0x05, "Address error (store)"},
{0x06, "Bus error (instruction fetch)"},
{0x07, "Bus error (data load/store)"},
{0x08, "Syscall"},
{0x09, "Breakpoint"},
{0x0A, "Reserved instruction"},
{0x0B, "Coprocessor unusable"},
{0x0C, "Arithmetic overflow"},
{0x0D, "Trap"},
{0x0F, "Floating point exception"},
{0x17, "Watch"},
};
}
}

View File

@@ -16,239 +16,149 @@ namespace Antmicro.Renode.Peripherals.CPU
{
public partial class Mips
{
/// <summary>
/// 设置寄存器值
/// </summary>
public override void SetRegister(int register, RegisterValue value)
{
if(!mapping.TryGetValue((MipsRegisters)register, out var r))
if(!Mapping.TryGetValue((MipsRegisters)register, out var r))
{
throw new RecoverableException($"Wrong register index: {register}");
}
if(r.Width == 64)
{
SetRegisterValue64(r.Index, checked((ulong)value));
}
else
{
SetRegisterValue32(r.Index, checked((uint)value));
}
}
/// <summary>
/// 获取寄存器值
/// </summary>
public override RegisterValue GetRegister(int register)
{
if(!mapping.TryGetValue((MipsRegisters)register, out var r))
if(!Mapping.TryGetValue((MipsRegisters)register, out var r))
{
throw new RecoverableException($"Wrong register index: {register}");
}
return GetRegisterValue32(r.Index);
return r.Width == 64 ? GetRegisterValue64(r.Index) : GetRegisterValue32(r.Index);
}
/// <summary>
/// 获取所有寄存器
/// </summary>
public override IEnumerable<CPURegister> GetRegisters()
{
return mapping.Values.OrderBy(x => x.Index);
return Mapping.Values.OrderBy(x => x.Index);
}
/// <summary>
/// PC - 程序计数器
/// </summary>
[Register]
public override RegisterValue PC
{
get
{
return GetRegisterValue32((int)MipsRegisters.PC);
}
set
{
SetRegisterValue32((int)MipsRegisters.PC, value);
}
get { return GetRegister((int)MipsRegisters.PC); }
set { SetRegister((int)MipsRegisters.PC, value); }
}
/// <summary>
/// Status - CP0状态寄存器 (GDB通信必须)
/// </summary>
[Register]
public RegisterValue Status
{
get { return GetRegisterValue32((int)MipsRegisters.Status); }
set { SetRegisterValue32((int)MipsRegisters.Status, value); }
get { return GetRegister((int)MipsRegisters.Status); }
set { SetRegister((int)MipsRegisters.Status, value); }
}
/// <summary>
/// LO - 乘除法结果低32位
/// </summary>
[Register]
public RegisterValue LO
{
get
{
return GetRegisterValue32((int)MipsRegisters.LO);
}
set
{
SetRegisterValue32((int)MipsRegisters.LO, value);
}
get { return GetRegister((int)MipsRegisters.LO); }
set { SetRegister((int)MipsRegisters.LO, value); }
}
/// <summary>
/// HI - 乘除法结果高32位
/// </summary>
[Register]
public RegisterValue HI
{
get
{
return GetRegisterValue32((int)MipsRegisters.HI);
}
set
{
SetRegisterValue32((int)MipsRegisters.HI, value);
}
get { return GetRegister((int)MipsRegisters.HI); }
set { SetRegister((int)MipsRegisters.HI, value); }
}
/// <summary>
/// BadVAddr - CP0错误地址 (GDB通信必须)
/// </summary>
[Register]
public RegisterValue BadVAddr
{
get { return GetRegisterValue32((int)MipsRegisters.BadVAddr); }
set { SetRegisterValue32((int)MipsRegisters.BadVAddr, value); }
get { return GetRegister((int)MipsRegisters.BadVAddr); }
set { SetRegister((int)MipsRegisters.BadVAddr, value); }
}
/// <summary>
/// Cause - CP0异常原因 (GDB通信必须)
/// </summary>
[Register]
public RegisterValue Cause
{
get { return GetRegisterValue32((int)MipsRegisters.Cause); }
set { SetRegisterValue32((int)MipsRegisters.Cause, value); }
get { return GetRegister((int)MipsRegisters.Cause); }
set { SetRegister((int)MipsRegisters.Cause, value); }
}
/// <summary>
/// SP - 栈指针 ($29)
/// </summary>
[Register]
public RegisterValue SP
{
get
{
return GetRegisterValue32((int)MipsRegisters.SP);
}
set
{
SetRegisterValue32((int)MipsRegisters.SP, value);
}
get { return GetRegister((int)MipsRegisters.SP); }
set { SetRegister((int)MipsRegisters.SP, value); }
}
/// <summary>
/// RA - 返回地址 ($31)
/// </summary>
[Register]
public RegisterValue RA
{
get
{
return GetRegisterValue32((int)MipsRegisters.RA);
}
set
{
SetRegisterValue32((int)MipsRegisters.RA, value);
}
get { return GetRegister((int)MipsRegisters.RA); }
set { SetRegister((int)MipsRegisters.RA, value); }
}
/// <summary>
/// GP - 全局指针 ($28)
/// </summary>
[Register]
public RegisterValue GP
{
get
{
return GetRegisterValue32((int)MipsRegisters.GP);
}
set
{
SetRegisterValue32((int)MipsRegisters.GP, value);
}
get { return GetRegister((int)MipsRegisters.GP); }
set { SetRegister((int)MipsRegisters.GP, value); }
}
/// <summary>
/// V0 - 函数返回值 ($2)
/// </summary>
[Register]
public RegisterValue V0
{
get { return GetRegisterValue32((int)MipsRegisters.V0); }
set { SetRegisterValue32((int)MipsRegisters.V0, value); }
get { return GetRegister((int)MipsRegisters.V0); }
set { SetRegister((int)MipsRegisters.V0, value); }
}
/// <summary>
/// V1 - 函数返回值 ($3)
/// </summary>
[Register]
public RegisterValue V1
{
get { return GetRegisterValue32((int)MipsRegisters.V1); }
set { SetRegisterValue32((int)MipsRegisters.V1, value); }
get { return GetRegister((int)MipsRegisters.V1); }
set { SetRegister((int)MipsRegisters.V1, value); }
}
/// <summary>
/// A0 - 函数参数 ($4)
/// </summary>
[Register]
public RegisterValue A0
{
get { return GetRegisterValue32((int)MipsRegisters.A0); }
set { SetRegisterValue32((int)MipsRegisters.A0, value); }
get { return GetRegister((int)MipsRegisters.A0); }
set { SetRegister((int)MipsRegisters.A0, value); }
}
/// <summary>
/// A1 - 函数参数 ($5)
/// </summary>
[Register]
public RegisterValue A1
{
get { return GetRegisterValue32((int)MipsRegisters.A1); }
set { SetRegisterValue32((int)MipsRegisters.A1, value); }
get { return GetRegister((int)MipsRegisters.A1); }
set { SetRegister((int)MipsRegisters.A1, value); }
}
/// <summary>
/// A2 - 函数参数 ($6)
/// </summary>
[Register]
public RegisterValue A2
{
get { return GetRegisterValue32((int)MipsRegisters.A2); }
set { SetRegisterValue32((int)MipsRegisters.A2, value); }
get { return GetRegister((int)MipsRegisters.A2); }
set { SetRegister((int)MipsRegisters.A2, value); }
}
/// <summary>
/// A3 - 函数参数 ($7)
/// </summary>
[Register]
public RegisterValue A3
{
get { return GetRegisterValue32((int)MipsRegisters.A3); }
set { SetRegisterValue32((int)MipsRegisters.A3, value); }
get { return GetRegister((int)MipsRegisters.A3); }
set { SetRegister((int)MipsRegisters.A3, value); }
}
/// <summary>
/// 通用寄存器组 (GPR[0-31])
/// 注意此属性主要用于C#代码访问Renode Monitor中请使用寄存器别名如 V0, A0, T0 等)
/// </summary>
public RegistersGroup GPR { get; private set; }
/// <summary>
/// 初始化寄存器
/// </summary>
protected override void InitializeRegisters()
{
// 创建32个通用寄存器的映射
var indexValueMapGPR = new Dictionary<int, MipsRegisters>();
for (int i = 0; i < 32; i++)
for(var i = 0; i < 32; i++)
{
indexValueMapGPR[i] = (MipsRegisters)i;
}
@@ -260,112 +170,115 @@ namespace Antmicro.Renode.Peripherals.CPU
}
#pragma warning disable 649
// 649: Field '...' is never assigned to, and will always have its default value null
[Import(Name = "tlib_set_register_value_32")]
protected Action<int, uint> SetRegisterValue32;
[Import(Name = "tlib_get_register_value_32")]
protected Func<int, uint> GetRegisterValue32;
[Import(Name = "tlib_set_register_value_64")]
protected Action<int, ulong> SetRegisterValue64;
[Import(Name = "tlib_get_register_value_64")]
protected Func<int, ulong> GetRegisterValue64;
#pragma warning restore 649
/// <summary>
/// MIPS32寄存器到CPURegister的映射
/// </summary>
private static readonly Dictionary<MipsRegisters, CPURegister> mapping = new Dictionary<MipsRegisters, CPURegister>
{
// 32个通用寄存器 (GPR[0-31])
{ MipsRegisters.ZERO, new CPURegister(0, 32, isGeneral: true, isReadonly: true, aliases: new [] { "ZERO", "R0", "$0" }) },
{ MipsRegisters.AT, new CPURegister(1, 32, isGeneral: true, isReadonly: false, aliases: new [] { "AT", "R1", "$1" }) },
{ MipsRegisters.V0, new CPURegister(2, 32, isGeneral: true, isReadonly: false, aliases: new [] { "V0", "R2", "$2" }) },
{ MipsRegisters.V1, new CPURegister(3, 32, isGeneral: true, isReadonly: false, aliases: new [] { "V1", "R3", "$3" }) },
{ MipsRegisters.A0, new CPURegister(4, 32, isGeneral: true, isReadonly: false, aliases: new [] { "A0", "R4", "$4" }) },
{ MipsRegisters.A1, new CPURegister(5, 32, isGeneral: true, isReadonly: false, aliases: new [] { "A1", "R5", "$5" }) },
{ MipsRegisters.A2, new CPURegister(6, 32, isGeneral: true, isReadonly: false, aliases: new [] { "A2", "R6", "$6" }) },
{ MipsRegisters.A3, new CPURegister(7, 32, isGeneral: true, isReadonly: false, aliases: new [] { "A3", "R7", "$7" }) },
{ MipsRegisters.T0, new CPURegister(8, 32, isGeneral: true, isReadonly: false, aliases: new [] { "T0", "R8", "$8" }) },
{ MipsRegisters.T1, new CPURegister(9, 32, isGeneral: true, isReadonly: false, aliases: new [] { "T1", "R9", "$9" }) },
{ MipsRegisters.T2, new CPURegister(10, 32, isGeneral: true, isReadonly: false, aliases: new [] { "T2", "R10", "$10" }) },
{ MipsRegisters.T3, new CPURegister(11, 32, isGeneral: true, isReadonly: false, aliases: new [] { "T3", "R11", "$11" }) },
{ MipsRegisters.T4, new CPURegister(12, 32, isGeneral: true, isReadonly: false, aliases: new [] { "T4", "R12", "$12" }) },
{ MipsRegisters.T5, new CPURegister(13, 32, isGeneral: true, isReadonly: false, aliases: new [] { "T5", "R13", "$13" }) },
{ MipsRegisters.T6, new CPURegister(14, 32, isGeneral: true, isReadonly: false, aliases: new [] { "T6", "R14", "$14" }) },
{ MipsRegisters.T7, new CPURegister(15, 32, isGeneral: true, isReadonly: false, aliases: new [] { "T7", "R15", "$15" }) },
{ MipsRegisters.S0, new CPURegister(16, 32, isGeneral: true, isReadonly: false, aliases: new [] { "S0", "R16", "$16" }) },
{ MipsRegisters.S1, new CPURegister(17, 32, isGeneral: true, isReadonly: false, aliases: new [] { "S1", "R17", "$17" }) },
{ MipsRegisters.S2, new CPURegister(18, 32, isGeneral: true, isReadonly: false, aliases: new [] { "S2", "R18", "$18" }) },
{ MipsRegisters.S3, new CPURegister(19, 32, isGeneral: true, isReadonly: false, aliases: new [] { "S3", "R19", "$19" }) },
{ MipsRegisters.S4, new CPURegister(20, 32, isGeneral: true, isReadonly: false, aliases: new [] { "S4", "R20", "$20" }) },
{ MipsRegisters.S5, new CPURegister(21, 32, isGeneral: true, isReadonly: false, aliases: new [] { "S5", "R21", "$21" }) },
{ MipsRegisters.S6, new CPURegister(22, 32, isGeneral: true, isReadonly: false, aliases: new [] { "S6", "R22", "$22" }) },
{ MipsRegisters.S7, new CPURegister(23, 32, isGeneral: true, isReadonly: false, aliases: new [] { "S7", "R23", "$23" }) },
{ MipsRegisters.T8, new CPURegister(24, 32, isGeneral: true, isReadonly: false, aliases: new [] { "T8", "R24", "$24" }) },
{ MipsRegisters.T9, new CPURegister(25, 32, isGeneral: true, isReadonly: false, aliases: new [] { "T9", "R25", "$25" }) },
{ MipsRegisters.K0, new CPURegister(26, 32, isGeneral: true, isReadonly: false, aliases: new [] { "K0", "R26", "$26" }) },
{ MipsRegisters.K1, new CPURegister(27, 32, isGeneral: true, isReadonly: false, aliases: new [] { "K1", "R27", "$27" }) },
{ MipsRegisters.GP, new CPURegister(28, 32, isGeneral: true, isReadonly: false, aliases: new [] { "GP", "R28", "$28" }) },
{ MipsRegisters.SP, new CPURegister(29, 32, isGeneral: true, isReadonly: false, aliases: new [] { "SP", "R29", "$29" }) },
{ MipsRegisters.FP, new CPURegister(30, 32, isGeneral: true, isReadonly: false, aliases: new [] { "FP", "S8", "R30", "$30" }) },
{ MipsRegisters.RA, new CPURegister(31, 32, isGeneral: true, isReadonly: false, aliases: new [] { "RA", "R31", "$31" }) },
private Dictionary<MipsRegisters, CPURegister> Mapping => isMips64 ? mapping64 : mapping32;
// =====================================
// 特殊寄存器 (严格遵循GDB的 32-37 坑位)
// =====================================
{ MipsRegisters.Status, new CPURegister(32, 32, isGeneral: false, isReadonly: false, aliases: new [] { "Status", "SR" }) },
{ MipsRegisters.LO, new CPURegister(33, 32, isGeneral: false, isReadonly: false, aliases: new [] { "LO" }) },
{ MipsRegisters.HI, new CPURegister(34, 32, isGeneral: false, isReadonly: false, aliases: new [] { "HI" }) },
{ MipsRegisters.BadVAddr, new CPURegister(35, 32, isGeneral: false, isReadonly: true, aliases: new [] { "BadVAddr" }) },
{ MipsRegisters.Cause, new CPURegister(36, 32, isGeneral: false, isReadonly: false, aliases: new [] { "Cause" }) },
{ MipsRegisters.PC, new CPURegister(37, 32, isGeneral: false, isReadonly: false, aliases: new [] { "PC" }) },
private static CPURegister R(int index, int width, bool isGeneral, bool isReadonly, params string[] aliases)
{
return new CPURegister(index, width, isGeneral: isGeneral, isReadonly: isReadonly, aliases: aliases);
}
private static Dictionary<MipsRegisters, CPURegister> CreateMapping(int width)
{
return new Dictionary<MipsRegisters, CPURegister>
{
{ MipsRegisters.ZERO, R(0, width, true, true, "ZERO", "R0", "$0") },
{ MipsRegisters.AT, R(1, width, true, false, "AT", "R1", "$1") },
{ MipsRegisters.V0, R(2, width, true, false, "V0", "R2", "$2") },
{ MipsRegisters.V1, R(3, width, true, false, "V1", "R3", "$3") },
{ MipsRegisters.A0, R(4, width, true, false, "A0", "R4", "$4") },
{ MipsRegisters.A1, R(5, width, true, false, "A1", "R5", "$5") },
{ MipsRegisters.A2, R(6, width, true, false, "A2", "R6", "$6") },
{ MipsRegisters.A3, R(7, width, true, false, "A3", "R7", "$7") },
{ MipsRegisters.T0, R(8, width, true, false, "T0", "R8", "$8") },
{ MipsRegisters.T1, R(9, width, true, false, "T1", "R9", "$9") },
{ MipsRegisters.T2, R(10, width, true, false, "T2", "R10", "$10") },
{ MipsRegisters.T3, R(11, width, true, false, "T3", "R11", "$11") },
{ MipsRegisters.T4, R(12, width, true, false, "T4", "R12", "$12") },
{ MipsRegisters.T5, R(13, width, true, false, "T5", "R13", "$13") },
{ MipsRegisters.T6, R(14, width, true, false, "T6", "R14", "$14") },
{ MipsRegisters.T7, R(15, width, true, false, "T7", "R15", "$15") },
{ MipsRegisters.S0, R(16, width, true, false, "S0", "R16", "$16") },
{ MipsRegisters.S1, R(17, width, true, false, "S1", "R17", "$17") },
{ MipsRegisters.S2, R(18, width, true, false, "S2", "R18", "$18") },
{ MipsRegisters.S3, R(19, width, true, false, "S3", "R19", "$19") },
{ MipsRegisters.S4, R(20, width, true, false, "S4", "R20", "$20") },
{ MipsRegisters.S5, R(21, width, true, false, "S5", "R21", "$21") },
{ MipsRegisters.S6, R(22, width, true, false, "S6", "R22", "$22") },
{ MipsRegisters.S7, R(23, width, true, false, "S7", "R23", "$23") },
{ MipsRegisters.T8, R(24, width, true, false, "T8", "R24", "$24") },
{ MipsRegisters.T9, R(25, width, true, false, "T9", "R25", "$25") },
{ MipsRegisters.K0, R(26, width, true, false, "K0", "R26", "$26") },
{ MipsRegisters.K1, R(27, width, true, false, "K1", "R27", "$27") },
{ MipsRegisters.GP, R(28, width, true, false, "GP", "R28", "$28") },
{ MipsRegisters.SP, R(29, width, true, false, "SP", "R29", "$29") },
{ MipsRegisters.FP, R(30, width, true, false, "FP", "S8", "R30", "$30") },
{ MipsRegisters.RA, R(31, width, true, false, "RA", "R31", "$31") },
{ MipsRegisters.Status, R(32, width, false, false, "Status", "SR") },
{ MipsRegisters.LO, R(33, width, false, false, "LO") },
{ MipsRegisters.HI, R(34, width, false, false, "HI") },
{ MipsRegisters.BadVAddr, R(35, width, false, true, "BadVAddr") },
{ MipsRegisters.Cause, R(36, width, false, false, "Cause") },
{ MipsRegisters.PC, R(37, width, false, false, "PC") },
};
}
/// <summary>
/// MIPS32寄存器枚举
/// </summary>
private static readonly Dictionary<MipsRegisters, CPURegister> mapping32 = CreateMapping(32);
private static readonly Dictionary<MipsRegisters, CPURegister> mapping64 = CreateMapping(64);
}
public enum MipsRegisters
{
// 32个通用寄存器 (GPR[0-31])
ZERO = 0, // $0 - 常量0
AT = 1, // $1 - 汇编器临时寄存器
V0 = 2, // $2 - 函数返回值
V1 = 3, // $3 - 函数返回值
A0 = 4, // $4 - 函数参数
A1 = 5, // $5 - 函数参数
A2 = 6, // $6 - 函数参数
A3 = 7, // $7 - 函数参数
T0 = 8, // $8 - 临时寄存器
T1 = 9, // $9 - 临时寄存器
T2 = 10, // $10 - 临时寄存器
T3 = 11, // $11 - 临时寄存器
T4 = 12, // $12 - 临时寄存器
T5 = 13, // $13 - 临时寄存器
T6 = 14, // $14 - 临时寄存器
T7 = 15, // $15 - 临时寄存器
S0 = 16, // $16 - 保存寄存器
S1 = 17, // $17 - 保存寄存器
S2 = 18, // $18 - 保存寄存器
S3 = 19, // $19 - 保存寄存器
S4 = 20, // $20 - 保存寄存器
S5 = 21, // $21 - 保存寄存器
S6 = 22, // $22 - 保存寄存器
S7 = 23, // $23 - 保存寄存器
T8 = 24, // $24 - 临时寄存器
T9 = 25, // $25 - 临时寄存器
K0 = 26, // $26 - 内核保留
K1 = 27, // $27 - 内核保留
GP = 28, // $28 - 全局指针
SP = 29, // $29 - 栈指针
FP = 30, // $30 - 帧指针 (也称为 S8)
RA = 31, // $31 - 返回地址
ZERO = 0,
AT = 1,
V0 = 2,
V1 = 3,
A0 = 4,
A1 = 5,
A2 = 6,
A3 = 7,
T0 = 8,
T1 = 9,
T2 = 10,
T3 = 11,
T4 = 12,
T5 = 13,
T6 = 14,
T7 = 15,
S0 = 16,
S1 = 17,
S2 = 18,
S3 = 19,
S4 = 20,
S5 = 21,
S6 = 22,
S7 = 23,
T8 = 24,
T9 = 25,
K0 = 26,
K1 = 27,
GP = 28,
SP = 29,
FP = 30,
RA = 31,
Status = 32,
LO = 33,
HI = 34,
BadVAddr = 35,
Cause = 36,
PC = 37,
}
}
// =====================================
// 特殊寄存器 (严格遵循GDB的 32-37 坑位)
// =====================================
Status = 32, // CP0 状态寄存器
LO = 33, // 乘除法结果低32位
HI = 34, // 乘除法结果高32位
BadVAddr = 35, // CP0 内存错误地址
Cause = 36, // CP0 异常原因
PC = 37, // 程序计数器
}
}

View File

@@ -11,7 +11,7 @@ if(TCG_OPCODE_BACKTRACE)
message(FATAL_ERROR "Cannot use TCG_OPCODE_BACKTRACE without Debug configuration")
endif()
add_definitions(-DTCG_OPCODE_BACKTRACE=1)
add_definitions(-DTCG_OPCODE_BACKTRACE)
# Don't cache this variable, so the user can
# repeatedly toggle it on/off by providing/omitting it.
@@ -96,7 +96,6 @@ message(VERBOSE "Target is: ${TARGET_WORD_SIZE}-bit ${TARGET_ARCH}")
set_property (CACHE HOST_ARCH PROPERTY STRINGS i386 arm aarch64)
# [MIPS架构支持] 在目标架构列表中添加 mips 和 mips64用于支持龙芯1E300等MIPS处理器
set_property (CACHE TARGET_ARCH PROPERTY STRINGS i386 x86_64 arm arm-m arm64 sparc ppc ppc64 riscv riscv64 xtensa mips mips64)
# set_property (CACHE TARGET_ARCH PROPERTY STRINGS i386 x86_64 arm arm-m arm64 sparc ppc ppc64 riscv riscv64 xtensa)
if(NOT HOST_ARCH)
message (FATAL_ERROR "Host architecture not set")
@@ -126,6 +125,9 @@ elseif("${TARGET_ACTUAL_ARCH}" STREQUAL "riscv64")
set (TARGET_ACTUAL_ARCH "riscv")
elseif("${TARGET_ACTUAL_ARCH}" STREQUAL "x86_64")
set (TARGET_ACTUAL_ARCH "i386")
elseif("${TARGET_ACTUAL_ARCH}" STREQUAL "mips64")
set (TARGET_ACTUAL_ARCH "mips")
set (TARGET_WORD_SIZE "64")
endif()
# Let's make TARGET_ACTUAL_ARCH available in CMakes adding tlib subdirectory. Using PARENT_SCOPE
@@ -152,8 +154,13 @@ endif()
# 2. TARGET_MIPS宏: 启用MIPS特定的代码路径和功能
# 3. 这些定义会影响cpu.h中的类型定义和指令翻译行为
if("${TARGET_ACTUAL_ARCH}" STREQUAL "mips")
set(TARGET_LONG_BITS 32)
add_definitions(-DTARGET_MIPS)
if("${TARGET_WORD_SIZE}" STREQUAL "64")
add_definitions(-DTARGET_MIPS64)
else()
set(TARGET_WORD_SIZE "32")
add_definitions(-DTARGET_MIPS32)
endif()
endif()
string (TOUPPER "${HOST_ARCH}" HOST_ARCH_U)
@@ -243,6 +250,12 @@ file (GLOB SOURCES
${ARM_COMMON_SRC}
)
# MIPS 目录中可能保留人工备份文件 "translate copy.c"。GLOB 会把它
# 当作正常源文件编译,导致 translate.c 的公共入口符号重复定义。
if("${TARGET_ACTUAL_ARCH}" STREQUAL "mips")
list(FILTER SOURCES EXCLUDE REGEX ".*/arch/mips/translate copy\\.c$")
endif()
add_library (tlib SHARED ${SOURCES})
add_dependencies (tlib tcg)
set_property(TARGET tlib PROPERTY C_STANDARD 11)
@@ -289,3 +302,4 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CheckLinkerFlag.cmake")
target_link_options(tlib PUBLIC -Wl,-Bsymbolic)
endif()
endif()

View File

@@ -12,13 +12,17 @@
/* =========================================
1. 核心与静态检查 (IDE 防报错) 定义
========================================= */
#ifndef TARGET_LONG_BITS
#define TARGET_LONG_BITS 32
#ifndef TARGET_PHYS_ADDR_BITS
#define TARGET_PHYS_ADDR_BITS 32
#endif
#define TARGET_PHYS_ADDR_SPACE_BITS 32
#ifndef TARGET_PHYS_ADDR_BITS
#define TARGET_PHYS_ADDR_BITS TARGET_LONG_BITS
#endif
#ifndef TARGET_PHYS_ADDR_SPACE_BITS
#define TARGET_PHYS_ADDR_SPACE_BITS TARGET_PHYS_ADDR_BITS
#endif
#define TARGET_PAGE_BITS 12
#ifndef TARGET_INSN_START_EXTRA_WORDS
@@ -28,8 +32,12 @@
/* 终极兜底:防止 IntelliSense 报 target_ulong 未定义 */
#include <stdint.h>
#ifndef target_ulong
#if TARGET_LONG_BITS == 64
typedef uint64_t target_ulong;
#else
typedef uint32_t target_ulong;
#endif
#endif
#include "cpu-defs.h"
#include "cpu_registers.h"
@@ -76,6 +84,15 @@ typedef uint32_t target_ulong;
#define CP0_CAUSE_BD (1 << 31) // Branch Delay
#define NB_MMU_MODES 2
#define MIPS_TLB_MAX 32
typedef struct MIPSTLBEntry {
target_ulong mask;
target_ulong hi;
target_ulong lo0;
target_ulong lo1;
uint8_t valid;
} MIPSTLBEntry;
/* =========================================
4. CPU 状态结构体
@@ -89,6 +106,15 @@ typedef struct CPUState {
target_ulong HI;
target_ulong LO;
/*
* LL/SC 链接状态。
* LL 记录被监视的字地址和值SC 只有在地址和值仍然匹配时才真正写内存并返回 1。
* 当前 1E300 模型是单核简化实现,暂不建模外部总线写入导致的链接失效。
*/
target_ulong lladdr;
target_ulong llval;
uint32_t ll_active;
// CP0 - 协处理器0系统控制寄存器
target_ulong CP0_Index;
target_ulong CP0_Random;
@@ -108,6 +134,14 @@ typedef struct CPUState {
target_ulong CP0_Config0;
target_ulong CP0_Config1;
target_ulong CP0_EBase;
target_ulong CP0_UserLocal; /* CP0 r4 sel 2用户线程本地寄存器(ULR)RDHWR $29 读取 */
/*
* 简化版架构 TLB。这里保存 CP0 可见的 TLB 表项内容,用于实现
* TLBP/TLBR/TLBWI/TLBWR 指令语义。当前 MMU fault 路径仍是直接映射,
* 所以这张表主要服务系统软件探测/读写 TLB 指令,而不是完整地址转换。
*/
MIPSTLBEntry tlb[MIPS_TLB_MAX];
// 龙芯1E300特定寄存器预留空间
target_ulong loongson_custom[8];
@@ -121,7 +155,7 @@ typedef struct CPUState {
/* --- 核心补充:内部状态和标志 (与 translate.c 的 offsetof 强绑定) --- */
uint32_t hflags; // 内部CPU标志
int error_code;
uint32_t btarget; // 分支目标地址
target_ulong btarget; // 分支目标地址
uint32_t bcond; // 条件跳转判定结果 (1=跳, 0=不跳)
CPU_COMMON

View File

@@ -1,18 +1,15 @@
/*
* MIPS寄存器接口
* Author:liuwb
* Date:2026_0209
* MIPS register accessors used by the C# TranslationCPU binding.
*/
#include <stdint.h>
#include "cpu.h"
#include "cpu_registers.h"
// 获取寄存器指针32位版本
uint32_t *get_reg_pointer_32(int reg)
{
switch(reg) {
case MIPS_REG_ZERO ... MIPS_REG_RA: // GPR 0-31
case MIPS_REG_ZERO ... MIPS_REG_RA:
return (uint32_t *)&(cpu->gpr[reg]);
case MIPS_REG_PC:
return (uint32_t *)&(cpu->pc);
@@ -28,10 +25,94 @@ uint32_t *get_reg_pointer_32(int reg)
return (uint32_t *)&(cpu->CP0_EPC);
case MIPS_CP0_BADVADDR:
return (uint32_t *)&(cpu->CP0_BadVAddr);
case MIPS_CP0_INDEX:
return (uint32_t *)&(cpu->CP0_Index);
case MIPS_CP0_RANDOM:
return (uint32_t *)&(cpu->CP0_Random);
case MIPS_CP0_ENTRYLO0:
return (uint32_t *)&(cpu->CP0_EntryLo0);
case MIPS_CP0_ENTRYLO1:
return (uint32_t *)&(cpu->CP0_EntryLo1);
case MIPS_CP0_CONTEXT:
return (uint32_t *)&(cpu->CP0_Context);
case MIPS_CP0_PAGEMASK:
return (uint32_t *)&(cpu->CP0_PageMask);
case MIPS_CP0_WIRED:
return (uint32_t *)&(cpu->CP0_Wired);
case MIPS_CP0_COUNT:
return (uint32_t *)&(cpu->CP0_Count);
case MIPS_CP0_ENTRYHI:
return (uint32_t *)&(cpu->CP0_EntryHi);
case MIPS_CP0_COMPARE:
return (uint32_t *)&(cpu->CP0_Compare);
case MIPS_CP0_PRID:
return (uint32_t *)&(cpu->CP0_PRId);
case MIPS_CP0_CONFIG0:
return (uint32_t *)&(cpu->CP0_Config0);
case MIPS_CP0_CONFIG1:
return (uint32_t *)&(cpu->CP0_Config1);
case MIPS_CP0_EBASE:
return (uint32_t *)&(cpu->CP0_EBase);
case MIPS_FCR0:
return (uint32_t *)&(cpu->fcr0);
case MIPS_FCR31:
return (uint32_t *)&(cpu->fcr31);
default:
return NULL;
}
}
uint64_t *get_reg_pointer_64(int reg)
{
switch(reg) {
case MIPS_REG_ZERO ... MIPS_REG_RA:
return (uint64_t *)&(cpu->gpr[reg]);
case MIPS_REG_PC:
return (uint64_t *)&(cpu->pc);
case MIPS_REG_HI:
return (uint64_t *)&(cpu->HI);
case MIPS_REG_LO:
return (uint64_t *)&(cpu->LO);
case MIPS_CP0_STATUS:
return (uint64_t *)&(cpu->CP0_Status);
case MIPS_CP0_CAUSE:
return (uint64_t *)&(cpu->CP0_Cause);
case MIPS_CP0_EPC:
return (uint64_t *)&(cpu->CP0_EPC);
case MIPS_CP0_BADVADDR:
return (uint64_t *)&(cpu->CP0_BadVAddr);
case MIPS_CP0_INDEX:
return (uint64_t *)&(cpu->CP0_Index);
case MIPS_CP0_RANDOM:
return (uint64_t *)&(cpu->CP0_Random);
case MIPS_CP0_ENTRYLO0:
return (uint64_t *)&(cpu->CP0_EntryLo0);
case MIPS_CP0_ENTRYLO1:
return (uint64_t *)&(cpu->CP0_EntryLo1);
case MIPS_CP0_CONTEXT:
return (uint64_t *)&(cpu->CP0_Context);
case MIPS_CP0_PAGEMASK:
return (uint64_t *)&(cpu->CP0_PageMask);
case MIPS_CP0_WIRED:
return (uint64_t *)&(cpu->CP0_Wired);
case MIPS_CP0_COUNT:
return (uint64_t *)&(cpu->CP0_Count);
case MIPS_CP0_ENTRYHI:
return (uint64_t *)&(cpu->CP0_EntryHi);
case MIPS_CP0_COMPARE:
return (uint64_t *)&(cpu->CP0_Compare);
case MIPS_CP0_PRID:
return (uint64_t *)&(cpu->CP0_PRId);
case MIPS_CP0_CONFIG0:
return (uint64_t *)&(cpu->CP0_Config0);
case MIPS_CP0_CONFIG1:
return (uint64_t *)&(cpu->CP0_Config1);
case MIPS_CP0_EBASE:
return (uint64_t *)&(cpu->CP0_EBase);
default:
return NULL;
}
}
// 生成寄存器访问函数tlib_get_register_value_32 和 tlib_set_register_value_32
CPU_REGISTER_ACCESSOR(32)
CPU_REGISTER_ACCESSOR(64)

View File

@@ -99,12 +99,23 @@ int cpu_handle_mmu_fault(CPUState *env, target_ulong address, int access_type,
target_ulong vaddr, paddr_mapped;
int prot;
// 虚拟地址和物理地址(直接映射
// kseg0/kseg1 地址映射
// 0x80000000-0x9FFFFFFF (kseg0) -> 0x00000000-0x1FFFFFFF
// 0xA0000000-0xBFFFFFFF (kseg1) -> 0x00000000-0x1FFFFFFF
if ((address >= 0x80000000) && (address < 0xC0000000)) {
// 去掉高3位得到物理地址
paddr_mapped = address & 0x1FFFFFFF;
} else {
// 其他地址直接映射
paddr_mapped = address;
}
// 虚拟地址和物理地址
vaddr = address & TARGET_PAGE_MASK;
paddr_mapped = address & TARGET_PAGE_MASK;
paddr_mapped = paddr_mapped & TARGET_PAGE_MASK;
// 返回物理地址
*paddr = address;
*paddr = paddr_mapped;
// 权限:可读、可写、可执行
prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;

View File

@@ -362,7 +362,7 @@ static void disas_cop1(DisasContext *ctx, CPUState *env, uint32_t insn) {
break;
case 0x03: // MFHC1 - 读浮点寄存器高 32 位到主 CPU
fprintf(stderr, "[MFHC1] PC=%08x insn=%08x rs=%d rt=%d rd=%d\n", ctx->pc, insn, rs, rt, rd);
fprintf(stderr, "[MFHC1] PC=%08lx insn=%08x rs=%d rt=%d rd=%d\n", ctx->pc, insn, rs, rt, rd);
if (!is_zero_reg(rt)) {
TCGv t0 = tcg_temp_new();
TCGv_i32 t32 = tcg_temp_new_i32();
@@ -376,7 +376,7 @@ static void disas_cop1(DisasContext *ctx, CPUState *env, uint32_t insn) {
break;
case 0x07: // MTHC1 - 写主 CPU 值到浮点寄存器高 32 位
fprintf(stderr, "[MTHC1] PC=%08x insn=%08x rs=%d rt=%d rd=%d\n", ctx->pc, insn, rs, rt, rd);
fprintf(stderr, "[MTHC1] PC=%08lx insn=%08x rs=%d rt=%d rd=%d\n", ctx->pc, insn, rs, rt, rd);
{
TCGv t0 = load_gpr(rt);
TCGv_i64 t64 = tcg_temp_new_i64();
@@ -455,7 +455,7 @@ static void disas_cop1(DisasContext *ctx, CPUState *env, uint32_t insn) {
break;
default:
fprintf(stderr, "[COP1 DEFAULT] PC=%08x insn=%08x rs=%d rt=%d rd=%d\n", ctx->pc, insn, rs, rt, rd);
fprintf(stderr, "[COP1 DEFAULT] PC=%08lx insn=%08x rs=%d rt=%d rd=%d\n", ctx->pc, insn, rs, rt, rd);
generate_exception_end(ctx, EXCP_RI);
break;
}
@@ -473,6 +473,8 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
int32_t imm = IMM(insn);
uint32_t uimm = UIMM(insn);
fprintf(stderr, "[DISASM] PC=%08lx insn=%08x op=0x%02x rs=%d rt=%d\n", ctx->pc, insn, op, rs, rt);
switch (op) {
case 0x00: // SPECIAL (R-Type)
switch (funct) {
@@ -576,6 +578,20 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
}
break;
case 0x38: // DSLL (MIPS64)
fprintf(stderr, "[DSLL] PC=%08lx insn=%08x rt=%d rd=%d sa=%d\n", ctx->pc, insn, rt, rd, SA(insn));
if (!is_zero_reg(rd)) {
TCGv t0 = load_gpr(rt);
TCGv res = tcg_temp_new();
tcg_gen_shli_tl(res, t0, shamt);
store_gpr(rd, res);
tcg_temp_free(t0);
tcg_temp_free(res);
}
break;
case 0x04: // SLLV
case 0x06: // SRLV
case 0x07: // SRAV
@@ -799,7 +815,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
break;
case 0x11: // COP1
fprintf(stderr, "[COP1] PC=%08x insn=%08x rs=%d rt=%d rd=%d\n", ctx->pc, insn, rs, rt, rd);
fprintf(stderr, "[COP1] PC=%08lx insn=%08x rs=%d rt=%d rd=%d\n", ctx->pc, insn, rs, rt, rd);
if (!(ctx->hflags & MIPS_HFLAG_FPU)) {
// 门禁未开,操作系统拦截,触发浮点懒加载陷阱
generate_exception_end(ctx, EXCP_CpU);
@@ -831,7 +847,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
break;
case 0x35: // LDC1 (Load Doubleword to Coprocessor 1)
{
fprintf(stderr, "[LDC1] PC=%08x insn=%08x rs=%d rt=%d imm=%d\n", ctx->pc, insn, rs, rt, imm);
fprintf(stderr, "[LDC1] PC=%08lx insn=%08x rs=%d rt=%d imm=%d\n", ctx->pc, insn, rs, rt, imm);
TCGv t0 = load_gpr(rs);
TCGv addr = tcg_temp_local_new();
TCGv val_lo = tcg_temp_new();
@@ -843,11 +859,11 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
tcg_gen_addi_tl(addr, t0, SEXT16(imm));
// 加载低32位
tcg_gen_qemu_ld_tl(val_lo, addr, ctx->mem_idx, MO_TE | MO_UL);
tcg_gen_qemu_ld_op(val_lo, addr, ctx->mem_idx, MO_TE | MO_UL);
// 加载高32位地址+4
TCGv addr_plus4 = tcg_temp_new();
tcg_gen_addi_tl(addr_plus4, addr, 4);
tcg_gen_qemu_ld_tl(val_hi, addr_plus4, ctx->mem_idx, MO_TE | MO_UL);
tcg_gen_qemu_ld_op(val_hi, addr_plus4, ctx->mem_idx, MO_TE | MO_UL);
// 拼接成64位
tcg_gen_trunc_tl_i32(t32_lo, val_lo);
@@ -868,7 +884,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
case 0x3D: // SDC1 (Store Doubleword from Coprocessor 1)
{
fprintf(stderr, "[SDC1] PC=%08x insn=%08x rs=%d rt=%d imm=%d\n", ctx->pc, insn, rs, rt, imm);
fprintf(stderr, "[SDC1] PC=%08lx insn=%08x rs=%d rt=%d imm=%d\n", ctx->pc, insn, rs, rt, imm);
TCGv t0 = load_gpr(rs);
TCGv addr = tcg_temp_local_new();
TCGv val_lo = tcg_temp_new();
@@ -890,11 +906,11 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
tcg_gen_ext_i32_tl(val_hi, t32_hi);
// 存储低32位
tcg_gen_qemu_st_tl(val_lo, addr, ctx->mem_idx, MO_TE | MO_UL);
tcg_gen_qemu_st_op(val_lo, addr, ctx->mem_idx, MO_TE | MO_UL);
// 存储高32位地址+4
TCGv addr_plus4 = tcg_temp_new();
tcg_gen_addi_tl(addr_plus4, addr, 4);
tcg_gen_qemu_st_tl(val_hi, addr_plus4, ctx->mem_idx, MO_TE | MO_UL);
tcg_gen_qemu_st_op(val_hi, addr_plus4, ctx->mem_idx, MO_TE | MO_UL);
tcg_temp_free(t0);
tcg_temp_free(addr);
@@ -915,7 +931,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
TCGv_i64 t64 = tcg_temp_new_i64();
tcg_gen_addi_tl(addr, t0, SEXT16(imm));
tcg_gen_qemu_ld_tl(val, addr, ctx->mem_idx, MO_TE | MO_UL);
tcg_gen_qemu_ld_op(val, addr, ctx->mem_idx, MO_TE | MO_UL);
tcg_gen_ext_tl_i64(t64, val);
tcg_gen_mov_i64(fpu_gpr[rt], t64);
@@ -936,7 +952,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
tcg_gen_addi_tl(addr, t0, SEXT16(imm));
tcg_gen_extrl_i64_i32(t32, fpu_gpr[rt]);
tcg_gen_ext_i32_tl(val, t32);
tcg_gen_qemu_st_tl(val, addr, ctx->mem_idx, MO_TE | MO_UL);
tcg_gen_qemu_st_op(val, addr, ctx->mem_idx, MO_TE | MO_UL);
tcg_temp_free(t0);
tcg_temp_free(addr);
@@ -960,6 +976,20 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
}
break;
case 0x19: // DADDIU (MIPS64)
fprintf(stderr, "[DADDIU] PC=%08lx insn=%08x rs=%d rt=%d imm=%d\n", ctx->pc, insn, rs, rt, imm);
if (!is_zero_reg(rt)) {
TCGv t0 = load_gpr(rs);
TCGv res = tcg_temp_new();
tcg_gen_addi_tl(res, t0, SEXT16(imm));
store_gpr(rt, res);
tcg_temp_free(t0);
tcg_temp_free(res);
}
break;
case 0x0A: // SLTI
case 0x0B: // SLTIU
if (!is_zero_reg(rt)) {
@@ -1175,7 +1205,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
gen_set_label(l_align_ok);
TCGv res = tcg_temp_new();
tcg_gen_qemu_ld_tl(res, addr, ctx->mem_idx, MO_TE | MO_SL);
tcg_gen_qemu_ld_op(res, addr, ctx->mem_idx, MO_TE | MO_SL);
store_gpr(rt, res);
tcg_temp_free(t0);
@@ -1199,7 +1229,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
gen_set_label(l_align_ok);
TCGv t1 = load_gpr(rt);
tcg_gen_qemu_st_tl(t1, addr, ctx->mem_idx, MO_TE | MO_UL);
tcg_gen_qemu_st_op(t1, addr, ctx->mem_idx, MO_TE | MO_UL);
tcg_temp_free(t0);
tcg_temp_free(t1);
@@ -1223,7 +1253,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
gen_set_label(l_align_ok);
TCGv res = tcg_temp_new();
tcg_gen_qemu_ld_tl(res, addr, ctx->mem_idx, (op == 0x21) ? (MO_TE | MO_SW) : (MO_TE | MO_UW));
tcg_gen_qemu_ld_op(res, addr, ctx->mem_idx, (op == 0x21) ? (MO_TE | MO_SW) : (MO_TE | MO_UW));
store_gpr(rt, res);
tcg_temp_free(t0);
@@ -1247,7 +1277,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
gen_set_label(l_align_ok);
TCGv t1 = load_gpr(rt);
tcg_gen_qemu_st_tl(t1, addr, ctx->mem_idx, MO_TE | MO_UW);
tcg_gen_qemu_st_op(t1, addr, ctx->mem_idx, MO_TE | MO_UW);
tcg_temp_free(t0);
tcg_temp_free(t1);
@@ -1264,7 +1294,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
TCGv res = tcg_temp_new();
tcg_gen_addi_tl(addr, t0, SEXT16(imm));
tcg_gen_qemu_ld_tl(res, addr, ctx->mem_idx, (op == 0x20) ? (MO_TE | MO_SB) : (MO_TE | MO_UB));
tcg_gen_qemu_ld_op(res, addr, ctx->mem_idx, (op == 0x20) ? (MO_TE | MO_SB) : (MO_TE | MO_UB));
store_gpr(rt, res);
tcg_temp_free(t0);
@@ -1280,7 +1310,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
TCGv addr = tcg_temp_new();
tcg_gen_addi_tl(addr, t0, SEXT16(imm));
tcg_gen_qemu_st_tl(t1, addr, ctx->mem_idx, MO_TE | MO_UB);
tcg_gen_qemu_st_op(t1, addr, ctx->mem_idx, MO_TE | MO_UB);
tcg_temp_free(t0);
tcg_temp_free(t1);
@@ -1300,6 +1330,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
* 主控架构 (Main Architecture Loop)
* ======================================================================== */
void translate_init(void) {
fprintf(stderr, "=== MIPS64 TRANSLATE INIT === TARGET_LONG_BITS=%d ===\n", TARGET_LONG_BITS);
for (int i = 0; i < 32; i++) {
cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, gpr[i]), mips_gpr_names[i]);
}

View File

@@ -15,10 +15,10 @@
"System.ServiceModel.Duplex": "4.8.1",
"System.ServiceModel.Federation": "4.8.1",
"System.ServiceModel.NetTcp": "4.8.1",
"AntShell.Reference": "1.0.9672.29300",
"AntShell.Reference": "1.0.9673.25382",
"BigGustave.Reference": "1.0.0.0",
"crypto.Reference": "1.9.0.0",
"CxxDemangler.Reference": "1.0.9672.29287",
"CxxDemangler.Reference": "1.0.9673.25375",
"ELFSharp.Reference": "0.1.1.0",
"FdtSharp.Reference": "0.1.0.0",
"Infrastructure.Reference": "1.0.0.0",
@@ -1782,10 +1782,10 @@
}
}
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"runtime": {
"AntShell.dll": {
"assemblyVersion": "1.0.9672.29300",
"assemblyVersion": "1.0.9673.25382",
"fileVersion": "0.0.0.0"
}
}
@@ -1806,10 +1806,10 @@
}
}
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"runtime": {
"CxxDemangler.dll": {
"assemblyVersion": "1.0.9672.29287",
"assemblyVersion": "1.0.9673.25375",
"fileVersion": "0.0.0.0"
}
}
@@ -2841,7 +2841,7 @@
"serviceable": false,
"sha512": ""
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"type": "reference",
"serviceable": false,
"sha512": ""
@@ -2856,7 +2856,7 @@
"serviceable": false,
"sha512": ""
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"type": "reference",
"serviceable": false,
"sha512": ""

View File

@@ -14,10 +14,10 @@
"System.ServiceModel.Duplex": "4.8.1",
"System.ServiceModel.Federation": "4.8.1",
"System.ServiceModel.NetTcp": "4.8.1",
"AntShell.Reference": "1.0.9672.29300",
"AntShell.Reference": "1.0.9673.25382",
"BigGustave.Reference": "1.0.0.0",
"crypto.Reference": "1.9.0.0",
"CxxDemangler.Reference": "1.0.9672.29287",
"CxxDemangler.Reference": "1.0.9673.25375",
"ELFSharp.Reference": "0.1.1.0",
"FdtSharp.Reference": "0.1.0.0",
"Infrastructure.Reference": "1.0.0.0",
@@ -1781,10 +1781,10 @@
}
}
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"runtime": {
"AntShell.dll": {
"assemblyVersion": "1.0.9672.29300",
"assemblyVersion": "1.0.9673.25382",
"fileVersion": "0.0.0.0"
}
}
@@ -1805,10 +1805,10 @@
}
}
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"runtime": {
"CxxDemangler.dll": {
"assemblyVersion": "1.0.9672.29287",
"assemblyVersion": "1.0.9673.25375",
"fileVersion": "0.0.0.0"
}
}
@@ -2840,7 +2840,7 @@
"serviceable": false,
"sha512": ""
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"type": "reference",
"serviceable": false,
"sha512": ""
@@ -2855,7 +2855,7 @@
"serviceable": false,
"sha512": ""
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"type": "reference",
"serviceable": false,
"sha512": ""

View File

@@ -11,10 +11,10 @@
"AntShell": "1.0.0",
"Infrastructure": "1.0.0",
"StyleCop.Analyzers": "1.1.118",
"AntShell.Reference": "1.0.9672.29300",
"AntShell.Reference": "1.0.9673.25382",
"BigGustave.Reference": "1.0.0.0",
"crypto.Reference": "1.9.0.0",
"CxxDemangler.Reference": "1.0.9672.29287",
"CxxDemangler.Reference": "1.0.9673.25375",
"ELFSharp.Reference": "0.1.1.0",
"FdtSharp.Reference": "0.1.0.0",
"Infrastructure.Reference": "1.0.0.0",
@@ -1574,10 +1574,10 @@
}
}
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"runtime": {
"AntShell.dll": {
"assemblyVersion": "1.0.9672.29300",
"assemblyVersion": "1.0.9673.25382",
"fileVersion": "0.0.0.0"
}
}
@@ -1598,10 +1598,10 @@
}
}
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"runtime": {
"CxxDemangler.dll": {
"assemblyVersion": "1.0.9672.29287",
"assemblyVersion": "1.0.9673.25375",
"fileVersion": "0.0.0.0"
}
}
@@ -2507,7 +2507,7 @@
"serviceable": false,
"sha512": ""
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"type": "reference",
"serviceable": false,
"sha512": ""
@@ -2522,7 +2522,7 @@
"serviceable": false,
"sha512": ""
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"type": "reference",
"serviceable": false,
"sha512": ""

View File

@@ -26,12 +26,12 @@
"Xwt": "1.0.0",
"Xwt.Gtk3": "1.0.0",
"libtftp": "1.0.0",
"AntShell.Reference": "1.0.9672.29300",
"AntShell.Reference": "1.0.9673.25382",
"BigGustave.Reference": "1.0.0.0",
"CookComputing.XmlRpcV2": "2.5.0.0",
"CoSimulationPlugin.Reference": "1.0.0.0",
"crypto.Reference": "1.9.0.0",
"CxxDemangler.Reference": "1.0.9672.29287",
"CxxDemangler.Reference": "1.0.9673.25375",
"ELFSharp.Reference": "0.1.1.0",
"FdtSharp.Reference": "0.1.0.0",
"Infrastructure.Reference": "1.0.0.0",
@@ -1954,10 +1954,10 @@
}
}
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"runtime": {
"AntShell.dll": {
"assemblyVersion": "1.0.9672.29300",
"assemblyVersion": "1.0.9673.25382",
"fileVersion": "0.0.0.0"
}
}
@@ -1994,10 +1994,10 @@
}
}
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"runtime": {
"CxxDemangler.dll": {
"assemblyVersion": "1.0.9672.29287",
"assemblyVersion": "1.0.9673.25375",
"fileVersion": "0.0.0.0"
}
}
@@ -3134,7 +3134,7 @@
"serviceable": false,
"sha512": ""
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"type": "reference",
"serviceable": false,
"sha512": ""
@@ -3159,7 +3159,7 @@
"serviceable": false,
"sha512": ""
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"type": "reference",
"serviceable": false,
"sha512": ""

View File

@@ -16,11 +16,11 @@
"NUnit3TestAdapter": "3.17.0",
"Renode": "1.0.0",
"UnitTests": "1.0.0",
"AntShell.Reference": "1.0.9672.29300",
"AntShell.Reference": "1.0.9673.25382",
"BigGustave.Reference": "1.0.0.0",
"CoSimulationPlugin.Reference": "1.0.0.0",
"crypto.Reference": "1.9.0.0",
"CxxDemangler.Reference": "1.0.9672.29287",
"CxxDemangler.Reference": "1.0.9673.25375",
"ELFSharp.Reference": "0.1.1.0",
"FdtSharp.Reference": "0.1.0.0",
"Infrastructure.Reference": "1.0.0.0",
@@ -28,7 +28,7 @@
"Migrant.Reference": "0.14.0.0",
"OptionsParser.Reference": "0.1.0.0",
"PacketDotNet.Reference": "0.13.0.0",
"Renode.Reference": "1.16.0.29349",
"Renode.Reference": "1.16.0.25439",
"SampleCommandPlugin.Reference": "1.0.0.0",
"Sprache": "2.1.0.0",
"SystemCPlugin.Reference": "1.0.0.0",
@@ -2035,10 +2035,10 @@
}
}
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"runtime": {
"AntShell.dll": {
"assemblyVersion": "1.0.9672.29300",
"assemblyVersion": "1.0.9673.25382",
"fileVersion": "0.0.0.0"
}
}
@@ -2067,10 +2067,10 @@
}
}
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"runtime": {
"CxxDemangler.dll": {
"assemblyVersion": "1.0.9672.29287",
"assemblyVersion": "1.0.9673.25375",
"fileVersion": "0.0.0.0"
}
}
@@ -2131,10 +2131,10 @@
}
}
},
"Renode.Reference/1.16.0.29349": {
"Renode.Reference/1.16.0.25439": {
"runtime": {
"Renode.dll": {
"assemblyVersion": "1.16.0.29349",
"assemblyVersion": "1.16.0.25439",
"fileVersion": "0.0.0.0"
}
}
@@ -3255,7 +3255,7 @@
"serviceable": false,
"sha512": ""
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"type": "reference",
"serviceable": false,
"sha512": ""
@@ -3275,7 +3275,7 @@
"serviceable": false,
"sha512": ""
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"type": "reference",
"serviceable": false,
"sha512": ""
@@ -3315,7 +3315,7 @@
"serviceable": false,
"sha512": ""
},
"Renode.Reference/1.16.0.29349": {
"Renode.Reference/1.16.0.25439": {
"type": "reference",
"serviceable": false,
"sha512": ""

View File

@@ -18,11 +18,11 @@
"NUnit3TestAdapter": "3.17.0",
"Renode": "1.0.0",
"StyleCop.Analyzers": "1.1.118",
"AntShell.Reference": "1.0.9672.29300",
"AntShell.Reference": "1.0.9673.25382",
"BigGustave.Reference": "1.0.0.0",
"CoSimulationPlugin.Reference": "1.0.0.0",
"crypto.Reference": "1.9.0.0",
"CxxDemangler.Reference": "1.0.9672.29287",
"CxxDemangler.Reference": "1.0.9673.25375",
"ELFSharp.Reference": "0.1.1.0",
"FdtSharp.Reference": "0.1.0.0",
"Infrastructure.Reference": "1.0.0.0",
@@ -31,7 +31,7 @@
"Migrant.Reference": "0.14.0.0",
"OptionsParser.Reference": "0.1.0.0",
"PacketDotNet.Reference": "0.13.0.0",
"Renode.Reference": "1.16.0.29349",
"Renode.Reference": "1.16.0.25439",
"SampleCommandPlugin.Reference": "1.0.0.0",
"SystemCPlugin.Reference": "1.0.0.0",
"TermSharp.Reference": "0.0.0.0",
@@ -2018,10 +2018,10 @@
}
}
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"runtime": {
"AntShell.dll": {
"assemblyVersion": "1.0.9672.29300",
"assemblyVersion": "1.0.9673.25382",
"fileVersion": "0.0.0.0"
}
}
@@ -2050,10 +2050,10 @@
}
}
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"runtime": {
"CxxDemangler.dll": {
"assemblyVersion": "1.0.9672.29287",
"assemblyVersion": "1.0.9673.25375",
"fileVersion": "0.0.0.0"
}
}
@@ -2122,10 +2122,10 @@
}
}
},
"Renode.Reference/1.16.0.29349": {
"Renode.Reference/1.16.0.25439": {
"runtime": {
"Renode.dll": {
"assemblyVersion": "1.16.0.29349",
"assemblyVersion": "1.16.0.25439",
"fileVersion": "0.0.0.0"
}
}
@@ -3232,7 +3232,7 @@
"serviceable": false,
"sha512": ""
},
"AntShell.Reference/1.0.9672.29300": {
"AntShell.Reference/1.0.9673.25382": {
"type": "reference",
"serviceable": false,
"sha512": ""
@@ -3252,7 +3252,7 @@
"serviceable": false,
"sha512": ""
},
"CxxDemangler.Reference/1.0.9672.29287": {
"CxxDemangler.Reference/1.0.9673.25375": {
"type": "reference",
"serviceable": false,
"sha512": ""
@@ -3297,7 +3297,7 @@
"serviceable": false,
"sha512": ""
},
"Renode.Reference/1.16.0.29349": {
"Renode.Reference/1.16.0.25439": {
"type": "reference",
"serviceable": false,
"sha512": ""