summaryrefslogtreecommitdiff
path: root/target/nios2
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-04-21 08:16:53 -0700
committerRichard Henderson <richard.henderson@linaro.org>2022-04-26 08:16:41 -0700
commitb8f036a9fab6266828546dd127c5535bd535fcda (patch)
tree3fda574f9c5d7a0ba80b30da98ca57d9813d68ee /target/nios2
parente237ac34db57078f8c8c167ea24acee71394dc2a (diff)
target/nios2: Split control registers away from general registers
Place the control registers into their own array, env->ctrl[]. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220421151735.31996-23-richard.henderson@linaro.org>
Diffstat (limited to 'target/nios2')
-rw-r--r--target/nios2/cpu.c19
-rw-r--r--target/nios2/cpu.h43
-rw-r--r--target/nios2/helper.c106
-rw-r--r--target/nios2/mmu.c26
-rw-r--r--target/nios2/op_helper.c2
-rw-r--r--target/nios2/translate.c35
6 files changed, 118 insertions, 113 deletions
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index dc1551241e..fce16a2e77 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -48,14 +48,15 @@ static void nios2_cpu_reset(DeviceState *dev)
ncc->parent_reset(dev);
- memset(env->regs, 0, sizeof(uint32_t) * NUM_CORE_REGS);
+ memset(env->regs, 0, sizeof(env->regs));
+ memset(env->ctrl, 0, sizeof(env->ctrl));
env->pc = cpu->reset_addr;
#if defined(CONFIG_USER_ONLY)
/* Start in user mode with interrupts enabled. */
- env->regs[CR_STATUS] = CR_STATUS_U | CR_STATUS_PIE;
+ env->ctrl[CR_STATUS] = CR_STATUS_U | CR_STATUS_PIE;
#else
- env->regs[CR_STATUS] = 0;
+ env->ctrl[CR_STATUS] = 0;
#endif
}
@@ -66,9 +67,9 @@ static void nios2_cpu_set_irq(void *opaque, int irq, int level)
CPUNios2State *env = &cpu->env;
CPUState *cs = CPU(cpu);
- env->regs[CR_IPENDING] = deposit32(env->regs[CR_IPENDING], irq, 1, !!level);
+ env->ctrl[CR_IPENDING] = deposit32(env->ctrl[CR_IPENDING], irq, 1, !!level);
- if (env->regs[CR_IPENDING]) {
+ if (env->ctrl[CR_IPENDING]) {
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
} else {
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
@@ -126,8 +127,8 @@ static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
CPUNios2State *env = &cpu->env;
if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->regs[CR_STATUS] & CR_STATUS_PIE) &&
- (env->regs[CR_IPENDING] & env->regs[CR_IENABLE])) {
+ (env->ctrl[CR_STATUS] & CR_STATUS_PIE) &&
+ (env->ctrl[CR_IPENDING] & env->ctrl[CR_IENABLE])) {
cs->exception_index = EXCP_IRQ;
nios2_cpu_do_interrupt(cs);
return true;
@@ -158,7 +159,7 @@ static int nios2_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
} else if (n == 32) { /* PC */
return gdb_get_reg32(mem_buf, env->pc);
} else if (n < 49) { /* Status regs */
- return gdb_get_reg32(mem_buf, env->regs[n - 1]);
+ return gdb_get_reg32(mem_buf, env->ctrl[n - 33]);
}
/* Invalid regs */
@@ -180,7 +181,7 @@ static int nios2_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
} else if (n == 32) { /* PC */
env->pc = ldl_p(mem_buf);
} else if (n < 49) { /* Status regs */
- env->regs[n - 1] = ldl_p(mem_buf);
+ env->ctrl[n - 33] = ldl_p(mem_buf);
}
return 4;
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index 6bd8367eb8..68ff8033b6 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -59,9 +59,6 @@ struct Nios2CPUClass {
#define NUM_GP_REGS 32
#define NUM_CR_REGS 32
-/* GP regs + CR regs */
-#define NUM_CORE_REGS (NUM_GP_REGS + NUM_CR_REGS)
-
/* General purpose register aliases */
#define R_ZERO 0
#define R_AT 1
@@ -81,8 +78,7 @@ struct Nios2CPUClass {
#define R_RA 31
/* Control register aliases */
-#define CR_BASE NUM_GP_REGS
-#define CR_STATUS (CR_BASE + 0)
+#define CR_STATUS 0
#define CR_STATUS_PIE (1 << 0)
#define CR_STATUS_U (1 << 1)
#define CR_STATUS_EH (1 << 2)
@@ -92,19 +88,19 @@ struct Nios2CPUClass {
#define CR_STATUS_PRS (63 << 16)
#define CR_STATUS_NMI (1 << 22)
#define CR_STATUS_RSIE (1 << 23)
-#define CR_ESTATUS (CR_BASE + 1)
-#define CR_BSTATUS (CR_BASE + 2)
-#define CR_IENABLE (CR_BASE + 3)
-#define CR_IPENDING (CR_BASE + 4)
-#define CR_CPUID (CR_BASE + 5)
-#define CR_CTL6 (CR_BASE + 6)
-#define CR_EXCEPTION (CR_BASE + 7)
-#define CR_PTEADDR (CR_BASE + 8)
+#define CR_ESTATUS 1
+#define CR_BSTATUS 2
+#define CR_IENABLE 3
+#define CR_IPENDING 4
+#define CR_CPUID 5
+#define CR_CTL6 6
+#define CR_EXCEPTION 7
+#define CR_PTEADDR 8
#define CR_PTEADDR_PTBASE_SHIFT 22
#define CR_PTEADDR_PTBASE_MASK (0x3FF << CR_PTEADDR_PTBASE_SHIFT)
#define CR_PTEADDR_VPN_SHIFT 2
#define CR_PTEADDR_VPN_MASK (0xFFFFF << CR_PTEADDR_VPN_SHIFT)
-#define CR_TLBACC (CR_BASE + 9)
+#define CR_TLBACC 9
#define CR_TLBACC_IGN_SHIFT 25
#define CR_TLBACC_IGN_MASK (0x7F << CR_TLBACC_IGN_SHIFT)
#define CR_TLBACC_C (1 << 24)
@@ -113,7 +109,7 @@ struct Nios2CPUClass {
#define CR_TLBACC_X (1 << 21)
#define CR_TLBACC_G (1 << 20)
#define CR_TLBACC_PFN_MASK 0x000FFFFF
-#define CR_TLBMISC (CR_BASE + 10)
+#define CR_TLBMISC 10
#define CR_TLBMISC_WAY_SHIFT 20
#define CR_TLBMISC_WAY_MASK (0xF << CR_TLBMISC_WAY_SHIFT)
#define CR_TLBMISC_RD (1 << 19)
@@ -124,11 +120,11 @@ struct Nios2CPUClass {
#define CR_TLBMISC_BAD (1 << 2)
#define CR_TLBMISC_PERM (1 << 1)
#define CR_TLBMISC_D (1 << 0)
-#define CR_ENCINJ (CR_BASE + 11)
-#define CR_BADADDR (CR_BASE + 12)
-#define CR_CONFIG (CR_BASE + 13)
-#define CR_MPUBASE (CR_BASE + 14)
-#define CR_MPUACC (CR_BASE + 15)
+#define CR_ENCINJ 11
+#define CR_BADADDR 12
+#define CR_CONFIG 13
+#define CR_MPUBASE 14
+#define CR_MPUACC 15
/* Exceptions */
#define EXCP_BREAK 0x1000
@@ -154,7 +150,8 @@ struct Nios2CPUClass {
#define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_3
struct CPUArchState {
- uint32_t regs[NUM_CORE_REGS];
+ uint32_t regs[NUM_GP_REGS];
+ uint32_t ctrl[NUM_CR_REGS];
uint32_t pc;
#if !defined(CONFIG_USER_ONLY)
@@ -212,7 +209,7 @@ void do_nios2_semihosting(CPUNios2State *env);
static inline int cpu_mmu_index(CPUNios2State *env, bool ifetch)
{
- return (env->regs[CR_STATUS] & CR_STATUS_U) ? MMU_USER_IDX :
+ return (env->ctrl[CR_STATUS] & CR_STATUS_U) ? MMU_USER_IDX :
MMU_SUPERVISOR_IDX;
}
@@ -232,7 +229,7 @@ static inline void cpu_get_tb_cpu_state(CPUNios2State *env, target_ulong *pc,
{
*pc = env->pc;
*cs_base = 0;
- *flags = (env->regs[CR_STATUS] & (CR_STATUS_EH | CR_STATUS_U));
+ *flags = env->ctrl[CR_STATUS] & (CR_STATUS_EH | CR_STATUS_U);
}
#endif /* NIOS2_CPU_H */
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index 34b3e18e37..2e5f5b8b54 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -36,38 +36,38 @@ void nios2_cpu_do_interrupt(CPUState *cs)
switch (cs->exception_index) {
case EXCP_IRQ:
- assert(env->regs[CR_STATUS] & CR_STATUS_PIE);
+ assert(env->ctrl[CR_STATUS] & CR_STATUS_PIE);
qemu_log_mask(CPU_LOG_INT, "interrupt at pc=%x\n", env->pc);
- env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
- env->regs[CR_STATUS] |= CR_STATUS_IH;
- env->regs[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
+ env->ctrl[CR_ESTATUS] = env->ctrl[CR_STATUS];
+ env->ctrl[CR_STATUS] |= CR_STATUS_IH;
+ env->ctrl[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
- env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
- env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+ env->ctrl[CR_EXCEPTION] &= ~(0x1F << 2);
+ env->ctrl[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
env->regs[R_EA] = env->pc + 4;
env->pc = cpu->exception_addr;
break;
case EXCP_TLBD:
- if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
+ if ((env->ctrl[CR_STATUS] & CR_STATUS_EH) == 0) {
qemu_log_mask(CPU_LOG_INT, "TLB MISS (fast) at pc=%x\n", env->pc);
/* Fast TLB miss */
/* Variation from the spec. Table 3-35 of the cpu reference shows
* estatus not being changed for TLB miss but this appears to
* be incorrect. */
- env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
- env->regs[CR_STATUS] |= CR_STATUS_EH;
- env->regs[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
+ env->ctrl[CR_ESTATUS] = env->ctrl[CR_STATUS];
+ env->ctrl[CR_STATUS] |= CR_STATUS_EH;
+ env->ctrl[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
- env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
- env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+ env->ctrl[CR_EXCEPTION] &= ~(0x1F << 2);
+ env->ctrl[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
- env->regs[CR_TLBMISC] &= ~CR_TLBMISC_DBL;
- env->regs[CR_TLBMISC] |= CR_TLBMISC_WR;
+ env->ctrl[CR_TLBMISC] &= ~CR_TLBMISC_DBL;
+ env->ctrl[CR_TLBMISC] |= CR_TLBMISC_WR;
env->regs[R_EA] = env->pc + 4;
env->pc = cpu->fast_tlb_miss_addr;
@@ -75,13 +75,13 @@ void nios2_cpu_do_interrupt(CPUState *cs)
qemu_log_mask(CPU_LOG_INT, "TLB MISS (double) at pc=%x\n", env->pc);
/* Double TLB miss */
- env->regs[CR_STATUS] |= CR_STATUS_EH;
- env->regs[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
+ env->ctrl[CR_STATUS] |= CR_STATUS_EH;
+ env->ctrl[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
- env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
- env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+ env->ctrl[CR_EXCEPTION] &= ~(0x1F << 2);
+ env->ctrl[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
- env->regs[CR_TLBMISC] |= CR_TLBMISC_DBL;
+ env->ctrl[CR_TLBMISC] |= CR_TLBMISC_DBL;
env->pc = cpu->exception_addr;
}
@@ -92,15 +92,15 @@ void nios2_cpu_do_interrupt(CPUState *cs)
case EXCP_TLBX:
qemu_log_mask(CPU_LOG_INT, "TLB PERM at pc=%x\n", env->pc);
- env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
- env->regs[CR_STATUS] |= CR_STATUS_EH;
- env->regs[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
+ env->ctrl[CR_ESTATUS] = env->ctrl[CR_STATUS];
+ env->ctrl[CR_STATUS] |= CR_STATUS_EH;
+ env->ctrl[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
- env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
- env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+ env->ctrl[CR_EXCEPTION] &= ~(0x1F << 2);
+ env->ctrl[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
- if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
- env->regs[CR_TLBMISC] |= CR_TLBMISC_WR;
+ if ((env->ctrl[CR_STATUS] & CR_STATUS_EH) == 0) {
+ env->ctrl[CR_TLBMISC] |= CR_TLBMISC_WR;
}
env->regs[R_EA] = env->pc + 4;
@@ -112,16 +112,16 @@ void nios2_cpu_do_interrupt(CPUState *cs)
case EXCP_SUPERD:
qemu_log_mask(CPU_LOG_INT, "SUPERVISOR exception at pc=%x\n", env->pc);
- if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
- env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
+ if ((env->ctrl[CR_STATUS] & CR_STATUS_EH) == 0) {
+ env->ctrl[CR_ESTATUS] = env->ctrl[CR_STATUS];
env->regs[R_EA] = env->pc + 4;
}
- env->regs[CR_STATUS] |= CR_STATUS_EH;
- env->regs[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
+ env->ctrl[CR_STATUS] |= CR_STATUS_EH;
+ env->ctrl[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
- env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
- env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+ env->ctrl[CR_EXCEPTION] &= ~(0x1F << 2);
+ env->ctrl[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
env->pc = cpu->exception_addr;
break;
@@ -130,16 +130,16 @@ void nios2_cpu_do_interrupt(CPUState *cs)
case EXCP_TRAP:
qemu_log_mask(CPU_LOG_INT, "TRAP exception at pc=%x\n", env->pc);
- if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
- env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
+ if ((env->ctrl[CR_STATUS] & CR_STATUS_EH) == 0) {
+ env->ctrl[CR_ESTATUS] = env->ctrl[CR_STATUS];
env->regs[R_EA] = env->pc + 4;
}
- env->regs[CR_STATUS] |= CR_STATUS_EH;
- env->regs[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
+ env->ctrl[CR_STATUS] |= CR_STATUS_EH;
+ env->ctrl[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
- env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
- env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+ env->ctrl[CR_EXCEPTION] &= ~(0x1F << 2);
+ env->ctrl[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
env->pc = cpu->exception_addr;
break;
@@ -155,16 +155,16 @@ void nios2_cpu_do_interrupt(CPUState *cs)
break;
}
- if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
- env->regs[CR_BSTATUS] = env->regs[CR_STATUS];
+ if ((env->ctrl[CR_STATUS] & CR_STATUS_EH) == 0) {
+ env->ctrl[CR_BSTATUS] = env->ctrl[CR_STATUS];
env->regs[R_BA] = env->pc + 4;
}
- env->regs[CR_STATUS] |= CR_STATUS_EH;
- env->regs[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
+ env->ctrl[CR_STATUS] |= CR_STATUS_EH;
+ env->ctrl[CR_STATUS] &= ~(CR_STATUS_PIE | CR_STATUS_U);
- env->regs[CR_EXCEPTION] &= ~(0x1F << 2);
- env->regs[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
+ env->ctrl[CR_EXCEPTION] &= ~(0x1F << 2);
+ env->ctrl[CR_EXCEPTION] |= (cs->exception_index & 0x1F) << 2;
env->pc = cpu->exception_addr;
break;
@@ -207,8 +207,8 @@ void nios2_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
Nios2CPU *cpu = NIOS2_CPU(cs);
CPUNios2State *env = &cpu->env;
- env->regs[CR_BADADDR] = addr;
- env->regs[CR_EXCEPTION] = EXCP_UNALIGN << 2;
+ env->ctrl[CR_BADADDR] = addr;
+ env->ctrl[CR_EXCEPTION] = EXCP_UNALIGN << 2;
helper_raise_exception(env, EXCP_UNALIGN);
}
@@ -246,7 +246,7 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
return false;
}
cs->exception_index = EXCP_SUPERA;
- env->regs[CR_BADADDR] = address;
+ env->ctrl[CR_BADADDR] = address;
cpu_loop_exit_restore(cs, retaddr);
}
}
@@ -275,15 +275,15 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
}
if (access_type == MMU_INST_FETCH) {
- env->regs[CR_TLBMISC] &= ~CR_TLBMISC_D;
+ env->ctrl[CR_TLBMISC] &= ~CR_TLBMISC_D;
} else {
- env->regs[CR_TLBMISC] |= CR_TLBMISC_D;
+ env->ctrl[CR_TLBMISC] |= CR_TLBMISC_D;
}
- env->regs[CR_PTEADDR] &= CR_PTEADDR_PTBASE_MASK;
- env->regs[CR_PTEADDR] |= (address >> 10) & CR_PTEADDR_VPN_MASK;
- env->mmu.pteaddr_wr = env->regs[CR_PTEADDR];
+ env->ctrl[CR_PTEADDR] &= CR_PTEADDR_PTBASE_MASK;
+ env->ctrl[CR_PTEADDR] |= (address >> 10) & CR_PTEADDR_VPN_MASK;
+ env->mmu.pteaddr_wr = env->ctrl[CR_PTEADDR];
cs->exception_index = excp;
- env->regs[CR_BADADDR] = address;
+ env->ctrl[CR_BADADDR] = address;
cpu_loop_exit_restore(cs, retaddr);
}
diff --git a/target/nios2/mmu.c b/target/nios2/mmu.c
index 4daab2a7ab..95900724e8 100644
--- a/target/nios2/mmu.c
+++ b/target/nios2/mmu.c
@@ -95,8 +95,8 @@ void helper_mmu_write_tlbacc(CPUNios2State *env, uint32_t v)
v & CR_TLBACC_PFN_MASK);
/* if tlbmisc.WE == 1 then trigger a TLB write on writes to TLBACC */
- if (env->regs[CR_TLBMISC] & CR_TLBMISC_WR) {
- int way = (env->regs[CR_TLBMISC] >> CR_TLBMISC_WAY_SHIFT);
+ if (env->ctrl[CR_TLBMISC] & CR_TLBMISC_WR) {
+ int way = (env->ctrl[CR_TLBMISC] >> CR_TLBMISC_WAY_SHIFT);
int vpn = (env->mmu.pteaddr_wr & CR_PTEADDR_VPN_MASK) >> 2;
int pid = (env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK) >> 4;
int g = (v & CR_TLBACC_G) ? 1 : 0;
@@ -117,8 +117,8 @@ void helper_mmu_write_tlbacc(CPUNios2State *env, uint32_t v)
entry->data = newData;
}
/* Auto-increment tlbmisc.WAY */
- env->regs[CR_TLBMISC] =
- (env->regs[CR_TLBMISC] & ~CR_TLBMISC_WAY_MASK) |
+ env->ctrl[CR_TLBMISC] =
+ (env->ctrl[CR_TLBMISC] & ~CR_TLBMISC_WAY_MASK) |
(((way + 1) & (cpu->tlb_num_ways - 1)) <<
CR_TLBMISC_WAY_SHIFT);
}
@@ -153,17 +153,17 @@ void helper_mmu_write_tlbmisc(CPUNios2State *env, uint32_t v)
&env->mmu.tlb[(way * cpu->tlb_num_ways) +
(vpn & env->mmu.tlb_entry_mask)];
- env->regs[CR_TLBACC] &= CR_TLBACC_IGN_MASK;
- env->regs[CR_TLBACC] |= entry->data;
- env->regs[CR_TLBACC] |= (entry->tag & (1 << 11)) ? CR_TLBACC_G : 0;
- env->regs[CR_TLBMISC] =
+ env->ctrl[CR_TLBACC] &= CR_TLBACC_IGN_MASK;
+ env->ctrl[CR_TLBACC] |= entry->data;
+ env->ctrl[CR_TLBACC] |= (entry->tag & (1 << 11)) ? CR_TLBACC_G : 0;
+ env->ctrl[CR_TLBMISC] =
(v & ~CR_TLBMISC_PID_MASK) |
((entry->tag & ((1 << cpu->pid_num_bits) - 1)) <<
CR_TLBMISC_PID_SHIFT);
- env->regs[CR_PTEADDR] &= ~CR_PTEADDR_VPN_MASK;
- env->regs[CR_PTEADDR] |= (entry->tag >> 12) << CR_PTEADDR_VPN_SHIFT;
+ env->ctrl[CR_PTEADDR] &= ~CR_PTEADDR_VPN_MASK;
+ env->ctrl[CR_PTEADDR] |= (entry->tag >> 12) << CR_PTEADDR_VPN_SHIFT;
} else {
- env->regs[CR_TLBMISC] = v;
+ env->ctrl[CR_TLBMISC] = v;
}
env->mmu.tlbmisc_wr = v;
@@ -175,8 +175,8 @@ void helper_mmu_write_pteaddr(CPUNios2State *env, uint32_t v)
(v & CR_PTEADDR_VPN_MASK) >> CR_PTEADDR_VPN_SHIFT);
/* Writes to PTEADDR don't change the read-back VPN value */
- env->regs[CR_PTEADDR] = (v & ~CR_PTEADDR_VPN_MASK) |
- (env->regs[CR_PTEADDR] & CR_PTEADDR_VPN_MASK);
+ env->ctrl[CR_PTEADDR] = ((v & ~CR_PTEADDR_VPN_MASK) |
+ (env->ctrl[CR_PTEADDR] & CR_PTEADDR_VPN_MASK));
env->mmu.pteaddr_wr = v;
}
diff --git a/target/nios2/op_helper.c b/target/nios2/op_helper.c
index ee5ad8b23f..08ed3b4598 100644
--- a/target/nios2/op_helper.c
+++ b/target/nios2/op_helper.c
@@ -34,7 +34,7 @@ void helper_raise_exception(CPUNios2State *env, uint32_t index)
#ifndef CONFIG_USER_ONLY
void helper_eret(CPUNios2State *env, uint32_t new_status, uint32_t new_pc)
{
- env->regs[CR_STATUS] = new_status;
+ env->ctrl[CR_STATUS] = new_status;
env->pc = new_pc;
cpu_loop_exit(env_cpu(env));
}
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 6c739bfa5e..308da8057c 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -395,7 +395,7 @@ static void eret(DisasContext *dc, uint32_t code, uint32_t flags)
g_assert_not_reached();
#else
TCGv tmp = tcg_temp_new();
- tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUNios2State, regs[CR_ESTATUS]));
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUNios2State, ctrl[CR_ESTATUS]));
gen_helper_eret(cpu_env, tmp, cpu_R[R_EA]);
tcg_temp_free(tmp);
@@ -425,7 +425,7 @@ static void bret(DisasContext *dc, uint32_t code, uint32_t flags)
g_assert_not_reached();
#else
TCGv tmp = tcg_temp_new();
- tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUNios2State, regs[CR_BSTATUS]));
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUNios2State, ctrl[CR_BSTATUS]));
gen_helper_eret(cpu_env, tmp, cpu_R[R_BA]);
tcg_temp_free(tmp);
@@ -481,7 +481,7 @@ static void rdctl(DisasContext *dc, uint32_t code, uint32_t flags)
return;
}
- switch (instr.imm5 + CR_BASE) {
+ switch (instr.imm5) {
case CR_IPENDING:
/*
* The value of the ipending register is synthetic.
@@ -493,17 +493,15 @@ static void rdctl(DisasContext *dc, uint32_t code, uint32_t flags)
*/
t1 = tcg_temp_new();
t2 = tcg_temp_new();
- tcg_gen_ld_tl(t1, cpu_env,
- offsetof(CPUNios2State, regs[CR_IPENDING]));
- tcg_gen_ld_tl(t2, cpu_env,
- offsetof(CPUNios2State, regs[CR_IENABLE]));
+ tcg_gen_ld_tl(t1, cpu_env, offsetof(CPUNios2State, ctrl[CR_IPENDING]));
+ tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUNios2State, ctrl[CR_IENABLE]));
tcg_gen_and_tl(cpu_R[instr.c], t1, t2);
tcg_temp_free(t1);
tcg_temp_free(t2);
break;
default:
tcg_gen_ld_tl(cpu_R[instr.c], cpu_env,
- offsetof(CPUNios2State, regs[instr.imm5 + CR_BASE]));
+ offsetof(CPUNios2State, ctrl[instr.imm5]));
break;
}
}
@@ -521,7 +519,7 @@ static void wrctl(DisasContext *dc, uint32_t code, uint32_t flags)
R_TYPE(instr, code);
TCGv v = load_gpr(dc, instr.a);
- switch (instr.imm5 + CR_BASE) {
+ switch (instr.imm5) {
case CR_PTEADDR:
gen_helper_mmu_write_pteaddr(cpu_env, v);
break;
@@ -541,7 +539,7 @@ static void wrctl(DisasContext *dc, uint32_t code, uint32_t flags)
/* fall through */
default:
tcg_gen_st_tl(v, cpu_env,
- offsetof(CPUNios2State, regs[instr.imm5 + CR_BASE]));
+ offsetof(CPUNios2State, ctrl[instr.imm5]));
break;
}
#endif
@@ -774,7 +772,7 @@ illegal_op:
t_gen_helper_raise_exception(dc, EXCP_ILLEGAL);
}
-static const char * const regnames[NUM_CORE_REGS] = {
+static const char * const gr_regnames[NUM_GP_REGS] = {
"zero", "at", "r2", "r3",
"r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11",
@@ -783,6 +781,9 @@ static const char * const regnames[NUM_CORE_REGS] = {
"r20", "r21", "r22", "r23",
"et", "bt", "gp", "sp",
"fp", "ea", "ba", "ra",
+};
+
+static const char * const cr_regnames[NUM_CR_REGS] = {
"status", "estatus", "bstatus", "ienable",
"ipending", "cpuid", "reserved0", "exception",
"pteaddr", "tlbacc", "tlbmisc", "reserved1",
@@ -910,8 +911,14 @@ void nios2_cpu_dump_state(CPUState *cs, FILE *f, int flags)
qemu_fprintf(f, "IN: PC=%x %s\n", env->pc, lookup_symbol(env->pc));
- for (i = 0; i < NUM_CORE_REGS; i++) {
- qemu_fprintf(f, "%9s=%8.8x ", regnames[i], env->regs[i]);
+ for (i = 0; i < NUM_GP_REGS; i++) {
+ qemu_fprintf(f, "%9s=%8.8x ", gr_regnames[i], env->regs[i]);
+ if ((i + 1) % 4 == 0) {
+ qemu_fprintf(f, "\n");
+ }
+ }
+ for (i = 0; i < NUM_CR_REGS; i++) {
+ qemu_fprintf(f, "%9s=%8.8x ", cr_regnames[i], env->ctrl[i]);
if ((i + 1) % 4 == 0) {
qemu_fprintf(f, "\n");
}
@@ -932,7 +939,7 @@ void nios2_tcg_init(void)
for (i = 0; i < NUM_GP_REGS; i++) {
cpu_R[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUNios2State, regs[i]),
- regnames[i]);
+ gr_regnames[i]);
}
cpu_pc = tcg_global_mem_new(cpu_env,
offsetof(CPUNios2State, pc), "pc");