diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-06-26 20:28:10 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-07-07 16:25:44 +0900 |
commit | a15119db2ff5c2fdfdeb913b297bf8aa3399132e (patch) | |
tree | 7d6f779408bb772b11c029ab88000fc01856b599 /target-openrisc | |
parent | 340f06c9eaee097e626c251bf7a013350649c091 (diff) | |
download | qemu-a15119db2ff5c2fdfdeb913b297bf8aa3399132e.tar.gz qemu-a15119db2ff5c2fdfdeb913b297bf8aa3399132e.tar.bz2 qemu-a15119db2ff5c2fdfdeb913b297bf8aa3399132e.zip |
Imported Upstream version 2.0.0upstream/2.0.0
Change-Id: I081766c4314e7893f54fec80b920b1638d15021f
Diffstat (limited to 'target-openrisc')
-rw-r--r-- | target-openrisc/cpu.c | 35 | ||||
-rw-r--r-- | target-openrisc/cpu.h | 13 | ||||
-rw-r--r-- | target-openrisc/exception.c | 6 | ||||
-rw-r--r-- | target-openrisc/interrupt.c | 37 | ||||
-rw-r--r-- | target-openrisc/interrupt_helper.c | 2 | ||||
-rw-r--r-- | target-openrisc/mmu.c | 30 | ||||
-rw-r--r-- | target-openrisc/mmu_helper.c | 8 | ||||
-rw-r--r-- | target-openrisc/sys_helper.c | 60 | ||||
-rw-r--r-- | target-openrisc/translate.c | 205 |
9 files changed, 175 insertions, 221 deletions
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index 075f00a89..08e724c12 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -27,6 +27,12 @@ static void openrisc_cpu_set_pc(CPUState *cs, vaddr value) cpu->env.pc = value; } +static bool openrisc_cpu_has_work(CPUState *cs) +{ + return cs->interrupt_request & (CPU_INTERRUPT_HARD | + CPU_INTERRUPT_TIMER); +} + /* CPUClass::reset() */ static void openrisc_cpu_reset(CPUState *s) { @@ -35,14 +41,18 @@ static void openrisc_cpu_reset(CPUState *s) occ->parent_reset(s); - memset(&cpu->env, 0, offsetof(CPUOpenRISCState, breakpoints)); +#ifndef CONFIG_USER_ONLY + memset(&cpu->env, 0, offsetof(CPUOpenRISCState, tlb)); +#else + memset(&cpu->env, 0, offsetof(CPUOpenRISCState, irq)); +#endif - tlb_flush(&cpu->env, 1); + tlb_flush(s, 1); /*tb_flush(&cpu->env); FIXME: Do we need it? */ cpu->env.pc = 0x100; cpu->env.sr = SR_FO | SR_SM; - cpu->env.exception_index = -1; + s->exception_index = -1; cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP; cpu->env.cpucfgr = CPUCFGR_OB32S | CPUCFGR_OF32S; @@ -153,12 +163,15 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data) cc->reset = openrisc_cpu_reset; cc->class_by_name = openrisc_cpu_class_by_name; + cc->has_work = openrisc_cpu_has_work; cc->do_interrupt = openrisc_cpu_do_interrupt; cc->dump_state = openrisc_cpu_dump_state; cc->set_pc = openrisc_cpu_set_pc; cc->gdb_read_register = openrisc_cpu_gdb_read_register; cc->gdb_write_register = openrisc_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = openrisc_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug; dc->vmsd = &vmstate_openrisc_cpu; #endif @@ -201,19 +214,7 @@ static void openrisc_cpu_register_types(void) OpenRISCCPU *cpu_openrisc_init(const char *cpu_model) { - OpenRISCCPU *cpu; - ObjectClass *oc; - - oc = openrisc_cpu_class_by_name(cpu_model); - if (oc == NULL) { - return NULL; - } - cpu = OPENRISC_CPU(object_new(object_class_get_name(oc))); - cpu->env.cpu_model_str = cpu_model; - - object_property_set_bool(OBJECT(cpu), true, "realized", NULL); - - return cpu; + return OPENRISC_CPU(cpu_generic_init(TYPE_OPENRISC_CPU, cpu_model)); } /* Sort alphabetically by type name, except for "any". */ diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 8fd0bc0bf..4512f459b 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -304,10 +304,11 @@ typedef struct CPUOpenRISCState { CPU_COMMON + /* Fields from here on are preserved across CPU reset. */ #ifndef CONFIG_USER_ONLY CPUOpenRISCTLBContext * tlb; - struct QEMUTimer *timer; + QEMUTimer *timer; uint32_t ttmr; /* Timer tick mode register */ uint32_t ttcr; /* Timer tick count register */ @@ -353,15 +354,13 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); int openrisc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void openrisc_translate_init(void); -int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, - target_ulong address, +int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc); #define cpu_list cpu_openrisc_list #define cpu_exec cpu_openrisc_exec #define cpu_gen_code cpu_openrisc_gen_code -#define cpu_handle_mmu_fault cpu_openrisc_handle_mmu_fault #define cpu_signal_handler cpu_openrisc_signal_handler #ifndef CONFIG_USER_ONLY @@ -373,6 +372,7 @@ void cpu_openrisc_pic_init(OpenRISCCPU *cpu); /* hw/openrisc_timer.c */ void cpu_openrisc_clock_init(OpenRISCCPU *cpu); void cpu_openrisc_count_update(OpenRISCCPU *cpu); +void cpu_openrisc_timer_update(OpenRISCCPU *cpu); void cpu_openrisc_count_start(OpenRISCCPU *cpu); void cpu_openrisc_count_stop(OpenRISCCPU *cpu); @@ -418,11 +418,6 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env) } #define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_INT_0 -static inline bool cpu_has_work(CPUState *cpu) -{ - return cpu->interrupt_request & (CPU_INTERRUPT_HARD | - CPU_INTERRUPT_TIMER); -} #include "exec/exec-all.h" diff --git a/target-openrisc/exception.c b/target-openrisc/exception.c index 58e53c6c9..74652a58f 100644 --- a/target-openrisc/exception.c +++ b/target-openrisc/exception.c @@ -22,6 +22,8 @@ void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp) { - cpu->env.exception_index = excp; - cpu_loop_exit(&cpu->env); + CPUState *cs = CPU(cpu); + + cs->exception_index = excp; + cpu_loop_exit(cs); } diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c index 16ef4b3e7..3de567eee 100644 --- a/target-openrisc/interrupt.c +++ b/target-openrisc/interrupt.c @@ -27,34 +27,23 @@ void openrisc_cpu_do_interrupt(CPUState *cs) { +#ifndef CONFIG_USER_ONLY OpenRISCCPU *cpu = OPENRISC_CPU(cs); CPUOpenRISCState *env = &cpu->env; -#ifndef CONFIG_USER_ONLY - if (env->flags & D_FLAG) { /* Delay Slot insn */ + + env->epcr = env->pc; + if (env->flags & D_FLAG) { env->flags &= ~D_FLAG; env->sr |= SR_DSX; - if (env->exception_index == EXCP_TICK || - env->exception_index == EXCP_INT || - env->exception_index == EXCP_SYSCALL || - env->exception_index == EXCP_FPE) { - env->epcr = env->jmp_pc; - } else { - env->epcr = env->pc - 4; - } - } else { - if (env->exception_index == EXCP_TICK || - env->exception_index == EXCP_INT || - env->exception_index == EXCP_SYSCALL || - env->exception_index == EXCP_FPE) { - env->epcr = env->npc; - } else { - env->epcr = env->pc; - } + env->epcr -= 4; + } + if (cs->exception_index == EXCP_SYSCALL) { + env->epcr += 4; } /* For machine-state changed between user-mode and supervisor mode, we need flush TLB when we enter&exit EXCP. */ - tlb_flush(env, 1); + tlb_flush(cs, 1); env->esr = env->sr; env->sr &= ~SR_DME; @@ -65,12 +54,12 @@ void openrisc_cpu_do_interrupt(CPUState *cs) env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu; env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu; - if (env->exception_index > 0 && env->exception_index < EXCP_NR) { - env->pc = (env->exception_index << 8); + if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) { + env->pc = (cs->exception_index << 8); } else { - cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index); + cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); } #endif - env->exception_index = -1; + cs->exception_index = -1; } diff --git a/target-openrisc/interrupt_helper.c b/target-openrisc/interrupt_helper.c index 844648f78..819405701 100644 --- a/target-openrisc/interrupt_helper.c +++ b/target-openrisc/interrupt_helper.c @@ -51,7 +51,7 @@ void HELPER(rfe)(CPUOpenRISCState *env) } if (need_flush_tlb) { - tlb_flush(&cpu->env, 1); + tlb_flush(cs, 1); } #endif cs->interrupt_request |= CPU_INTERRUPT_EXITTB; diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c index 57f5616e9..750a93636 100644 --- a/target-openrisc/mmu.c +++ b/target-openrisc/mmu.c @@ -32,7 +32,7 @@ int cpu_openrisc_get_phys_nommu(OpenRISCCPU *cpu, int *prot, target_ulong address, int rw) { *physical = address; - *prot = PAGE_READ | PAGE_WRITE; + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; return TLBRET_MATCH; } @@ -102,7 +102,7 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu, } } - if ((rw & 0) && ((right & PAGE_READ) == 0)) { + if (!(rw & 1) && ((right & PAGE_READ) == 0)) { return TLBRET_BADADDR; } if ((rw & 1) && ((right & PAGE_WRITE) == 0)) { @@ -122,13 +122,6 @@ static int cpu_openrisc_get_phys_addr(OpenRISCCPU *cpu, { int ret = TLBRET_MATCH; - /* [0x0000--0x2000]: unmapped */ - if (address < 0x2000 && (cpu->env.sr & SR_SM)) { - *physical = address; - *prot = PAGE_READ | PAGE_WRITE; - return ret; - } - if (rw == 2) { /* ITLB */ *physical = 0; ret = cpu->env.tlb->cpu_openrisc_map_address_code(cpu, physical, @@ -146,6 +139,7 @@ static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu, target_ulong address, int rw, int tlb_error) { + CPUState *cs = CPU(cpu); int exception = 0; switch (tlb_error) { @@ -176,25 +170,25 @@ static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu, #endif } - cpu->env.exception_index = exception; + cs->exception_index = exception; cpu->env.eear = address; } #ifndef CONFIG_USER_ONLY -int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, - target_ulong address, int rw, int mmu_idx) +int openrisc_cpu_handle_mmu_fault(CPUState *cs, + vaddr address, int rw, int mmu_idx) { + OpenRISCCPU *cpu = OPENRISC_CPU(cs); int ret = 0; hwaddr physical = 0; int prot = 0; - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); ret = cpu_openrisc_get_phys_addr(cpu, &physical, &prot, address, rw); if (ret == TLBRET_MATCH) { - tlb_set_page(env, address & TARGET_PAGE_MASK, - physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, + tlb_set_page(cs, address & TARGET_PAGE_MASK, + physical & TARGET_PAGE_MASK, prot, mmu_idx, TARGET_PAGE_SIZE); ret = 0; } else if (ret < 0) { @@ -205,11 +199,11 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, return ret; } #else -int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, - target_ulong address, int rw, int mmu_idx) +int openrisc_cpu_handle_mmu_fault(CPUState *cs, + vaddr address, int rw, int mmu_idx) { + OpenRISCCPU *cpu = OPENRISC_CPU(cs); int ret = 0; - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); cpu_openrisc_raise_mmu_exception(cpu, address, rw, ret); ret = 1; diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c index e46b09298..fb457c76a 100644 --- a/target-openrisc/mmu_helper.c +++ b/target-openrisc/mmu_helper.c @@ -36,20 +36,20 @@ #define SHIFT 3 #include "exec/softmmu_template.h" -void tlb_fill(CPUOpenRISCState *env, target_ulong addr, int is_write, +void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { int ret; - ret = cpu_openrisc_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = openrisc_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx); if (ret) { if (retaddr) { /* now we have a real cpu fault. */ - cpu_restore_state(env, retaddr); + cpu_restore_state(cs, retaddr); } /* Raise Exception. */ - cpu_loop_exit(env); + cpu_loop_exit(cs); } } #endif diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c index cccbc0e93..fedcbed4f 100644 --- a/target-openrisc/sys_helper.c +++ b/target-openrisc/sys_helper.c @@ -45,7 +45,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, case TO_SPR(0, 17): /* SR */ if ((env->sr & (SR_IME | SR_DME | SR_SM)) ^ (rb & (SR_IME | SR_DME | SR_SM))) { - tlb_flush(env, 1); + tlb_flush(cs, 1); } env->sr = rb; env->sr |= SR_FO; /* FO is const equal to 1 */ @@ -81,15 +81,15 @@ void HELPER(mtspr)(CPUOpenRISCState *env, case TO_SPR(0, 64): /* ESR */ env->esr = rb; break; - case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */ + case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */ idx = spr - TO_SPR(1, 512); if (!(rb & 1)) { - tlb_flush_page(env, env->tlb->dtlb[0][idx].mr & TARGET_PAGE_MASK); + tlb_flush_page(cs, env->tlb->dtlb[0][idx].mr & TARGET_PAGE_MASK); } env->tlb->dtlb[0][idx].mr = rb; break; - case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ + case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */ idx = spr - TO_SPR(1, 640); env->tlb->dtlb[0][idx].tr = rb; break; @@ -100,15 +100,15 @@ void HELPER(mtspr)(CPUOpenRISCState *env, case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */ case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */ break; - case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */ + case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1): /* ITLBW0MR 0-127 */ idx = spr - TO_SPR(2, 512); if (!(rb & 1)) { - tlb_flush_page(env, env->tlb->itlb[0][idx].mr & TARGET_PAGE_MASK); + tlb_flush_page(cs, env->tlb->itlb[0][idx].mr & TARGET_PAGE_MASK); } env->tlb->itlb[0][idx].mr = rb; break; - case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */ + case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */ idx = spr - TO_SPR(2, 640); env->tlb->itlb[0][idx].tr = rb; break; @@ -127,33 +127,31 @@ void HELPER(mtspr)(CPUOpenRISCState *env, break; case TO_SPR(10, 0): /* TTMR */ { + if ((env->ttmr & TTMR_M) ^ (rb & TTMR_M)) { + switch (rb & TTMR_M) { + case TIMER_NONE: + cpu_openrisc_count_stop(cpu); + break; + case TIMER_INTR: + case TIMER_SHOT: + case TIMER_CONT: + cpu_openrisc_count_start(cpu); + break; + default: + break; + } + } + int ip = env->ttmr & TTMR_IP; if (rb & TTMR_IP) { /* Keep IP bit. */ - env->ttmr = (rb & ~TTMR_IP) + ip; + env->ttmr = (rb & ~TTMR_IP) | ip; } else { /* Clear IP bit. */ env->ttmr = rb & ~TTMR_IP; cs->interrupt_request &= ~CPU_INTERRUPT_TIMER; } - cpu_openrisc_count_update(cpu); - - switch (env->ttmr & TTMR_M) { - case TIMER_NONE: - cpu_openrisc_count_stop(cpu); - break; - case TIMER_INTR: - cpu_openrisc_count_start(cpu); - break; - case TIMER_SHOT: - cpu_openrisc_count_start(cpu); - break; - case TIMER_CONT: - cpu_openrisc_count_start(cpu); - break; - default: - break; - } + cpu_openrisc_timer_update(cpu); } break; @@ -162,7 +160,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, if (env->ttmr & TIMER_NONE) { return; } - cpu_openrisc_count_start(cpu); + cpu_openrisc_timer_update(cpu); break; default: @@ -214,11 +212,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, case TO_SPR(0, 64): /* ESR */ return env->esr; - case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */ + case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */ idx = spr - TO_SPR(1, 512); return env->tlb->dtlb[0][idx].mr; - case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ + case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */ idx = spr - TO_SPR(1, 640); return env->tlb->dtlb[0][idx].tr; @@ -230,11 +228,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */ break; - case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */ + case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1): /* ITLBW0MR 0-127 */ idx = spr - TO_SPR(2, 512); return env->tlb->itlb[0][idx].mr; - case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */ + case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */ idx = spr - TO_SPR(2, 640); return env->tlb->itlb[0][idx].tr; diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index a6050ba6d..852b5e610 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -110,11 +110,9 @@ void openrisc_translate_init(void) offsetof(CPUOpenRISCState, gpr[i]), regnames[i]); } -#define GEN_HELPER 2 -#include "helper.h" } -/* Writeback SR_F transaltion-space to execution-space. */ +/* Writeback SR_F translation space to execution space. */ static inline void wb_SR_F(void) { int label; @@ -198,7 +196,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) likely(!dc->singlestep_enabled)) { tcg_gen_movi_tl(cpu_pc, dest); tcg_gen_goto_tb(n); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { tcg_gen_movi_tl(cpu_pc, dest); if (dc->singlestep_enabled) { @@ -211,42 +209,49 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0) { target_ulong tmp_pc; - int lab = gen_new_label(); - TCGv sr_f = tcg_temp_new(); /* N26, 26bits imm */ tmp_pc = sign_extend((imm<<2), 26) + dc->pc; - tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); - if (op0 == 0x00) { /* l.j */ + switch (op0) { + case 0x00: /* l.j */ tcg_gen_movi_tl(jmp_pc, tmp_pc); - } else if (op0 == 0x01) { /* l.jal */ + break; + case 0x01: /* l.jal */ tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8)); tcg_gen_movi_tl(jmp_pc, tmp_pc); - } else if (op0 == 0x03) { /* l.bnf */ - tcg_gen_movi_tl(jmp_pc, dc->pc+8); - tcg_gen_brcondi_i32(TCG_COND_EQ, sr_f, SR_F, lab); - tcg_gen_movi_tl(jmp_pc, tmp_pc); - gen_set_label(lab); - } else if (op0 == 0x04) { /* l.bf */ - tcg_gen_movi_tl(jmp_pc, dc->pc+8); - tcg_gen_brcondi_i32(TCG_COND_NE, sr_f, SR_F, lab); - tcg_gen_movi_tl(jmp_pc, tmp_pc); - gen_set_label(lab); - } else if (op0 == 0x11) { /* l.jr */ + break; + case 0x03: /* l.bnf */ + case 0x04: /* l.bf */ + { + int lab = gen_new_label(); + TCGv sr_f = tcg_temp_new(); + tcg_gen_movi_tl(jmp_pc, dc->pc+8); + tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); + tcg_gen_brcondi_i32(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE, + sr_f, SR_F, lab); + tcg_gen_movi_tl(jmp_pc, tmp_pc); + gen_set_label(lab); + tcg_temp_free(sr_f); + } + break; + case 0x11: /* l.jr */ tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); - } else if (op0 == 0x12) { /* l.jalr */ + break; + case 0x12: /* l.jalr */ tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8)); tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); - } else { + break; + default: gen_illegal_exception(dc); + break; } - tcg_temp_free(sr_f); dc->delayed_branch = 2; dc->tb_flags |= D_FLAG; gen_sync_flags(dc); } + static void dec_calc(DisasContext *dc, uint32_t insn) { uint32_t op0, op1, op2; @@ -702,6 +707,8 @@ static void dec_misc(DisasContext *dc, uint32_t insn) uint32_t L6, K5; #endif uint32_t I16, I5, I11, N26, tmp; + TCGMemOp mop; + op0 = extract32(insn, 26, 6); op1 = extract32(insn, 24, 2); ra = extract32(insn, 16, 5); @@ -833,72 +840,46 @@ static void dec_misc(DisasContext *dc, uint32_t insn) /*#ifdef TARGET_OPENRISC64 case 0x20: l.ld LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16); - { - check_ob64s(dc); - TCGv_i64 t0 = tcg_temp_new_i64(); - tcg_gen_addi_i64(t0, cpu_R[ra], sign_extend(I16, 16)); - tcg_gen_qemu_ld64(cpu_R[rd], t0, dc->mem_idx); - tcg_temp_free_i64(t0); - } - break; + check_ob64s(dc); + mop = MO_TEQ; + goto do_load; #endif*/ case 0x21: /* l.lwz */ LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16); - { - TCGv t0 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16)); - tcg_gen_qemu_ld32u(cpu_R[rd], t0, dc->mem_idx); - tcg_temp_free(t0); - } - break; + mop = MO_TEUL; + goto do_load; case 0x22: /* l.lws */ LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16); - { - TCGv t0 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16)); - tcg_gen_qemu_ld32s(cpu_R[rd], t0, dc->mem_idx); - tcg_temp_free(t0); - } - break; + mop = MO_TESL; + goto do_load; case 0x23: /* l.lbz */ LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16); - { - TCGv t0 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16)); - tcg_gen_qemu_ld8u(cpu_R[rd], t0, dc->mem_idx); - tcg_temp_free(t0); - } - break; + mop = MO_UB; + goto do_load; case 0x24: /* l.lbs */ LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16); - { - TCGv t0 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16)); - tcg_gen_qemu_ld8s(cpu_R[rd], t0, dc->mem_idx); - tcg_temp_free(t0); - } - break; + mop = MO_SB; + goto do_load; case 0x25: /* l.lhz */ LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16); - { - TCGv t0 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16)); - tcg_gen_qemu_ld16u(cpu_R[rd], t0, dc->mem_idx); - tcg_temp_free(t0); - } - break; + mop = MO_TEUW; + goto do_load; case 0x26: /* l.lhs */ LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16); + mop = MO_TESW; + goto do_load; + + do_load: { TCGv t0 = tcg_temp_new(); tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16)); - tcg_gen_qemu_ld16s(cpu_R[rd], t0, dc->mem_idx); + tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop); tcg_temp_free(t0); } break; @@ -906,29 +887,33 @@ static void dec_misc(DisasContext *dc, uint32_t insn) case 0x27: /* l.addi */ LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16); { - int lab = gen_new_label(); - TCGv_i64 ta = tcg_temp_new_i64(); - TCGv_i64 td = tcg_temp_local_new_i64(); - TCGv_i32 res = tcg_temp_local_new_i32(); - TCGv_i32 sr_ove = tcg_temp_local_new_i32(); - tcg_gen_extu_i32_i64(ta, cpu_R[ra]); - tcg_gen_addi_i64(td, ta, sign_extend(I16, 16)); - tcg_gen_trunc_i64_i32(res, td); - tcg_gen_shri_i64(td, td, 32); - tcg_gen_andi_i64(td, td, 0x3); - /* Jump to lab when no overflow. */ - tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); - tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); - tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); - tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); - tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); - gen_exception(dc, EXCP_RANGE); - gen_set_label(lab); - tcg_gen_mov_i32(cpu_R[rd], res); - tcg_temp_free_i64(ta); - tcg_temp_free_i64(td); - tcg_temp_free_i32(res); - tcg_temp_free_i32(sr_ove); + if (I16 == 0) { + tcg_gen_mov_tl(cpu_R[rd], cpu_R[ra]); + } else { + int lab = gen_new_label(); + TCGv_i64 ta = tcg_temp_new_i64(); + TCGv_i64 td = tcg_temp_local_new_i64(); + TCGv_i32 res = tcg_temp_local_new_i32(); + TCGv_i32 sr_ove = tcg_temp_local_new_i32(); + tcg_gen_extu_i32_i64(ta, cpu_R[ra]); + tcg_gen_addi_i64(td, ta, sign_extend(I16, 16)); + tcg_gen_trunc_i64_i32(res, td); + tcg_gen_shri_i64(td, td, 32); + tcg_gen_andi_i64(td, td, 0x3); + /* Jump to lab when no overflow. */ + tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); + tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); + tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); + tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); + tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); + gen_exception(dc, EXCP_RANGE); + gen_set_label(lab); + tcg_gen_mov_i32(cpu_R[rd], res); + tcg_temp_free_i64(ta); + tcg_temp_free_i64(td); + tcg_temp_free_i32(res); + tcg_temp_free_i32(sr_ove); + } } break; @@ -1033,42 +1018,31 @@ static void dec_misc(DisasContext *dc, uint32_t insn) /*#ifdef TARGET_OPENRISC64 case 0x34: l.sd LOG_DIS("l.sd %d, r%d, r%d, %d\n", I5, ra, rb, I11); - { - check_ob64s(dc); - TCGv_i64 t0 = tcg_temp_new_i64(); - tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16)); - tcg_gen_qemu_st64(cpu_R[rb], t0, dc->mem_idx); - tcg_temp_free_i64(t0); - } - break; + check_ob64s(dc); + mop = MO_TEQ; + goto do_store; #endif*/ case 0x35: /* l.sw */ LOG_DIS("l.sw %d, r%d, r%d, %d\n", I5, ra, rb, I11); - { - TCGv t0 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16)); - tcg_gen_qemu_st32(cpu_R[rb], t0, dc->mem_idx); - tcg_temp_free(t0); - } - break; + mop = MO_TEUL; + goto do_store; case 0x36: /* l.sb */ LOG_DIS("l.sb %d, r%d, r%d, %d\n", I5, ra, rb, I11); - { - TCGv t0 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16)); - tcg_gen_qemu_st8(cpu_R[rb], t0, dc->mem_idx); - tcg_temp_free(t0); - } - break; + mop = MO_UB; + goto do_store; case 0x37: /* l.sh */ LOG_DIS("l.sh %d, r%d, r%d, %d\n", I5, ra, rb, I11); + mop = MO_TEUW; + goto do_store; + + do_store: { TCGv t0 = tcg_temp_new(); tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16)); - tcg_gen_qemu_st16(cpu_R[rb], t0, dc->mem_idx); + tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop); tcg_temp_free(t0); } break; @@ -1645,10 +1619,11 @@ static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu) static void check_breakpoint(OpenRISCCPU *cpu, DisasContext *dc) { + CPUState *cs = CPU(cpu); CPUBreakpoint *bp; - if (unlikely(!QTAILQ_EMPTY(&cpu->env.breakpoints))) { - QTAILQ_FOREACH(bp, &cpu->env.breakpoints, entry) { + if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { + QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { if (bp->pc == dc->pc) { tcg_gen_movi_tl(cpu_pc, dc->pc); gen_exception(dc, EXCP_DEBUG); |