yichu-trap-yichang
This commit is contained in:
@@ -8,10 +8,10 @@
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"OptionsParser/1.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.NET.Test.Sdk": "16.9.1",
|
||||
"NUnit": "3.13.1",
|
||||
"NUnit3TestAdapter": "3.17.0",
|
||||
"OptionsParser": "1.0.0"
|
||||
"NUnit3TestAdapter": "3.17.0"
|
||||
},
|
||||
"runtime": {
|
||||
"OptionsParser.dll": {}
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
"Xwt": "1.0.0",
|
||||
"Xwt.Gtk3": "1.0.0",
|
||||
"libtftp": "1.0.0",
|
||||
"AntShell.Reference": "1.0.9568.24184",
|
||||
"AntShell.Reference": "1.0.9571.20353",
|
||||
"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.9568.24177",
|
||||
"CxxDemangler.Reference": "1.0.9571.20346",
|
||||
"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.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"runtime": {
|
||||
"AntShell.dll": {
|
||||
"assemblyVersion": "1.0.9568.24184",
|
||||
"assemblyVersion": "1.0.9571.20353",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1994,10 +1994,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"runtime": {
|
||||
"CxxDemangler.dll": {
|
||||
"assemblyVersion": "1.0.9568.24177",
|
||||
"assemblyVersion": "1.0.9571.20346",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -3134,7 +3134,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"AntShell.Reference/1.0.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
@@ -3159,7 +3159,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
/*
|
||||
* MIPS32 指令翻译器 - 终极救赎版 (Ultimate Redemption Edition)
|
||||
* * 核心破局:彻底避开老版 TCG 的“全局内存变量 (Global Mem Temp)”陷阱!
|
||||
* * 解决逻辑:
|
||||
* 1. 绝不将 cpu_gpr 等全局变量直接传入 tcg_gen_add_tl 等复杂 ALU 宏。
|
||||
* 2. 引入严格的 Load/Store 屏障:所有的全局变量必须先 mov 复制到 local temp 中,
|
||||
* 计算完成后再 mov 回去。这彻底消灭了 TCG 后端隐式创建 unnamed 变量导致的 DEAD 崩溃。
|
||||
* 3. 完美迎回 MIPS 原生跳转与延迟槽架构!
|
||||
* MIPS32
|
||||
* * 新增特性:完整 MIPS CP0 异常系统。
|
||||
* * 修复日志:全面实现了 MIPS 架构完整的 12 条 Trap 陷阱指令(R-Type 与 立即数型)。
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
@@ -21,6 +17,26 @@
|
||||
#define DISAS_STOP 4
|
||||
#endif
|
||||
|
||||
// ========================================================================
|
||||
// MIPS 架构标准异常代号 (ExcCode)
|
||||
// ========================================================================
|
||||
#define EXCP_INT 0 // 中断 (Interrupt)
|
||||
#define EXCP_MOD 1 // TLB 修改异常 (TLB Mod)
|
||||
#define EXCP_TLBL 2 // TLB 异常 (加载/取指)
|
||||
#define EXCP_TLBS 3 // TLB 异常 (存储)
|
||||
#define EXCP_AdEL 4 // 地址错误 (加载/取指)
|
||||
#define EXCP_AdES 5 // 地址错误 (存储)
|
||||
#define EXCP_IBE 6 // 总线错误 (取指)
|
||||
#define EXCP_DBE 7 // 总线错误 (数据访问)
|
||||
#define EXCP_SYSCALL 8 // 系统调用 (Syscall)
|
||||
#define EXCP_BREAK 9 // 断点 (Breakpoint)
|
||||
#define EXCP_RI 10 // 保留指令 (Reserved Instruction)
|
||||
#define EXCP_CpU 11 // 协处理器不可用 (Coprocessor Unusable)
|
||||
#define EXCP_OVERFLOW 12 // 算术溢出 (Arithmetic Overflow)
|
||||
#define EXCP_TRAP 13 // 陷阱指令 (Trap)
|
||||
#define EXCP_FPE 15 // 浮点异常 (Floating Point)
|
||||
#define EXCP_WATCH 23 // 监视点 (Watchpoint)
|
||||
|
||||
#define OPCODE(insn) ((insn >> 26) & 0x3F)
|
||||
#define RS(insn) ((insn >> 21) & 0x1F)
|
||||
#define RT(insn) ((insn >> 16) & 0x1F)
|
||||
@@ -44,38 +60,47 @@ static const char * const mips_gpr_names[32] = {
|
||||
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
|
||||
};
|
||||
|
||||
/* ========================================================================
|
||||
* 绝对安全的寄存器屏障访问接口 (Load/Store Barrier)
|
||||
* 每一滴数据都必须经过显式的 temp 中转!
|
||||
* ======================================================================== */
|
||||
static inline int is_zero_reg(int reg) {
|
||||
return reg == 0;
|
||||
// ========================================================================
|
||||
// 异常抛出引擎 (Exception Generator)
|
||||
// ========================================================================
|
||||
|
||||
// 1. 用于条件分支内的异常(仅在异常分支退出,正常执行流继续翻译)
|
||||
static inline void generate_exception_err(DisasContext *ctx, int excp) {
|
||||
tcg_gen_movi_tl(cpu_PC, ctx->pc);
|
||||
TCGv_i32 t_excp = tcg_const_i32(excp);
|
||||
tcg_gen_st_i32(t_excp, cpu_env, offsetof(CPUState, exception_index));
|
||||
tcg_temp_free_i32(t_excp);
|
||||
tcg_gen_exit_tb(0);
|
||||
}
|
||||
|
||||
/* 【核心救命神技】:永远返回一个崭新的 temp,绝不直接泄露 cpu_gpr */
|
||||
// 2. 用于无条件异常(抛出后彻底终止整个基本块的翻译)
|
||||
static inline void generate_exception_end(DisasContext *ctx, int excp) {
|
||||
generate_exception_err(ctx, excp);
|
||||
ctx->base.is_jmp = DISAS_TB_JUMP;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* 绝对安全的寄存器屏障访问接口 (Load/Store Barrier)
|
||||
* ======================================================================== */
|
||||
static inline int is_zero_reg(int reg) { return reg == 0; }
|
||||
|
||||
static inline TCGv load_gpr(int reg) {
|
||||
TCGv t = tcg_temp_new();
|
||||
if (reg == 0) {
|
||||
tcg_gen_movi_tl(t, 0);
|
||||
} else {
|
||||
tcg_gen_mov_tl(t, cpu_gpr[reg]);
|
||||
}
|
||||
if (reg == 0) tcg_gen_movi_tl(t, 0);
|
||||
else tcg_gen_mov_tl(t, cpu_gpr[reg]);
|
||||
return t;
|
||||
}
|
||||
|
||||
static inline void store_gpr(int reg, TCGv val) {
|
||||
if (reg != 0) {
|
||||
tcg_gen_mov_tl(cpu_gpr[reg], val);
|
||||
}
|
||||
if (reg != 0) tcg_gen_mov_tl(cpu_gpr[reg], val);
|
||||
}
|
||||
|
||||
/* 正规的老版本 TB 链接语法 */
|
||||
static inline void gen_goto_tb(DisasContext *dc, int n, uint32_t dest) {
|
||||
TranslationBlock *tb = dc->base.tb;
|
||||
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
|
||||
tcg_gen_goto_tb(n);
|
||||
tcg_gen_movi_tl(cpu_PC, dest);
|
||||
tcg_gen_exit_tb((uintptr_t)tb + n); // 必须用这种指针偏移法,这是老 QEMU 的规矩
|
||||
tcg_gen_exit_tb((uintptr_t)tb + n);
|
||||
} else {
|
||||
tcg_gen_movi_tl(cpu_PC, dest);
|
||||
tcg_gen_exit_tb(0);
|
||||
@@ -83,118 +108,119 @@ static inline void gen_goto_tb(DisasContext *dc, int n, uint32_t dest) {
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* 纯线性算术与逻辑运算 (100% 本地 Temp 化)
|
||||
* 带溢出检测的算术运算与逻辑运算
|
||||
* ======================================================================== */
|
||||
|
||||
static void gen_add_addu(DisasContext *ctx, int rd, int rs, int rt) {
|
||||
static void gen_add(DisasContext *ctx, int rd, int rs, int rt) {
|
||||
if (is_zero_reg(rd)) return;
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv t1 = load_gpr(rt);
|
||||
TCGv res = tcg_temp_new();
|
||||
TCGv res = tcg_temp_local_new(); // 跨越标签生存,必须使用 local temp
|
||||
|
||||
tcg_gen_add_tl(res, t0, t1);
|
||||
|
||||
TCGv t_ov = tcg_temp_new();
|
||||
TCGv t_tmp = tcg_temp_new();
|
||||
tcg_gen_xor_tl(t_ov, t0, res);
|
||||
tcg_gen_xor_tl(t_tmp, t1, res);
|
||||
tcg_gen_and_tl(t_ov, t_ov, t_tmp);
|
||||
|
||||
int l_no_ov = gen_new_label();
|
||||
tcg_gen_brcondi_tl(TCG_COND_GE, t_ov, 0, l_no_ov);
|
||||
|
||||
generate_exception_err(ctx, EXCP_OVERFLOW);
|
||||
|
||||
gen_set_label(l_no_ov);
|
||||
store_gpr(rd, res);
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(res);
|
||||
tcg_temp_free(t_ov); tcg_temp_free(t_tmp);
|
||||
}
|
||||
|
||||
static void gen_sub_subu(DisasContext *ctx, int rd, int rs, int rt) {
|
||||
static void gen_addu(DisasContext *ctx, int rd, int rs, int rt) {
|
||||
if (is_zero_reg(rd)) return;
|
||||
TCGv t0 = load_gpr(rs); TCGv t1 = load_gpr(rt); TCGv res = tcg_temp_new();
|
||||
tcg_gen_add_tl(res, t0, t1);
|
||||
store_gpr(rd, res);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(res);
|
||||
}
|
||||
|
||||
static void gen_sub(DisasContext *ctx, int rd, int rs, int rt) {
|
||||
if (is_zero_reg(rd)) return;
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv t1 = load_gpr(rt);
|
||||
TCGv res = tcg_temp_new();
|
||||
|
||||
TCGv res = tcg_temp_local_new(); // 跨越标签生存,必须使用 local temp
|
||||
tcg_gen_sub_tl(res, t0, t1);
|
||||
|
||||
TCGv t_ov = tcg_temp_new();
|
||||
TCGv t_tmp = tcg_temp_new();
|
||||
tcg_gen_xor_tl(t_ov, t0, t1);
|
||||
tcg_gen_xor_tl(t_tmp, t0, res);
|
||||
tcg_gen_and_tl(t_ov, t_ov, t_tmp);
|
||||
|
||||
int l_no_ov = gen_new_label();
|
||||
tcg_gen_brcondi_tl(TCG_COND_GE, t_ov, 0, l_no_ov);
|
||||
|
||||
generate_exception_err(ctx, EXCP_OVERFLOW);
|
||||
|
||||
gen_set_label(l_no_ov);
|
||||
store_gpr(rd, res);
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(res);
|
||||
tcg_temp_free(t_ov); tcg_temp_free(t_tmp);
|
||||
}
|
||||
|
||||
static void gen_subu(DisasContext *ctx, int rd, int rs, int rt) {
|
||||
if (is_zero_reg(rd)) return;
|
||||
TCGv t0 = load_gpr(rs); TCGv t1 = load_gpr(rt); TCGv res = tcg_temp_new();
|
||||
tcg_gen_sub_tl(res, t0, t1);
|
||||
store_gpr(rd, res);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(res);
|
||||
}
|
||||
|
||||
static void gen_logic(DisasContext *ctx, int rd, int rs, int rt, int op) {
|
||||
if (is_zero_reg(rd)) return;
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv t1 = load_gpr(rt);
|
||||
TCGv res = tcg_temp_new();
|
||||
|
||||
TCGv t0 = load_gpr(rs); TCGv t1 = load_gpr(rt); TCGv res = tcg_temp_new();
|
||||
if (op == 0x24) tcg_gen_and_tl(res, t0, t1);
|
||||
else if (op == 0x25) tcg_gen_or_tl(res, t0, t1);
|
||||
else if (op == 0x26) tcg_gen_xor_tl(res, t0, t1);
|
||||
else if (op == 0x27) {
|
||||
tcg_gen_or_tl(res, t0, t1);
|
||||
tcg_gen_not_tl(res, res);
|
||||
}
|
||||
|
||||
else if (op == 0x27) { tcg_gen_or_tl(res, t0, t1); tcg_gen_not_tl(res, res); }
|
||||
store_gpr(rd, res);
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(res);
|
||||
}
|
||||
|
||||
static void gen_muldiv(DisasContext *ctx, int rs, int rt, int op) {
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv t1 = load_gpr(rt);
|
||||
|
||||
TCGv t0 = load_gpr(rs); TCGv t1 = load_gpr(rt);
|
||||
if (op == 0x18 || op == 0x19) {
|
||||
TCGv t_lo = tcg_temp_new();
|
||||
TCGv t_hi = tcg_temp_new();
|
||||
|
||||
TCGv t_lo = tcg_temp_new(); TCGv t_hi = tcg_temp_new();
|
||||
if (op == 0x18) tcg_gen_muls2_tl(t_lo, t_hi, t0, t1);
|
||||
else tcg_gen_mulu2_tl(t_lo, t_hi, t0, t1);
|
||||
|
||||
tcg_gen_mov_tl(cpu_LO, t_lo);
|
||||
tcg_gen_mov_tl(cpu_HI, t_hi);
|
||||
|
||||
tcg_temp_free(t_lo);
|
||||
tcg_temp_free(t_hi);
|
||||
tcg_gen_mov_tl(cpu_LO, t_lo); tcg_gen_mov_tl(cpu_HI, t_hi);
|
||||
tcg_temp_free(t_lo); tcg_temp_free(t_hi);
|
||||
} else {
|
||||
// DIV / DIVU 防崩溃处理
|
||||
TCGv res = tcg_temp_new();
|
||||
TCGv safe_t1 = tcg_temp_new();
|
||||
TCGv is_zero = tcg_temp_new();
|
||||
|
||||
TCGv res = tcg_temp_new(); TCGv safe_t1 = tcg_temp_new(); TCGv is_zero = tcg_temp_new();
|
||||
tcg_gen_setcondi_tl(TCG_COND_EQ, is_zero, t1, 0);
|
||||
tcg_gen_or_tl(safe_t1, t1, is_zero);
|
||||
tcg_temp_free(is_zero);
|
||||
|
||||
if (op == 0x1A) { // DIV
|
||||
TCGv is_min = tcg_temp_new();
|
||||
TCGv is_neg1 = tcg_temp_new();
|
||||
TCGv is_fpe = tcg_temp_new();
|
||||
TCGv fix_fpe = tcg_temp_new();
|
||||
|
||||
if (op == 0x1A) {
|
||||
TCGv is_min = tcg_temp_new(); TCGv is_neg1 = tcg_temp_new();
|
||||
TCGv is_fpe = tcg_temp_new(); TCGv fix_fpe = tcg_temp_new();
|
||||
tcg_gen_setcondi_tl(TCG_COND_EQ, is_min, t0, 0x80000000);
|
||||
tcg_gen_setcondi_tl(TCG_COND_EQ, is_neg1, t1, 0xFFFFFFFF);
|
||||
tcg_gen_and_tl(is_fpe, is_min, is_neg1);
|
||||
|
||||
tcg_gen_shli_tl(fix_fpe, is_fpe, 1);
|
||||
tcg_gen_add_tl(safe_t1, safe_t1, fix_fpe);
|
||||
|
||||
tcg_gen_div_tl(res, t0, safe_t1);
|
||||
tcg_gen_rem_tl(safe_t1, t0, safe_t1); // 复用 safe_t1 当 HI
|
||||
tcg_gen_mov_tl(cpu_HI, safe_t1);
|
||||
tcg_gen_mov_tl(cpu_LO, res);
|
||||
|
||||
tcg_temp_free(is_min);
|
||||
tcg_temp_free(is_neg1);
|
||||
tcg_temp_free(is_fpe);
|
||||
tcg_temp_free(fix_fpe);
|
||||
} else { // DIVU
|
||||
tcg_gen_rem_tl(safe_t1, t0, safe_t1);
|
||||
tcg_gen_mov_tl(cpu_HI, safe_t1); tcg_gen_mov_tl(cpu_LO, res);
|
||||
tcg_temp_free(is_min); tcg_temp_free(is_neg1); tcg_temp_free(is_fpe); tcg_temp_free(fix_fpe);
|
||||
} else {
|
||||
tcg_gen_divu_tl(res, t0, safe_t1);
|
||||
tcg_gen_remu_tl(safe_t1, t0, safe_t1); // 复用 safe_t1 当 HI
|
||||
tcg_gen_mov_tl(cpu_HI, safe_t1);
|
||||
tcg_gen_mov_tl(cpu_LO, res);
|
||||
tcg_gen_remu_tl(safe_t1, t0, safe_t1);
|
||||
tcg_gen_mov_tl(cpu_HI, safe_t1); tcg_gen_mov_tl(cpu_LO, res);
|
||||
}
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(safe_t1);
|
||||
tcg_temp_free(res); tcg_temp_free(safe_t1);
|
||||
}
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1);
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
@@ -217,35 +243,57 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
|
||||
switch (op) {
|
||||
case 0x00: // SPECIAL (R-Type)
|
||||
switch (funct) {
|
||||
case 0x20: // ADD
|
||||
case 0x21: // ADDU
|
||||
gen_add_addu(ctx, rd, rs, rt);
|
||||
case 0x20: gen_add(ctx, rd, rs, rt); break; // ADD
|
||||
case 0x22: gen_sub(ctx, rd, rs, rt); break; // SUB
|
||||
case 0x21: gen_addu(ctx, rd, rs, rt); break; // ADDU
|
||||
case 0x23: gen_subu(ctx, rd, rs, rt); break; // SUBU
|
||||
|
||||
// 全系陷阱指令 (Trap) - R-Type
|
||||
case 0x30: // TGE
|
||||
case 0x31: // TGEU
|
||||
case 0x32: // TLT
|
||||
case 0x33: // TLTU
|
||||
case 0x34: // TEQ
|
||||
case 0x36: // TNE
|
||||
{
|
||||
TCGv t0 = load_gpr(rs); TCGv t1 = load_gpr(rt);
|
||||
int l_no_trap = gen_new_label();
|
||||
TCGCond cond_skip;
|
||||
|
||||
// 我们采用反向逻辑:如果“不满足陷阱条件”,则跳过抛异常的代码继续执行
|
||||
if (funct == 0x30) cond_skip = TCG_COND_LT; // TGE -> 不满足则跳过 (LT)
|
||||
else if (funct == 0x31) cond_skip = TCG_COND_LTU; // TGEU -> 不满足则跳过 (LTU)
|
||||
else if (funct == 0x32) cond_skip = TCG_COND_GE; // TLT -> 不满足则跳过 (GE)
|
||||
else if (funct == 0x33) cond_skip = TCG_COND_GEU; // TLTU -> 不满足则跳过 (GEU)
|
||||
else if (funct == 0x34) cond_skip = TCG_COND_NE; // TEQ -> 不满足则跳过 (NE)
|
||||
else cond_skip = TCG_COND_EQ; // TNE -> 不满足则跳过 (EQ)
|
||||
|
||||
tcg_gen_brcond_tl(cond_skip, t0, t1, l_no_trap);
|
||||
generate_exception_err(ctx, EXCP_TRAP); // 条件成立,抛出陷阱异常
|
||||
gen_set_label(l_no_trap); // 安全着陆点
|
||||
|
||||
tcg_temp_free(t0); tcg_temp_free(t1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x22: // SUB
|
||||
case 0x23: // SUBU
|
||||
gen_sub_subu(ctx, rd, rs, rt);
|
||||
|
||||
case 0x0C: // SYSCALL
|
||||
generate_exception_end(ctx, EXCP_SYSCALL); // 无条件异常,彻底截断
|
||||
break;
|
||||
case 0x0D: // BREAK
|
||||
generate_exception_end(ctx, EXCP_BREAK);
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
gen_logic(ctx, rd, rs, rt, funct);
|
||||
break;
|
||||
|
||||
case 0x2A: // SLT
|
||||
case 0x2B: // SLTU
|
||||
if (!is_zero_reg(rd)) {
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv t1 = load_gpr(rt);
|
||||
TCGv res = tcg_temp_new();
|
||||
TCGv t0 = load_gpr(rs); TCGv t1 = load_gpr(rt); TCGv res = tcg_temp_new();
|
||||
tcg_gen_setcond_tl((funct == 0x2A) ? TCG_COND_LT : TCG_COND_LTU, res, t0, t1);
|
||||
store_gpr(rd, res);
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(res);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -253,15 +301,12 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
|
||||
case 0x02: // SRL
|
||||
case 0x03: // SRA
|
||||
if (!is_zero_reg(rd)) {
|
||||
TCGv t0 = load_gpr(rt);
|
||||
TCGv res = tcg_temp_new();
|
||||
TCGv t0 = load_gpr(rt); TCGv res = tcg_temp_new();
|
||||
if (funct == 0x00) tcg_gen_shli_tl(res, t0, shamt);
|
||||
else if (funct == 0x02) tcg_gen_shri_tl(res, t0, shamt);
|
||||
else tcg_gen_sari_tl(res, t0, shamt);
|
||||
store_gpr(rd, res);
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(t0); tcg_temp_free(res);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -269,123 +314,98 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
|
||||
case 0x06: // SRLV
|
||||
case 0x07: // SRAV
|
||||
if (!is_zero_reg(rd)) {
|
||||
TCGv t0 = load_gpr(rt);
|
||||
TCGv t1 = load_gpr(rs);
|
||||
TCGv res = tcg_temp_new();
|
||||
TCGv t0 = load_gpr(rt); TCGv t1 = load_gpr(rs); TCGv res = tcg_temp_new();
|
||||
tcg_gen_andi_tl(t1, t1, 0x1F);
|
||||
if (funct == 0x04) tcg_gen_shl_tl(res, t0, t1);
|
||||
else if (funct == 0x06) tcg_gen_shr_tl(res, t0, t1);
|
||||
else tcg_gen_sar_tl(res, t0, t1);
|
||||
store_gpr(rd, res);
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(res);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
case 0x19:
|
||||
case 0x1A:
|
||||
case 0x1B:
|
||||
case 0x18: case 0x19: case 0x1A: case 0x1B:
|
||||
gen_muldiv(ctx, rs, rt, funct);
|
||||
break;
|
||||
|
||||
case 0x10: // MFHI
|
||||
if (!is_zero_reg(rd)) {
|
||||
TCGv t0 = tcg_temp_new();
|
||||
tcg_gen_mov_tl(t0, cpu_HI);
|
||||
store_gpr(rd, t0);
|
||||
tcg_temp_free(t0);
|
||||
TCGv t0 = tcg_temp_new(); tcg_gen_mov_tl(t0, cpu_HI);
|
||||
store_gpr(rd, t0); tcg_temp_free(t0);
|
||||
}
|
||||
break;
|
||||
case 0x12: // MFLO
|
||||
if (!is_zero_reg(rd)) {
|
||||
TCGv t0 = tcg_temp_new();
|
||||
tcg_gen_mov_tl(t0, cpu_LO);
|
||||
store_gpr(rd, t0);
|
||||
tcg_temp_free(t0);
|
||||
TCGv t0 = tcg_temp_new(); tcg_gen_mov_tl(t0, cpu_LO);
|
||||
store_gpr(rd, t0); tcg_temp_free(t0);
|
||||
}
|
||||
break;
|
||||
case 0x11: // MTHI
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
tcg_gen_mov_tl(cpu_HI, t0);
|
||||
tcg_temp_free(t0);
|
||||
TCGv t0 = load_gpr(rs); tcg_gen_mov_tl(cpu_HI, t0); tcg_temp_free(t0);
|
||||
}
|
||||
break;
|
||||
case 0x13: // MTLO
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
tcg_gen_mov_tl(cpu_LO, t0);
|
||||
tcg_temp_free(t0);
|
||||
TCGv t0 = load_gpr(rs); tcg_gen_mov_tl(cpu_LO, t0); tcg_temp_free(t0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08: // JR
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
tcg_gen_mov_tl(cpu_PC, t0);
|
||||
TCGv t0 = load_gpr(rs); tcg_gen_mov_tl(cpu_PC, t0);
|
||||
ctx->hflags |= MIPS_HFLAG_BR;
|
||||
tcg_temp_free(t0);
|
||||
}
|
||||
break;
|
||||
case 0x09: // JALR
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv t1 = tcg_temp_new();
|
||||
tcg_gen_movi_tl(t1, ctx->pc + 8);
|
||||
store_gpr(rd, t1);
|
||||
TCGv t0 = load_gpr(rs); TCGv t1 = tcg_temp_new();
|
||||
tcg_gen_movi_tl(t1, ctx->pc + 8); store_gpr(rd, t1);
|
||||
tcg_gen_mov_tl(cpu_PC, t0);
|
||||
ctx->hflags |= MIPS_HFLAG_BR;
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false; // 交给兜底解释器
|
||||
generate_exception_end(ctx, EXCP_RI);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1C: // SPECIAL2
|
||||
if (funct == 0x02) { // MUL
|
||||
if (!is_zero_reg(rd)) {
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv t1 = load_gpr(rt);
|
||||
TCGv res = tcg_temp_new();
|
||||
tcg_gen_mul_tl(res, t0, t1);
|
||||
store_gpr(rd, res);
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(res);
|
||||
TCGv t0 = load_gpr(rs); TCGv t1 = load_gpr(rt); TCGv res = tcg_temp_new();
|
||||
tcg_gen_mul_tl(res, t0, t1); store_gpr(rd, res);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(res);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
generate_exception_end(ctx, EXCP_RI); return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x11: // COP1 (FPU)
|
||||
generate_exception_end(ctx, EXCP_CpU);
|
||||
return true;
|
||||
|
||||
case 0x08: // ADDI
|
||||
case 0x09: // ADDIU
|
||||
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);
|
||||
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)) {
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv res = tcg_temp_new();
|
||||
TCGv t0 = load_gpr(rs); TCGv res = tcg_temp_new();
|
||||
tcg_gen_setcondi_tl((op == 0x0A) ? TCG_COND_LT : TCG_COND_LTU, res, t0, (op == 0x0A) ? SEXT16(imm) : (uint32_t)SEXT16(imm));
|
||||
store_gpr(rt, res);
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(t0); tcg_temp_free(res);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -393,14 +413,12 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
|
||||
case 0x0D: // ORI
|
||||
case 0x0E: // XORI
|
||||
if (!is_zero_reg(rt)) {
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv res = tcg_temp_new();
|
||||
TCGv t0 = load_gpr(rs); TCGv res = tcg_temp_new();
|
||||
if (op == 0x0C) tcg_gen_andi_tl(res, t0, uimm);
|
||||
else if (op == 0x0D) tcg_gen_ori_tl(res, t0, uimm);
|
||||
else tcg_gen_xori_tl(res, t0, uimm);
|
||||
store_gpr(rt, res);
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(t0); tcg_temp_free(res);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -408,64 +426,73 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
|
||||
if (!is_zero_reg(rt)) {
|
||||
TCGv res = tcg_temp_new();
|
||||
tcg_gen_movi_tl(res, (int32_t)(imm << 16));
|
||||
store_gpr(rt, res);
|
||||
tcg_temp_free(res);
|
||||
store_gpr(rt, res); tcg_temp_free(res);
|
||||
}
|
||||
break;
|
||||
|
||||
/* 分支跳转指令 */
|
||||
/* REGIMM 系列指令:分支与立即数陷阱 */
|
||||
case 0x01: // REGIMM
|
||||
{
|
||||
if (rt != 0x00 && rt != 0x01) return false;
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv res = tcg_temp_new();
|
||||
|
||||
if (rt == 0x00) tcg_gen_setcondi_tl(TCG_COND_LT, res, t0, 0); // BLTZ
|
||||
else tcg_gen_setcondi_tl(TCG_COND_GE, res, t0, 0); // BGEZ
|
||||
|
||||
// 安全使用 _tl 宏,绝对防止截断
|
||||
tcg_gen_st_tl(res, cpu_env, offsetof(CPUState, bcond));
|
||||
ctx->btarget = ctx->pc + 4 + (imm << 2);
|
||||
ctx->hflags |= MIPS_HFLAG_BC;
|
||||
TCGv t0 = load_gpr(rs);
|
||||
|
||||
if (rt == 0x00 || rt == 0x01) { // BLTZ, BGEZ
|
||||
TCGv res = tcg_temp_new();
|
||||
if (rt == 0x00) tcg_gen_setcondi_tl(TCG_COND_LT, res, t0, 0);
|
||||
else tcg_gen_setcondi_tl(TCG_COND_GE, res, t0, 0);
|
||||
tcg_gen_st_tl(res, cpu_env, offsetof(CPUState, bcond));
|
||||
ctx->btarget = ctx->pc + 4 + (imm << 2);
|
||||
ctx->hflags |= MIPS_HFLAG_BC;
|
||||
tcg_temp_free(res);
|
||||
}
|
||||
// 全系陷阱指令 (Trap with Immediate) - I-Type
|
||||
else if (rt >= 0x08 && rt <= 0x0E && rt != 0x0D) {
|
||||
int l_no_trap = gen_new_label();
|
||||
TCGCond cond_skip;
|
||||
|
||||
// 反向逻辑跳过异常:
|
||||
if (rt == 0x08) cond_skip = TCG_COND_LT; // TGEI -> 不满足跳过 (LT)
|
||||
else if (rt == 0x09) cond_skip = TCG_COND_LTU; // TGEIU -> 不满足跳过 (LTU)
|
||||
else if (rt == 0x0A) cond_skip = TCG_COND_GE; // TLTI -> 不满足跳过 (GE)
|
||||
else if (rt == 0x0B) cond_skip = TCG_COND_GEU; // TLTIU -> 不满足跳过 (GEU)
|
||||
else if (rt == 0x0C) cond_skip = TCG_COND_NE; // TEQI -> 不满足跳过 (NE)
|
||||
else cond_skip = TCG_COND_EQ; // TNEI (0x0E) -> 不满足跳过 (EQ)
|
||||
|
||||
// MIPS 的立即数比较,imm 都会被符号扩展为 32位 参与比较
|
||||
tcg_gen_brcondi_tl(cond_skip, t0, SEXT16(imm), l_no_trap);
|
||||
generate_exception_err(ctx, EXCP_TRAP); // 触发立即数陷阱
|
||||
gen_set_label(l_no_trap); // 安全着陆点
|
||||
}
|
||||
else {
|
||||
generate_exception_end(ctx, EXCP_RI); // 不存在的 REGIMM 子指令
|
||||
tcg_temp_free(t0);
|
||||
return true;
|
||||
}
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(res);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x04: // BEQ
|
||||
case 0x05: // BNE
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv t1 = load_gpr(rt);
|
||||
TCGv res = tcg_temp_new();
|
||||
|
||||
TCGv t0 = load_gpr(rs); TCGv t1 = load_gpr(rt); TCGv res = tcg_temp_new();
|
||||
tcg_gen_setcond_tl((op == 0x04) ? TCG_COND_EQ : TCG_COND_NE, res, t0, t1);
|
||||
tcg_gen_st_tl(res, cpu_env, offsetof(CPUState, bcond));
|
||||
ctx->btarget = ctx->pc + 4 + (imm << 2);
|
||||
ctx->hflags |= MIPS_HFLAG_BC;
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(res);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06: // BLEZ
|
||||
case 0x07: // BGTZ
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv res = tcg_temp_new();
|
||||
|
||||
TCGv t0 = load_gpr(rs); TCGv res = tcg_temp_new();
|
||||
if (op == 0x06) tcg_gen_setcondi_tl(TCG_COND_LE, res, t0, 0);
|
||||
else tcg_gen_setcondi_tl(TCG_COND_GT, res, t0, 0);
|
||||
|
||||
tcg_gen_st_tl(res, cpu_env, offsetof(CPUState, bcond));
|
||||
ctx->btarget = ctx->pc + 4 + (imm << 2);
|
||||
ctx->hflags |= MIPS_HFLAG_BC;
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(res);
|
||||
tcg_temp_free(t0); tcg_temp_free(res);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -474,61 +501,117 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
|
||||
ctx->btarget = ((ctx->pc + 4) & 0xF0000000) | (TARGET(insn) << 2);
|
||||
if (op == 0x03) {
|
||||
TCGv res = tcg_temp_new();
|
||||
tcg_gen_movi_tl(res, ctx->pc + 8);
|
||||
store_gpr(31, res);
|
||||
tcg_gen_movi_tl(res, ctx->pc + 8); store_gpr(31, res);
|
||||
tcg_temp_free(res);
|
||||
}
|
||||
ctx->hflags |= MIPS_HFLAG_B;
|
||||
break;
|
||||
|
||||
/* 访存指令 */
|
||||
case 0x20: // LB
|
||||
case 0x21: // LH
|
||||
/* ===============================================================
|
||||
* 访存异常监控 (Memory Traps: EXCP_AdEL / EXCP_AdES)
|
||||
* =============================================================== */
|
||||
case 0x23: // LW
|
||||
case 0x24: // LBU
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv addr = tcg_temp_local_new(); // 使用 local temp,跨越标签存活
|
||||
tcg_gen_addi_tl(addr, t0, SEXT16(imm));
|
||||
|
||||
int l_align_ok = gen_new_label();
|
||||
TCGv t_align = tcg_temp_new();
|
||||
tcg_gen_andi_tl(t_align, addr, 0x3);
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, t_align, 0, l_align_ok);
|
||||
generate_exception_err(ctx, EXCP_AdEL); // 条件异常,仅本分支停止
|
||||
|
||||
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);
|
||||
store_gpr(rt, res);
|
||||
tcg_temp_free(t0); tcg_temp_free(addr); tcg_temp_free(res); tcg_temp_free(t_align);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2B: // SW
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv addr = tcg_temp_local_new(); // 使用 local temp
|
||||
tcg_gen_addi_tl(addr, t0, SEXT16(imm));
|
||||
|
||||
int l_align_ok = gen_new_label();
|
||||
TCGv t_align = tcg_temp_new();
|
||||
tcg_gen_andi_tl(t_align, addr, 0x3);
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, t_align, 0, l_align_ok);
|
||||
generate_exception_err(ctx, EXCP_AdES); // 条件异常,仅本分支停止
|
||||
|
||||
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_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(addr); tcg_temp_free(t_align);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x21: // LH
|
||||
case 0x25: // LHU
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv addr = tcg_temp_new();
|
||||
TCGv res = tcg_temp_new();
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv addr = tcg_temp_local_new(); // 使用 local temp
|
||||
tcg_gen_addi_tl(addr, t0, SEXT16(imm));
|
||||
TCGMemOp mop = MO_TE;
|
||||
if (op == 0x20) mop |= MO_SB;
|
||||
else if (op == 0x21) mop |= MO_SW;
|
||||
else if (op == 0x23) mop |= MO_SL;
|
||||
else if (op == 0x24) mop |= MO_UB;
|
||||
else mop |= MO_UW;
|
||||
tcg_gen_qemu_ld_tl(res, addr, ctx->mem_idx, mop);
|
||||
store_gpr(rt, res);
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(addr);
|
||||
tcg_temp_free(res);
|
||||
int l_align_ok = gen_new_label();
|
||||
TCGv t_align = tcg_temp_new();
|
||||
tcg_gen_andi_tl(t_align, addr, 0x1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, t_align, 0, l_align_ok);
|
||||
generate_exception_err(ctx, EXCP_AdEL); // 条件异常,仅本分支停止
|
||||
|
||||
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));
|
||||
store_gpr(rt, res);
|
||||
tcg_temp_free(t0); tcg_temp_free(addr); tcg_temp_free(res); tcg_temp_free(t_align);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x29: // SH
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv addr = tcg_temp_local_new(); // 使用 local temp
|
||||
tcg_gen_addi_tl(addr, t0, SEXT16(imm));
|
||||
|
||||
int l_align_ok = gen_new_label();
|
||||
TCGv t_align = tcg_temp_new();
|
||||
tcg_gen_andi_tl(t_align, addr, 0x1);
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, t_align, 0, l_align_ok);
|
||||
generate_exception_err(ctx, EXCP_AdES); // 条件异常,仅本分支停止
|
||||
|
||||
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_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(addr); tcg_temp_free(t_align);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x20: // LB
|
||||
case 0x24: // LBU
|
||||
{
|
||||
TCGv t0 = load_gpr(rs); TCGv addr = tcg_temp_new(); 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));
|
||||
store_gpr(rt, res);
|
||||
tcg_temp_free(t0); tcg_temp_free(addr); tcg_temp_free(res);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x28: // SB
|
||||
case 0x29: // SH
|
||||
case 0x2B: // SW
|
||||
{
|
||||
TCGv t0 = load_gpr(rs);
|
||||
TCGv t1 = load_gpr(rt);
|
||||
TCGv addr = tcg_temp_new();
|
||||
TCGv t0 = load_gpr(rs); TCGv t1 = load_gpr(rt); TCGv addr = tcg_temp_new();
|
||||
tcg_gen_addi_tl(addr, t0, SEXT16(imm));
|
||||
TCGMemOp smop = MO_TE;
|
||||
if (op == 0x28) smop |= MO_UB;
|
||||
else if (op == 0x29) smop |= MO_UW;
|
||||
else smop |= MO_UL;
|
||||
tcg_gen_qemu_st_tl(t1, addr, ctx->mem_idx, smop);
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(addr);
|
||||
tcg_gen_qemu_st_tl(t1, addr, ctx->mem_idx, MO_TE | MO_UB);
|
||||
tcg_temp_free(t0); tcg_temp_free(t1); tcg_temp_free(addr);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
generate_exception_end(ctx, EXCP_RI);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -538,7 +621,7 @@ static bool disas_insn(CPUState *env, DisasContext *ctx)
|
||||
* 主控架构
|
||||
* ======================================================================== */
|
||||
void translate_init(void) {
|
||||
printf("\n==== 🚀 终极救赎版!重铸 Local Temp 屏障,完美消灭 TCG 死锁! ==== \n\n");
|
||||
printf("\n====ALL-GOOD==== \n\n");
|
||||
for (int i = 0; i < 32; i++) {
|
||||
cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, gpr[i]), mips_gpr_names[i]);
|
||||
}
|
||||
@@ -580,28 +663,24 @@ int gen_intermediate_code(CPUState *env, DisasContextBase *dcbase) {
|
||||
}
|
||||
else if (ctx->hflags & MIPS_HFLAG_BC) {
|
||||
int l1 = gen_new_label();
|
||||
int l_end = gen_new_label(); // 建立一个统一的安全出口
|
||||
int l_end = gen_new_label();
|
||||
|
||||
TCGv bv = tcg_temp_new();
|
||||
tcg_gen_ld_tl(bv, cpu_env, offsetof(CPUState, bcond));
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, bv, 0, l1);
|
||||
|
||||
// --- 条件为真:起跳 ---
|
||||
TCGv t_dest = tcg_temp_new();
|
||||
tcg_gen_ld_tl(t_dest, cpu_env, offsetof(CPUState, btarget));
|
||||
tcg_gen_mov_tl(cpu_PC, t_dest);
|
||||
tcg_temp_free(t_dest);
|
||||
tcg_gen_br(l_end); // 绝不提前 exit_tb,跳到统一出口
|
||||
tcg_gen_br(l_end);
|
||||
|
||||
// --- 条件为假:越过延迟槽 ---
|
||||
gen_set_label(l1);
|
||||
tcg_gen_movi_tl(cpu_PC, dcbase->pc + 4);
|
||||
|
||||
// --- 统一安全出口 (Common Exit) ---
|
||||
gen_set_label(l_end);
|
||||
tcg_temp_free(bv);
|
||||
|
||||
// 只有汇聚到这里,才统一清空状态并宣告块结束,彻底避免临时变量死锁!
|
||||
TCGv_i32 t_hflags = tcg_const_i32(0);
|
||||
tcg_gen_st_i32(t_hflags, cpu_env, offsetof(CPUState, hflags));
|
||||
tcg_temp_free_i32(t_hflags);
|
||||
@@ -619,7 +698,7 @@ int gen_intermediate_code(CPUState *env, DisasContextBase *dcbase) {
|
||||
dcbase->tb->size += 4;
|
||||
dcbase->pc += 4;
|
||||
|
||||
// 如果上面经历了 exit_tb (即 IS_JUMP),则下面不会再生成多余的垃圾代码
|
||||
// 【修复核心】彻底移除了不存在的 DISAS_NORETURN 宏的判断
|
||||
if (ctx->base.is_jmp != DISAS_TB_JUMP) {
|
||||
TCGv_i32 t_hflags = tcg_const_i32(ctx->hflags);
|
||||
tcg_gen_st_i32(t_hflags, cpu_env, offsetof(CPUState, hflags));
|
||||
@@ -650,7 +729,7 @@ void setup_disas_context(DisasContextBase *dcbase, CPUState *env) {
|
||||
}
|
||||
|
||||
int gen_breakpoint(DisasContextBase *dcbase, CPUBreakpoint *bp) {
|
||||
tcg_gen_exit_tb(0);
|
||||
generate_exception_end((DisasContext*)dcbase, EXCP_BREAK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.9568.24184",
|
||||
"AntShell.Reference": "1.0.9571.20353",
|
||||
"BigGustave.Reference": "1.0.0.0",
|
||||
"crypto.Reference": "1.9.0.0",
|
||||
"CxxDemangler.Reference": "1.0.9568.24177",
|
||||
"CxxDemangler.Reference": "1.0.9571.20346",
|
||||
"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.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"runtime": {
|
||||
"AntShell.dll": {
|
||||
"assemblyVersion": "1.0.9568.24184",
|
||||
"assemblyVersion": "1.0.9571.20353",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1806,10 +1806,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"runtime": {
|
||||
"CxxDemangler.dll": {
|
||||
"assemblyVersion": "1.0.9568.24177",
|
||||
"assemblyVersion": "1.0.9571.20346",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -2841,7 +2841,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"AntShell.Reference/1.0.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
@@ -2856,7 +2856,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"OptionsParser/1.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.NET.Test.Sdk": "16.9.1",
|
||||
"NUnit": "3.13.1",
|
||||
"NUnit3TestAdapter": "3.17.0",
|
||||
"OptionsParser": "1.0.0"
|
||||
"NUnit3TestAdapter": "3.17.0"
|
||||
},
|
||||
"runtime": {
|
||||
"OptionsParser.dll": {}
|
||||
|
||||
Binary file not shown.
@@ -8,10 +8,10 @@
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"OptionsParser/1.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.NET.Test.Sdk": "16.9.1",
|
||||
"NUnit": "3.13.1",
|
||||
"NUnit3TestAdapter": "3.17.0",
|
||||
"OptionsParser": "1.0.0"
|
||||
"NUnit3TestAdapter": "3.17.0"
|
||||
},
|
||||
"runtime": {
|
||||
"OptionsParser.dll": {}
|
||||
|
||||
@@ -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.9568.24184",
|
||||
"AntShell.Reference": "1.0.9571.20353",
|
||||
"BigGustave.Reference": "1.0.0.0",
|
||||
"crypto.Reference": "1.9.0.0",
|
||||
"CxxDemangler.Reference": "1.0.9568.24177",
|
||||
"CxxDemangler.Reference": "1.0.9571.20346",
|
||||
"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.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"runtime": {
|
||||
"AntShell.dll": {
|
||||
"assemblyVersion": "1.0.9568.24184",
|
||||
"assemblyVersion": "1.0.9571.20353",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1805,10 +1805,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"runtime": {
|
||||
"CxxDemangler.dll": {
|
||||
"assemblyVersion": "1.0.9568.24177",
|
||||
"assemblyVersion": "1.0.9571.20346",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -2840,7 +2840,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"AntShell.Reference/1.0.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
@@ -2855,7 +2855,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
|
||||
Binary file not shown.
@@ -8,10 +8,10 @@
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"OptionsParser/1.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.NET.Test.Sdk": "16.9.1",
|
||||
"NUnit": "3.13.1",
|
||||
"NUnit3TestAdapter": "3.17.0",
|
||||
"OptionsParser": "1.0.0"
|
||||
"NUnit3TestAdapter": "3.17.0"
|
||||
},
|
||||
"runtime": {
|
||||
"OptionsParser.dll": {}
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
"AntShell": "1.0.0",
|
||||
"Infrastructure": "1.0.0",
|
||||
"StyleCop.Analyzers": "1.1.118",
|
||||
"AntShell.Reference": "1.0.9568.24184",
|
||||
"AntShell.Reference": "1.0.9571.20353",
|
||||
"BigGustave.Reference": "1.0.0.0",
|
||||
"crypto.Reference": "1.9.0.0",
|
||||
"CxxDemangler.Reference": "1.0.9568.24177",
|
||||
"CxxDemangler.Reference": "1.0.9571.20346",
|
||||
"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.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"runtime": {
|
||||
"AntShell.dll": {
|
||||
"assemblyVersion": "1.0.9568.24184",
|
||||
"assemblyVersion": "1.0.9571.20353",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1598,10 +1598,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"runtime": {
|
||||
"CxxDemangler.dll": {
|
||||
"assemblyVersion": "1.0.9568.24177",
|
||||
"assemblyVersion": "1.0.9571.20346",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -2507,7 +2507,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"AntShell.Reference/1.0.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
@@ -2522,7 +2522,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -8,10 +8,10 @@
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"OptionsParser/1.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.NET.Test.Sdk": "16.9.1",
|
||||
"NUnit": "3.13.1",
|
||||
"NUnit3TestAdapter": "3.17.0",
|
||||
"OptionsParser": "1.0.0"
|
||||
"NUnit3TestAdapter": "3.17.0"
|
||||
},
|
||||
"runtime": {
|
||||
"OptionsParser.dll": {}
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
"Xwt": "1.0.0",
|
||||
"Xwt.Gtk3": "1.0.0",
|
||||
"libtftp": "1.0.0",
|
||||
"AntShell.Reference": "1.0.9568.24184",
|
||||
"AntShell.Reference": "1.0.9571.20353",
|
||||
"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.9568.24177",
|
||||
"CxxDemangler.Reference": "1.0.9571.20346",
|
||||
"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.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"runtime": {
|
||||
"AntShell.dll": {
|
||||
"assemblyVersion": "1.0.9568.24184",
|
||||
"assemblyVersion": "1.0.9571.20353",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1994,10 +1994,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"runtime": {
|
||||
"CxxDemangler.dll": {
|
||||
"assemblyVersion": "1.0.9568.24177",
|
||||
"assemblyVersion": "1.0.9571.20346",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -3134,7 +3134,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"AntShell.Reference/1.0.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
@@ -3159,7 +3159,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
"NUnit3TestAdapter": "3.17.0",
|
||||
"Renode": "1.0.0",
|
||||
"UnitTests": "1.0.0",
|
||||
"AntShell.Reference": "1.0.9568.24184",
|
||||
"AntShell.Reference": "1.0.9571.20353",
|
||||
"BigGustave.Reference": "1.0.0.0",
|
||||
"CoSimulationPlugin.Reference": "1.0.0.0",
|
||||
"crypto.Reference": "1.9.0.0",
|
||||
"CxxDemangler.Reference": "1.0.9568.24177",
|
||||
"CxxDemangler.Reference": "1.0.9571.20346",
|
||||
"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.24240",
|
||||
"Renode.Reference": "1.16.0.20385",
|
||||
"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.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"runtime": {
|
||||
"AntShell.dll": {
|
||||
"assemblyVersion": "1.0.9568.24184",
|
||||
"assemblyVersion": "1.0.9571.20353",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -2067,10 +2067,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"runtime": {
|
||||
"CxxDemangler.dll": {
|
||||
"assemblyVersion": "1.0.9568.24177",
|
||||
"assemblyVersion": "1.0.9571.20346",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -2131,10 +2131,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Renode.Reference/1.16.0.24240": {
|
||||
"Renode.Reference/1.16.0.20385": {
|
||||
"runtime": {
|
||||
"Renode.dll": {
|
||||
"assemblyVersion": "1.16.0.24240",
|
||||
"assemblyVersion": "1.16.0.20385",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -3255,7 +3255,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"AntShell.Reference/1.0.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
@@ -3275,7 +3275,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
@@ -3315,7 +3315,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Renode.Reference/1.16.0.24240": {
|
||||
"Renode.Reference/1.16.0.20385": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
"NUnit3TestAdapter": "3.17.0",
|
||||
"Renode": "1.0.0",
|
||||
"StyleCop.Analyzers": "1.1.118",
|
||||
"AntShell.Reference": "1.0.9568.24184",
|
||||
"AntShell.Reference": "1.0.9571.20353",
|
||||
"BigGustave.Reference": "1.0.0.0",
|
||||
"CoSimulationPlugin.Reference": "1.0.0.0",
|
||||
"crypto.Reference": "1.9.0.0",
|
||||
"CxxDemangler.Reference": "1.0.9568.24177",
|
||||
"CxxDemangler.Reference": "1.0.9571.20346",
|
||||
"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.24240",
|
||||
"Renode.Reference": "1.16.0.20385",
|
||||
"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.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"runtime": {
|
||||
"AntShell.dll": {
|
||||
"assemblyVersion": "1.0.9568.24184",
|
||||
"assemblyVersion": "1.0.9571.20353",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -2050,10 +2050,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"runtime": {
|
||||
"CxxDemangler.dll": {
|
||||
"assemblyVersion": "1.0.9568.24177",
|
||||
"assemblyVersion": "1.0.9571.20346",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -2122,10 +2122,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Renode.Reference/1.16.0.24240": {
|
||||
"Renode.Reference/1.16.0.20385": {
|
||||
"runtime": {
|
||||
"Renode.dll": {
|
||||
"assemblyVersion": "1.16.0.24240",
|
||||
"assemblyVersion": "1.16.0.20385",
|
||||
"fileVersion": "0.0.0.0"
|
||||
}
|
||||
}
|
||||
@@ -3232,7 +3232,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"AntShell.Reference/1.0.9568.24184": {
|
||||
"AntShell.Reference/1.0.9571.20353": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
@@ -3252,7 +3252,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"CxxDemangler.Reference/1.0.9568.24177": {
|
||||
"CxxDemangler.Reference/1.0.9571.20346": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
@@ -3297,7 +3297,7 @@
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Renode.Reference/1.16.0.24240": {
|
||||
"Renode.Reference/1.16.0.20385": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user