Merge remote-tracking branch 'jliu/or32' into staging
# By Sebastian Macke # Via Jia Liu * jliu/or32: target-openrisc: Correct carry flag check of l.addc and l.addic test cases target-openrisc: Correct memory bounds checking for the tlb buffers openrisc-timer: Reduce overhead, Separate clock update functions target-openrisc: Correct wrong epcr register in interrupt handler target-openrisc: Remove executable flag for every page target-openrisc: Remove unnecessary code generated by jump instructions target-openrisc: Speed up move instruction Message-id: 1384958318-9145-1-git-send-email-proljc@gmail.com Signed-off-by: Anthony Liguori <aliguori@amazon.com>
This commit is contained in:
		
						commit
						ffb62da7a2
					
				| @ -30,19 +30,28 @@ static int is_counting; | ||||
| 
 | ||||
| void cpu_openrisc_count_update(OpenRISCCPU *cpu) | ||||
| { | ||||
|     uint64_t now, next; | ||||
|     uint32_t wait; | ||||
|     uint64_t now; | ||||
| 
 | ||||
|     now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); | ||||
|     if (!is_counting) { | ||||
|         timer_del(cpu->env.timer); | ||||
|         last_clk = now; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); | ||||
|     cpu->env.ttcr += (uint32_t)muldiv64(now - last_clk, TIMER_FREQ, | ||||
|                                         get_ticks_per_sec()); | ||||
|     last_clk = now; | ||||
| } | ||||
| 
 | ||||
| void cpu_openrisc_timer_update(OpenRISCCPU *cpu) | ||||
| { | ||||
|     uint32_t wait; | ||||
|     uint64_t now, next; | ||||
| 
 | ||||
|     if (!is_counting) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     cpu_openrisc_count_update(cpu); | ||||
|     now = last_clk; | ||||
| 
 | ||||
|     if ((cpu->env.ttmr & TTMR_TP) <= (cpu->env.ttcr & TTMR_TP)) { | ||||
|         wait = TTMR_TP - (cpu->env.ttcr & TTMR_TP) + 1; | ||||
| @ -50,7 +59,6 @@ void cpu_openrisc_count_update(OpenRISCCPU *cpu) | ||||
|     } else { | ||||
|         wait = (cpu->env.ttmr & TTMR_TP) - (cpu->env.ttcr & TTMR_TP); | ||||
|     } | ||||
| 
 | ||||
|     next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ); | ||||
|     timer_mod(cpu->env.timer, next); | ||||
| } | ||||
| @ -63,8 +71,9 @@ void cpu_openrisc_count_start(OpenRISCCPU *cpu) | ||||
| 
 | ||||
| void cpu_openrisc_count_stop(OpenRISCCPU *cpu) | ||||
| { | ||||
|     is_counting = 0; | ||||
|     timer_del(cpu->env.timer); | ||||
|     cpu_openrisc_count_update(cpu); | ||||
|     is_counting = 0; | ||||
| } | ||||
| 
 | ||||
| static void openrisc_timer_cb(void *opaque) | ||||
| @ -84,15 +93,15 @@ static void openrisc_timer_cb(void *opaque) | ||||
|         break; | ||||
|     case TIMER_INTR: | ||||
|         cpu->env.ttcr = 0; | ||||
|         cpu_openrisc_count_start(cpu); | ||||
|         break; | ||||
|     case TIMER_SHOT: | ||||
|         cpu_openrisc_count_stop(cpu); | ||||
|         break; | ||||
|     case TIMER_CONT: | ||||
|         cpu_openrisc_count_start(cpu); | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     cpu_openrisc_timer_update(cpu); | ||||
| } | ||||
| 
 | ||||
| void cpu_openrisc_clock_init(OpenRISCCPU *cpu) | ||||
|  | ||||
| @ -373,6 +373,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); | ||||
| 
 | ||||
|  | ||||
| @ -30,26 +30,15 @@ void openrisc_cpu_do_interrupt(CPUState *cs) | ||||
|     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 (env->exception_index == EXCP_SYSCALL) { | ||||
|         env->epcr += 4; | ||||
|     } | ||||
| 
 | ||||
