提交 fe0bd475 编写于 作者: M Max Filippov 提交者: Blue Swirl

target-xtensa: restrict available SRs by enabled options

Beginning with the RA-2004.1 release, SR access instructions (rsr, wsr,
xsr) are associated with their corresponding SR and raise illegal opcode
exception in case the register is not configured for the core.
Signed-off-by: NMax Filippov <jcmvbkbc@gmail.com>
Signed-off-by: NBlue Swirl <blauwirbel@gmail.com>
上级 4e41d2f5
...@@ -416,6 +416,7 @@ void debug_exception_env(CPUXtensaState *new_env, uint32_t cause); ...@@ -416,6 +416,7 @@ void debug_exception_env(CPUXtensaState *new_env, uint32_t cause);
#define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt)) #define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
#define XTENSA_OPTION_ALL (~(uint64_t)0)
static inline bool xtensa_option_bits_enabled(const XtensaConfig *config, static inline bool xtensa_option_bits_enabled(const XtensaConfig *config,
uint64_t opt) uint64_t opt)
......
...@@ -94,7 +94,9 @@ ...@@ -94,7 +94,9 @@
XCHAL_OPTION(XCHAL_HAVE_CACHEATTR, XTENSA_OPTION_CACHEATTR) | \ XCHAL_OPTION(XCHAL_HAVE_CACHEATTR, XTENSA_OPTION_CACHEATTR) | \
/* Other, TODO */ \ /* Other, TODO */ \
XCHAL_OPTION(XCHAL_HAVE_WINDOWED, XTENSA_OPTION_WINDOWED_REGISTER) | \ XCHAL_OPTION(XCHAL_HAVE_WINDOWED, XTENSA_OPTION_WINDOWED_REGISTER) | \
XCHAL_OPTION(XCHAL_HAVE_DEBUG, XTENSA_OPTION_DEBUG)) XCHAL_OPTION(XCHAL_HAVE_DEBUG, XTENSA_OPTION_DEBUG) |\
XCHAL_OPTION(XCHAL_HAVE_THREADPTR, XTENSA_OPTION_THREAD_POINTER) | \
XCHAL_OPTION(XCHAL_HAVE_PRID, XTENSA_OPTION_PROCESSOR_ID))
#ifndef XCHAL_WINDOW_OF4_VECOFS #ifndef XCHAL_WINDOW_OF4_VECOFS
#define XCHAL_WINDOW_OF4_VECOFS 0x00000000 #define XCHAL_WINDOW_OF4_VECOFS 0x00000000
......
...@@ -78,78 +78,102 @@ static TCGv_i32 cpu_UR[256]; ...@@ -78,78 +78,102 @@ static TCGv_i32 cpu_UR[256];
#include "gen-icount.h" #include "gen-icount.h"
static const char * const sregnames[256] = { typedef struct XtensaReg {
[LBEG] = "LBEG", const char *name;
[LEND] = "LEND", uint64_t opt_bits;
[LCOUNT] = "LCOUNT", } XtensaReg;
[SAR] = "SAR",
[BR] = "BR", #define XTENSA_REG(regname, opt) { \
[LITBASE] = "LITBASE", .name = (regname), \
[SCOMPARE1] = "SCOMPARE1", .opt_bits = XTENSA_OPTION_BIT(opt), \
[ACCLO] = "ACCLO", }
[ACCHI] = "ACCHI",
[MR] = "MR0", #define XTENSA_REG_BITS(regname, opt) { \
[MR + 1] = "MR1", .name = (regname), \
[MR + 2] = "MR2", .opt_bits = (opt), \
[MR + 3] = "MR3", }
[WINDOW_BASE] = "WINDOW_BASE",
[WINDOW_START] = "WINDOW_START", static const XtensaReg sregnames[256] = {
[PTEVADDR] = "PTEVADDR", [LBEG] = XTENSA_REG("LBEG", XTENSA_OPTION_LOOP),
[RASID] = "RASID", [LEND] = XTENSA_REG("LEND", XTENSA_OPTION_LOOP),
[ITLBCFG] = "ITLBCFG", [LCOUNT] = XTENSA_REG("LCOUNT", XTENSA_OPTION_LOOP),
[DTLBCFG] = "DTLBCFG", [SAR] = XTENSA_REG_BITS("SAR", XTENSA_OPTION_ALL),
[IBREAKENABLE] = "IBREAKENABLE", [BR] = XTENSA_REG("BR", XTENSA_OPTION_BOOLEAN),
[CACHEATTR] = "CACHEATTR", [LITBASE] = XTENSA_REG("LITBASE", XTENSA_OPTION_EXTENDED_L32R),
[ATOMCTL] = "ATOMCTL", [SCOMPARE1] = XTENSA_REG("SCOMPARE1", XTENSA_OPTION_CONDITIONAL_STORE),
[IBREAKA] = "IBREAKA0", [ACCLO] = XTENSA_REG("ACCLO", XTENSA_OPTION_MAC16),
[IBREAKA + 1] = "IBREAKA1", [ACCHI] = XTENSA_REG("ACCHI", XTENSA_OPTION_MAC16),
[DBREAKA] = "DBREAKA0", [MR] = XTENSA_REG("MR0", XTENSA_OPTION_MAC16),
[DBREAKA + 1] = "DBREAKA1", [MR + 1] = XTENSA_REG("MR1", XTENSA_OPTION_MAC16),
[DBREAKC] = "DBREAKC0", [MR + 2] = XTENSA_REG("MR2", XTENSA_OPTION_MAC16),
[DBREAKC + 1] = "DBREAKC1", [MR + 3] = XTENSA_REG("MR3", XTENSA_OPTION_MAC16),
[EPC1] = "EPC1", [WINDOW_BASE] = XTENSA_REG("WINDOW_BASE", XTENSA_OPTION_WINDOWED_REGISTER),
[EPC1 + 1] = "EPC2", [WINDOW_START] = XTENSA_REG("WINDOW_START",
[EPC1 + 2] = "EPC3", XTENSA_OPTION_WINDOWED_REGISTER),
[EPC1 + 3] = "EPC4", [PTEVADDR] = XTENSA_REG("PTEVADDR", XTENSA_OPTION_MMU),
[EPC1 + 4] = "EPC5", [RASID] = XTENSA_REG("RASID", XTENSA_OPTION_MMU),
[EPC1 + 5] = "EPC6", [ITLBCFG] = XTENSA_REG("ITLBCFG", XTENSA_OPTION_MMU),
[EPC1 + 6] = "EPC7", [DTLBCFG] = XTENSA_REG("DTLBCFG", XTENSA_OPTION_MMU),
[DEPC] = "DEPC", [IBREAKENABLE] = XTENSA_REG("IBREAKENABLE", XTENSA_OPTION_DEBUG),
[EPS2] = "EPS2", [CACHEATTR] = XTENSA_REG("CACHEATTR", XTENSA_OPTION_CACHEATTR),
[EPS2 + 1] = "EPS3", [ATOMCTL] = XTENSA_REG("ATOMCTL", XTENSA_OPTION_ATOMCTL),
[EPS2 + 2] = "EPS4", [IBREAKA] = XTENSA_REG("IBREAKA0", XTENSA_OPTION_DEBUG),
[EPS2 + 3] = "EPS5", [IBREAKA + 1] = XTENSA_REG("IBREAKA1", XTENSA_OPTION_DEBUG),
[EPS2 + 4] = "EPS6", [DBREAKA] = XTENSA_REG("DBREAKA0", XTENSA_OPTION_DEBUG),
[EPS2 + 5] = "EPS7", [DBREAKA + 1] = XTENSA_REG("DBREAKA1", XTENSA_OPTION_DEBUG),
[EXCSAVE1] = "EXCSAVE1", [DBREAKC] = XTENSA_REG("DBREAKC0", XTENSA_OPTION_DEBUG),
[EXCSAVE1 + 1] = "EXCSAVE2", [DBREAKC + 1] = XTENSA_REG("DBREAKC1", XTENSA_OPTION_DEBUG),
[EXCSAVE1 + 2] = "EXCSAVE3", [EPC1] = XTENSA_REG("EPC1", XTENSA_OPTION_EXCEPTION),
[EXCSAVE1 + 3] = "EXCSAVE4", [EPC1 + 1] = XTENSA_REG("EPC2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[EXCSAVE1 + 4] = "EXCSAVE5", [EPC1 + 2] = XTENSA_REG("EPC3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[EXCSAVE1 + 5] = "EXCSAVE6", [EPC1 + 3] = XTENSA_REG("EPC4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[EXCSAVE1 + 6] = "EXCSAVE7", [EPC1 + 4] = XTENSA_REG("EPC5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[CPENABLE] = "CPENABLE", [EPC1 + 5] = XTENSA_REG("EPC6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[INTSET] = "INTSET", [EPC1 + 6] = XTENSA_REG("EPC7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[INTCLEAR] = "INTCLEAR", [DEPC] = XTENSA_REG("DEPC", XTENSA_OPTION_EXCEPTION),
[INTENABLE] = "INTENABLE", [EPS2] = XTENSA_REG("EPS2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[PS] = "PS", [EPS2 + 1] = XTENSA_REG("EPS3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[VECBASE] = "VECBASE", [EPS2 + 2] = XTENSA_REG("EPS4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[EXCCAUSE] = "EXCCAUSE", [EPS2 + 3] = XTENSA_REG("EPS5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[DEBUGCAUSE] = "DEBUGCAUSE", [EPS2 + 4] = XTENSA_REG("EPS6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[CCOUNT] = "CCOUNT", [EPS2 + 5] = XTENSA_REG("EPS7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[PRID] = "PRID", [EXCSAVE1] = XTENSA_REG("EXCSAVE1", XTENSA_OPTION_EXCEPTION),
[ICOUNT] = "ICOUNT", [EXCSAVE1 + 1] = XTENSA_REG("EXCSAVE2",
[ICOUNTLEVEL] = "ICOUNTLEVEL", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[EXCVADDR] = "EXCVADDR", [EXCSAVE1 + 2] = XTENSA_REG("EXCSAVE3",
[CCOMPARE] = "CCOMPARE0", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[CCOMPARE + 1] = "CCOMPARE1", [EXCSAVE1 + 3] = XTENSA_REG("EXCSAVE4",
[CCOMPARE + 2] = "CCOMPARE2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[EXCSAVE1 + 4] = XTENSA_REG("EXCSAVE5",
XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[EXCSAVE1 + 5] = XTENSA_REG("EXCSAVE6",
XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[EXCSAVE1 + 6] = XTENSA_REG("EXCSAVE7",
XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
[CPENABLE] = XTENSA_REG("CPENABLE", XTENSA_OPTION_COPROCESSOR),
[INTSET] = XTENSA_REG("INTSET", XTENSA_OPTION_INTERRUPT),
[INTCLEAR] = XTENSA_REG("INTCLEAR", XTENSA_OPTION_INTERRUPT),
[INTENABLE] = XTENSA_REG("INTENABLE", XTENSA_OPTION_INTERRUPT),
[PS] = XTENSA_REG_BITS("PS", XTENSA_OPTION_ALL),
[VECBASE] = XTENSA_REG("VECBASE", XTENSA_OPTION_RELOCATABLE_VECTOR),
[EXCCAUSE] = XTENSA_REG("EXCCAUSE", XTENSA_OPTION_EXCEPTION),
[DEBUGCAUSE] = XTENSA_REG("DEBUGCAUSE", XTENSA_OPTION_DEBUG),
[CCOUNT] = XTENSA_REG("CCOUNT", XTENSA_OPTION_TIMER_INTERRUPT),
[PRID] = XTENSA_REG("PRID", XTENSA_OPTION_PROCESSOR_ID),
[ICOUNT] = XTENSA_REG("ICOUNT", XTENSA_OPTION_DEBUG),
[ICOUNTLEVEL] = XTENSA_REG("ICOUNTLEVEL", XTENSA_OPTION_DEBUG),
[EXCVADDR] = XTENSA_REG("EXCVADDR", XTENSA_OPTION_EXCEPTION),
[CCOMPARE] = XTENSA_REG("CCOMPARE0", XTENSA_OPTION_TIMER_INTERRUPT),
[CCOMPARE + 1] = XTENSA_REG("CCOMPARE1",
XTENSA_OPTION_TIMER_INTERRUPT),
[CCOMPARE + 2] = XTENSA_REG("CCOMPARE2",
XTENSA_OPTION_TIMER_INTERRUPT),
}; };
static const char * const uregnames[256] = { static const XtensaReg uregnames[256] = {
[THREADPTR] = "THREADPTR", [THREADPTR] = XTENSA_REG("THREADPTR", XTENSA_OPTION_THREAD_POINTER),
[FCR] = "FCR", [FCR] = XTENSA_REG("FCR", XTENSA_OPTION_FP_COPROCESSOR),
[FSR] = "FSR", [FSR] = XTENSA_REG("FSR", XTENSA_OPTION_FP_COPROCESSOR),
}; };
void xtensa_translate_init(void) void xtensa_translate_init(void)
...@@ -185,18 +209,18 @@ void xtensa_translate_init(void) ...@@ -185,18 +209,18 @@ void xtensa_translate_init(void)
} }
for (i = 0; i < 256; ++i) { for (i = 0; i < 256; ++i) {
if (sregnames[i]) { if (sregnames[i].name) {
cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0, cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
offsetof(CPUXtensaState, sregs[i]), offsetof(CPUXtensaState, sregs[i]),
sregnames[i]); sregnames[i].name);
} }
} }
for (i = 0; i < 256; ++i) { for (i = 0; i < 256; ++i) {
if (uregnames[i]) { if (uregnames[i].name) {
cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0, cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,
offsetof(CPUXtensaState, uregs[i]), offsetof(CPUXtensaState, uregs[i]),
uregnames[i]); uregnames[i].name);
} }
} }
#define GEN_HELPER 2 #define GEN_HELPER 2
...@@ -452,6 +476,18 @@ static void gen_brcondi(DisasContext *dc, TCGCond cond, ...@@ -452,6 +476,18 @@ static void gen_brcondi(DisasContext *dc, TCGCond cond,
tcg_temp_free(tmp); tcg_temp_free(tmp);
} }
static void gen_check_sr(DisasContext *dc, uint32_t sr)
{
if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) {
if (sregnames[sr].name) {
qemu_log("SR %s is not configured\n", sregnames[sr].name);
} else {
qemu_log("SR %d is not implemented\n", sr);
}
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
}
}
static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr) static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
{ {
gen_advance_ccount(dc); gen_advance_ccount(dc);
...@@ -473,14 +509,10 @@ static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr) ...@@ -473,14 +509,10 @@ static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
[PTEVADDR] = gen_rsr_ptevaddr, [PTEVADDR] = gen_rsr_ptevaddr,
}; };
if (sregnames[sr]) { if (rsr_handler[sr]) {
if (rsr_handler[sr]) { rsr_handler[sr](dc, d, sr);
rsr_handler[sr](dc, d, sr);
} else {
tcg_gen_mov_i32(d, cpu_SR[sr]);
}
} else { } else {
qemu_log("RSR %d not implemented, ", sr); tcg_gen_mov_i32(d, cpu_SR[sr]);
} }
} }
...@@ -721,14 +753,10 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) ...@@ -721,14 +753,10 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
[CCOMPARE + 2] = gen_wsr_ccompare, [CCOMPARE + 2] = gen_wsr_ccompare,
}; };
if (sregnames[sr]) { if (wsr_handler[sr]) {
if (wsr_handler[sr]) { wsr_handler[sr](dc, sr, s);
wsr_handler[sr](dc, sr, s);
} else {
tcg_gen_mov_i32(cpu_SR[sr], s);
}
} else { } else {
qemu_log("WSR %d not implemented, ", sr); tcg_gen_mov_i32(cpu_SR[sr], s);
} }
} }
...@@ -1439,6 +1467,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) ...@@ -1439,6 +1467,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
case 6: /*XSR*/ case 6: /*XSR*/
{ {
TCGv_i32 tmp = tcg_temp_new_i32(); TCGv_i32 tmp = tcg_temp_new_i32();
gen_check_sr(dc, RSR_SR);
if (RSR_SR >= 64) { if (RSR_SR >= 64) {
gen_check_privilege(dc); gen_check_privilege(dc);
} }
...@@ -1447,9 +1476,6 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) ...@@ -1447,9 +1476,6 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
gen_rsr(dc, cpu_R[RRR_T], RSR_SR); gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
gen_wsr(dc, RSR_SR, tmp); gen_wsr(dc, RSR_SR, tmp);
tcg_temp_free(tmp); tcg_temp_free(tmp);
if (!sregnames[RSR_SR]) {
TBD();
}
} }
break; break;
...@@ -1672,25 +1698,21 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) ...@@ -1672,25 +1698,21 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
case 3: /*RST3*/ case 3: /*RST3*/
switch (OP2) { switch (OP2) {
case 0: /*RSR*/ case 0: /*RSR*/
gen_check_sr(dc, RSR_SR);
if (RSR_SR >= 64) { if (RSR_SR >= 64) {
gen_check_privilege(dc); gen_check_privilege(dc);
} }
gen_window_check1(dc, RRR_T); gen_window_check1(dc, RRR_T);
gen_rsr(dc, cpu_R[RRR_T], RSR_SR); gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
if (!sregnames[RSR_SR]) {
TBD();
}
break; break;
case 1: /*WSR*/ case 1: /*WSR*/
gen_check_sr(dc, RSR_SR);
if (RSR_SR >= 64) { if (RSR_SR >= 64) {
gen_check_privilege(dc); gen_check_privilege(dc);
} }
gen_window_check1(dc, RRR_T); gen_window_check1(dc, RRR_T);
gen_wsr(dc, RSR_SR, cpu_R[RRR_T]); gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
if (!sregnames[RSR_SR]) {
TBD();
}
break; break;
case 2: /*SEXTu*/ case 2: /*SEXTu*/
...@@ -1807,7 +1829,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) ...@@ -1807,7 +1829,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
gen_window_check1(dc, RRR_R); gen_window_check1(dc, RRR_R);
{ {
int st = (RRR_S << 4) + RRR_T; int st = (RRR_S << 4) + RRR_T;
if (uregnames[st]) { if (uregnames[st].name) {
tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]); tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
} else { } else {
qemu_log("RUR %d not implemented, ", st); qemu_log("RUR %d not implemented, ", st);
...@@ -1818,7 +1840,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) ...@@ -1818,7 +1840,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
case 15: /*WUR*/ case 15: /*WUR*/
gen_window_check1(dc, RRR_T); gen_window_check1(dc, RRR_T);
if (uregnames[RSR_SR]) { if (uregnames[RSR_SR].name) {
gen_wur(RSR_SR, cpu_R[RRR_T]); gen_wur(RSR_SR, cpu_R[RRR_T]);
} else { } else {
qemu_log("WUR %d not implemented, ", RSR_SR); qemu_log("WUR %d not implemented, ", RSR_SR);
...@@ -3000,8 +3022,8 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf, ...@@ -3000,8 +3022,8 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, "PC=%08x\n\n", env->pc); cpu_fprintf(f, "PC=%08x\n\n", env->pc);
for (i = j = 0; i < 256; ++i) { for (i = j = 0; i < 256; ++i) {
if (sregnames[i]) { if (xtensa_option_bits_enabled(env->config, sregnames[i].opt_bits)) {
cpu_fprintf(f, "%s=%08x%c", sregnames[i], env->sregs[i], cpu_fprintf(f, "%12s=%08x%c", sregnames[i].name, env->sregs[i],
(j++ % 4) == 3 ? '\n' : ' '); (j++ % 4) == 3 ? '\n' : ' ');
} }
} }
...@@ -3009,8 +3031,8 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf, ...@@ -3009,8 +3031,8 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n"); cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
for (i = j = 0; i < 256; ++i) { for (i = j = 0; i < 256; ++i) {
if (uregnames[i]) { if (xtensa_option_bits_enabled(env->config, uregnames[i].opt_bits)) {
cpu_fprintf(f, "%s=%08x%c", uregnames[i], env->uregs[i], cpu_fprintf(f, "%s=%08x%c", uregnames[i].name, env->uregs[i],
(j++ % 4) == 3 ? '\n' : ' '); (j++ % 4) == 3 ? '\n' : ' ');
} }
} }
...@@ -3018,7 +3040,7 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf, ...@@ -3018,7 +3040,7 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n"); cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
for (i = 0; i < 16; ++i) { for (i = 0; i < 16; ++i) {
cpu_fprintf(f, "A%02d=%08x%c", i, env->regs[i], cpu_fprintf(f, " A%02d=%08x%c", i, env->regs[i],
(i % 4) == 3 ? '\n' : ' '); (i % 4) == 3 ? '\n' : ' ');
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册