|     /* For machine-state changed between user-mode and supervisor mode,
 | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
| 
 | ||||
| @ -187,7 +187,7 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, | ||||
| 
 | ||||
|     if (ret == TLBRET_MATCH) { | ||||
|         tlb_set_page(env, address & TARGET_PAGE_MASK, | ||||
|                      physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, | ||||
|                      physical & TARGET_PAGE_MASK, prot, | ||||
|                      mmu_idx, TARGET_PAGE_SIZE); | ||||
|         ret = 0; | ||||
|     } else if (ret < 0) { | ||||
|  | ||||
| @ -81,7 +81,7 @@ 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); | ||||
| @ -89,7 +89,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, | ||||
|         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,7 +100,7 @@ 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); | ||||
| @ -108,7 +108,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, | ||||
|         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,27 +127,13 @@ void HELPER(mtspr)(CPUOpenRISCState *env, | ||||
|         break; | ||||
|     case TO_SPR(10, 0): /* TTMR */ | ||||
|         { | ||||
|             int ip = env->ttmr & TTMR_IP; | ||||
| 
 | ||||
|             if (rb & TTMR_IP) {    /* Keep IP bit.  */ | ||||
|                 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) { | ||||
|             if ((env->ttmr & TTMR_M) ^ (rb & TTMR_M)) { | ||||
|                 switch (rb & 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; | ||||
| @ -155,6 +141,18 @@ void HELPER(mtspr)(CPUOpenRISCState *env, | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             int ip = env->ttmr & TTMR_IP; | ||||
| 
 | ||||
|             if (rb & TTMR_IP) {    /* Keep IP bit.  */ | ||||
|                 env->ttmr = (rb & ~TTMR_IP) | ip; | ||||
|             } else {    /* Clear IP bit.  */ | ||||
|                 env->ttmr = rb & ~TTMR_IP; | ||||
|                 cs->interrupt_request &= ~CPU_INTERRUPT_TIMER; | ||||
|             } | ||||
| 
 | ||||
|             cpu_openrisc_timer_update(cpu); | ||||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     case TO_SPR(10, 1): /* TTCR */ | ||||
| @ -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; | ||||
| 
 | ||||
|  | ||||
| @ -209,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 */ | ||||
|         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_brcondi_i32(TCG_COND_EQ, sr_f, SR_F, lab); | ||||
|             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); | ||||
|     } 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 */ | ||||
|             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; | ||||
| @ -904,6 +911,9 @@ 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); | ||||
|         { | ||||
|             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(); | ||||
| @ -928,6 +938,7 @@ static void dec_misc(DisasContext *dc, uint32_t insn) | ||||
|                 tcg_temp_free_i32(res); | ||||
|                 tcg_temp_free_i32(sr_ove); | ||||
|             } | ||||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     case 0x28:    /* l.addic */ | ||||
|  | ||||
| @ -7,9 +7,10 @@ int main(void) | ||||
| 
 | ||||
|     b = 0x01; | ||||
|     c = 0xffffffff; | ||||
|     result = 1; | ||||
|     result = 0; | ||||
|     __asm | ||||
|     ("l.addc   %0, %1, %2\n\t" | ||||
|     ("l.add r1, r1, r0\n\t" /* clear carry */ | ||||
|      "l.addc   %0, %1, %2\n\t" | ||||
|      : "=r"(a) | ||||
|      : "r"(b), "r"(c) | ||||
|     ); | ||||
| @ -22,7 +23,8 @@ int main(void) | ||||
|     c = 0xffffffff; | ||||
|     result = 0x80000001; | ||||
|     __asm | ||||
|     ("l.addc   %0, %1, %2\n\t" | ||||
|     ("l.add r1, r1, r0\n\t" /* clear carry */ | ||||
|      "l.addc   %0, %1, %2\n\t" | ||||
|      "l.movhi  %2, 0x7fff\n\t" | ||||
|      "l.ori    %2, %2, 0xffff\n\t" | ||||
|      "l.addc   %0, %1, %2\n\t" | ||||
|  | ||||
| @ -6,9 +6,10 @@ int main(void) | ||||
|     int result; | ||||
| 
 | ||||
|     a = 1; | ||||
|     result = 0x1; | ||||
|     result = 0x0; | ||||
|     __asm | ||||
|     ("l.addic %0, %0, 0xffff\n\t" | ||||
|     ("l.add r1, r1, r0\n\t" /* clear carry */ | ||||
|      "l.addic %0, %0, 0xffff\n\t" | ||||
|      : "+r"(a) | ||||
|     ); | ||||
|     if (a != result) { | ||||
| @ -16,10 +17,11 @@ int main(void) | ||||
|         return -1; | ||||
|    } | ||||
| 
 | ||||
|     a = 0x1; | ||||
|     a = -1; | ||||
|     result = 0x201; | ||||
|     __asm | ||||
|     ("l.addic %0, %0, 0xffff\n\t" | ||||
|     ("l.add r1, r1, r0\n\t"  /* clear carry */ | ||||
|      "l.addic %0, %0, 0x1\n\t" | ||||
|      "l.ori   %0, r0, 0x100\n\t" | ||||
|      "l.addic %0, %0, 0x100\n\t" | ||||
|      : "+r"(a) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Anthony Liguori
						Anthony Liguori