Hi Blue, On Wed, Jun 20, 2012 at 2:25 AM, Blue Swirl <blauwir...@gmail.com> wrote: > On Tue, Jun 19, 2012 at 8:02 AM, Jia Liu <pro...@gmail.com> wrote: >> Hi Blue, >> >> Thank you for review. >> Is this code OK? >> >> void HELPER(mtspr)(CPUOpenRISCState * env, >> target_ulong ra, target_ulong rb, target_ulong offset) >> { >> #ifndef CONFIG_USER_ONLY >> int spr = (ra | offset); >> int idx; >> >> switch (spr) { >> case TO_SPR(0, 0): /* VR */ >> env->vr = rb; >> break; >> >> case TO_SPR(0, 16): /* NPC */ >> env->npc = rb; >> break; >> >> 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); >> } >> env->sr = rb; >> env->sr |= SR_FO; /* FO is const equal to 1 */ >> if (env->sr & SR_DME) { >> env->tlb->map_address_data = &get_phys_data; >> } else { >> env->tlb->map_address_data = &get_phys_nommu; >> } >> >> if (env->sr & SR_IME) { >> env->tlb->map_address_code = &get_phys_code; >> } else { >> env->tlb->map_address_code = &get_phys_nommu; >> } >> break; >> >> case TO_SPR(0, 18): /* PPC */ >> env->ppc = rb; >> break; >> >> case TO_SPR(0, 32): /* EPCR */ >> env->epcr = rb; >> break; >> >> case TO_SPR(0, 48): /* EEAR */ >> env->eear = rb; >> break; >> >> case TO_SPR(0, 64): /* ESR */ >> env->esr = rb; >> break; >> case TO_SPR(1, 512) ... TO_SPR(1, 639): /* 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); >> } >> env->tlb->dtlb[0][idx].mr = rb; >> break; >> >> case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ >> idx = spr - TO_SPR(1, 640); >> env->tlb->dtlb[0][idx].tr = rb; >> break; >> case TO_SPR(1, 768) ... TO_SPR(1, 895): /* DTLBW1MR 0-127 */ >> case TO_SPR(1, 896) ... TO_SPR(1, 1023): /* DTLBW1TR 0-127 */ >> case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */ >> case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */ >> 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 */ >> idx = spr - TO_SPR(2, 512); >> if (!(rb & 1)) { >> tlb_flush_page(env, 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 */ >> idx = spr - TO_SPR(2, 640); >> env->tlb->itlb[0][idx].tr = rb; >> break; >> case TO_SPR(2, 768) ... TO_SPR(2, 895): /* ITLBW1MR 0-127 */ >> case TO_SPR(2, 896) ... TO_SPR(2, 1023): /* ITLBW1TR 0-127 */ >> case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */ >> case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */ >> case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */ >> case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */ >> break; >> case TO_SPR(9, 0): /* PICMR */ >> cpu_openrisc_store_picmr(env, rb); >> break; >> case TO_SPR(9, 2): /* PICSR */ >> cpu_openrisc_store_picsr(env, rb); >> break; >> case TO_SPR(10, 0): /* TTMR */ >> cpu_openrisc_store_compare(env, rb); >> break; >> case TO_SPR(10, 1): /* TTCR */ >> cpu_openrisc_store_count(env, rb); >> break; >> default: >> break; >> } >> #endif >> } > > OK > >> >> target_ulong HELPER(mfspr)(CPUOpenRISCState * env, >> target_ulong rd, target_ulong ra, uint32_t offset) >> { >> #ifndef CONFIG_USER_ONLY >> int spr = (ra | offset); >> int idx; >> >> switch (spr) { >> case TO_SPR(0, 0): /* VR */ >> return (env->vr & SPR_VR); > > Parentheses are not necessary. >
all deleted. Thanks. >> >> case TO_SPR(0, 1): /* UPR */ >> return (env->upr); /* TT, DM, IM, UP present */ >> >> case TO_SPR(0, 2): /* CPUCFGR */ >> return (env->cpucfgr); >> >> case TO_SPR(0, 3): /* DMMUCFGR */ >> return (env->dmmucfgr); /* 1Way, 64 entries */ >> >> case TO_SPR(0, 4): /* IMMUCFGR */ >> return (env->immucfgr); >> >> case TO_SPR(0, 16): /* NPC */ >> return (env->npc); >> >> case TO_SPR(0, 17): /* SR */ >> return (env->sr); >> >> case TO_SPR(0, 18): /* PPC */ >> return (env->ppc); >> >> case TO_SPR(0, 32): /* EPCR */ >> return (env->epcr); >> >> case TO_SPR(0, 48): /* EEAR */ >> return (env->eear); >> >> case TO_SPR(0, 64): /* ESR */ >> return (env->esr); >> >> case TO_SPR(1, 512) ... TO_SPR(1, 639): /* 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 */ >> idx = spr - TO_SPR(1, 640); >> return (env->tlb->dtlb[0][idx].tr); >> >> case TO_SPR(1, 768) ... TO_SPR(1, 895): /* DTLBW1MR 0-127 */ >> case TO_SPR(1, 896) ... TO_SPR(1, 1023): /* DTLBW1TR 0-127 */ >> case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */ >> case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */ >> 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 */ >> 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 */ >> idx = spr - TO_SPR(2, 640); >> return (env->tlb->itlb[0][idx].tr); >> >> case TO_SPR(2, 768) ... TO_SPR(2, 895): /* ITLBW1MR 0-127 */ >> case TO_SPR(2, 896) ... TO_SPR(2, 1023): /* ITLBW1TR 0-127 */ >> case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */ >> case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */ >> case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */ >> case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */ >> break; >> >> case TO_SPR(9, 0): /* PICMR */ >> return (env->picmr); >> >> case TO_SPR(9, 2): /* PICSR */ >> return (env->picsr); >> >> case TO_SPR(10, 0): /* TTMR */ >> return (env->ttmr); >> >> case TO_SPR(10, 1): /* TTCR */ >> return cpu_openrisc_get_count(env); >> >> default: >> break; >> } >> #endif >> return rd; > > Is this correct, maybe 0 would be a nice value for unknown SPRs, or is > rd the default value? > It is rd. for rd is passed in, if rd unchanged, just keep it back. But, I added a comment here, so, it now look like /* for rd is passed in, if rd unchanged, just keep it back. */ return rd; > If you later need to add tracepoints (or debug printfs) for the return > value, it may be useful to structure the code like this: > target_ulong ret = 0; > > switch() { > case x: > ret = y; > break; > case z: > ret = 42; > break; > ... > } > /* later something like trace_spr_read(ret); */ > return ret; > I've added this in a comment for the future use, thank you very much. >> } >> >> >> case 0x2d: /*l.mfspr*/ >> LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16); >> { >> TCGv_i32 ti = tcg_const_i32(I16); >> gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti); >> tcg_temp_free_i32(ti); >> } >> break; >> >> case 0x30: /*l.mtspr*/ >> LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11); >> { >> TCGv_i32 im = tcg_const_i32(tmp); >> gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im); >> tcg_temp_free_i32(im); >> } >> break; > > OK > >> >> >> On Tue, Jun 19, 2012 at 2:58 AM, Blue Swirl <blauwir...@gmail.com> wrote: >>> On Mon, Jun 18, 2012 at 1:03 AM, Jia Liu <pro...@gmail.com> wrote: >>>> Add OpenRISC system instruction support. >>>> >>>> Signed-off-by: Jia Liu <pro...@gmail.com> >>>> --- >>>> target-openrisc/Makefile.objs | 3 +- >>>> target-openrisc/helper.h | 4 + >>>> target-openrisc/sys_helper.c | 233 >>>> +++++++++++++++++++++++++++++++++++++++++ >>>> target-openrisc/translate.c | 20 ++++ >>>> 4 files changed, 259 insertions(+), 1 deletion(-) >>>> create mode 100644 target-openrisc/sys_helper.c >>>> >>>> diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs >>>> index 0d72c33..9d13a5d 100644 >>>> --- a/target-openrisc/Makefile.objs >>>> +++ b/target-openrisc/Makefile.objs >>>> @@ -1,3 +1,4 @@ >>>> obj-$(CONFIG_SOFTMMU) += machine.o >>>> obj-y += cpu.o excp.o intrpt.o mmu.o translate.o >>>> -obj-y += excp_helper.o fpu_helper.o int_helper.o intrpt_helper.o >>>> mmu_helper.o >>>> +obj-y += excp_helper.o fpu_helper.o int_helper.o intrpt_helper.o \ >>>> + mmu_helper.o sys_helper.o >>>> diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h >>>> index 60870f2..04c63c5 100644 >>>> --- a/target-openrisc/helper.h >>>> +++ b/target-openrisc/helper.h >>>> @@ -62,4 +62,8 @@ DEF_HELPER_FLAGS_1(fl1, 0, tl, tl) >>>> /* interrupt */ >>>> DEF_HELPER_FLAGS_1(rfe, 0, void, env) >>>> >>>> +/* sys */ >>>> +DEF_HELPER_FLAGS_4(mtspr, 0, void, env, tl, tl, tl) >>>> +DEF_HELPER_FLAGS_4(mfspr, 0, void, env, tl, tl, tl) >>>> + >>>> #include "def-helper.h" >>>> diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c >>>> new file mode 100644 >>>> index 0000000..f1e4314 >>>> --- /dev/null >>>> +++ b/target-openrisc/sys_helper.c >>>> @@ -0,0 +1,233 @@ >>>> +/* >>>> + * OpenRISC system instructions helper routines >>>> + * >>>> + * Copyright (c) 2011-2012 Jia Liu <pro...@gmail.com> >>>> + * Zhizhou Zhang <eto...@gmail.com> >>>> + * >>>> + * This library is free software; you can redistribute it and/or >>>> + * modify it under the terms of the GNU Lesser General Public >>>> + * License as published by the Free Software Foundation; either >>>> + * version 2 of the License, or (at your option) any later version. >>>> + * >>>> + * This library is distributed in the hope that it will be useful, >>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >>>> + * Lesser General Public License for more details. >>>> + * >>>> + * You should have received a copy of the GNU Lesser General Public >>>> + * License along with this library; if not, see >>>> <http://www.gnu.org/licenses/>. >>>> + */ >>>> + >>>> +#include "cpu.h" >>>> +#include "helper.h" >>>> + >>>> +#define TO_SPR(group, number) (((group) << 11) + (number)) >>>> + >>>> +void HELPER(mtspr)(CPUOpenRISCState * env, >>>> + target_ulong ra, target_ulong rb, target_ulong offset) >>>> +{ >>>> +#if !defined(CONFIG_USER_ONLY) >>>> + int spr = (ra | offset); >>>> + int idx; >>>> + >>>> + switch (spr) { >>>> + case TO_SPR(0, 0): /* VR */ >>>> + env->vr = rb; >>>> + break; >>>> + >>>> + case TO_SPR(0, 16): /* NPC */ >>>> + env->npc = rb; >>>> + break; >>>> + >>>> + 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); >>>> + } >>>> + env->sr = rb; >>>> + env->sr |= SR_FO; /* FO is const equal to 1 */ >>>> + if (env->sr & SR_DME) { >>>> + env->tlb->map_address_data = &get_phys_data; >>>> + } else { >>>> + env->tlb->map_address_data = &get_phys_nommu; >>>> + } >>>> + >>>> + if (env->sr & SR_IME) { >>>> + env->tlb->map_address_code = &get_phys_code; >>>> + } else { >>>> + env->tlb->map_address_code = &get_phys_nommu; >>>> + } >>>> + break; >>>> + >>>> + case TO_SPR(0, 18): /* PPC */ >>>> + env->ppc = rb; >>>> + break; >>>> + >>>> + case TO_SPR(0, 32): /* EPCR */ >>>> + env->epcr = rb; >>>> + break; >>>> + >>>> + case TO_SPR(0, 48): /* EEAR */ >>>> + env->eear = rb; >>>> + break; >>>> + >>>> + case TO_SPR(0, 64): /* ESR */ >>>> + env->esr = rb; >>>> + break; >>>> + case TO_SPR(1, 512) ... TO_SPR(1, 639): /* 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); >>>> + } >>>> + env->tlb->dtlb[0][idx].mr = rb; >>>> + break; >>>> + >>>> + case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ >>>> + idx = spr - TO_SPR(1, 640); >>>> + env->tlb->dtlb[0][idx].tr = rb; >>>> + break; >>>> + case TO_SPR(1, 768) ... TO_SPR(1, 895): /* DTLBW1MR 0-127 */ >>>> + case TO_SPR(1, 896) ... TO_SPR(1, 1023): /* DTLBW1TR 0-127 */ >>>> + case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */ >>>> + case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */ >>>> + 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 */ >>>> + idx = spr - TO_SPR(2, 512); >>>> + if (!(rb & 1)) { >>>> + tlb_flush_page(env, 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 */ >>>> + idx = spr - TO_SPR(2, 640); >>>> + env->tlb->itlb[0][idx].tr = rb; >>>> + break; >>>> + case TO_SPR(2, 768) ... TO_SPR(2, 895): /* ITLBW1MR 0-127 */ >>>> + case TO_SPR(2, 896) ... TO_SPR(2, 1023): /* ITLBW1TR 0-127 */ >>>> + case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */ >>>> + case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */ >>>> + case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */ >>>> + case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */ >>>> + break; >>>> + case TO_SPR(9, 0): /* PICMR */ >>>> + cpu_openrisc_store_picmr(env, rb); >>>> + break; >>>> + case TO_SPR(9, 2): /* PICSR */ >>>> + cpu_openrisc_store_picsr(env, rb); >>>> + break; >>>> + case TO_SPR(10, 0): /* TTMR */ >>>> + cpu_openrisc_store_compare(env, rb); >>>> + break; >>>> + case TO_SPR(10, 1): /* TTCR */ >>>> + cpu_openrisc_store_count(env, rb); >>>> + break; >>>> + default: >>>> + break; >>>> + } >>>> +#endif >>>> +} >>>> + >>>> +void HELPER(mfspr)(CPUOpenRISCState * env, >>>> + target_ulong rd, target_ulong ra, uint32_t offset) >>>> +{ >>>> +#if !defined(CONFIG_USER_ONLY) >>>> + int spr = env->gpr[ra] | offset; >>> >>> [1] >>> >>>> + int idx; >>>> + >>>> + switch (spr) { >>>> + case TO_SPR(0, 0): /* VR */ >>>> + env->gpr[rd] = (env->vr & SPR_VR); >>>> + break; >>>> + >>>> + case TO_SPR(0, 1): /* UPR */ >>>> + env->gpr[rd] = env->upr; /* TT, DM, IM, UP present */ >>>> + break; >>>> + >>>> + case TO_SPR(0, 2): /* CPUCFGR */ >>>> + env->gpr[rd] = env->cpucfgr; >>>> + break; >>>> + >>>> + case TO_SPR(0, 3): /* DMMUCFGR */ >>>> + env->gpr[rd] = env->dmmucfgr; /* 1Way, 64 entries */ >>>> + break; >>>> + case TO_SPR(0, 4): /* IMMUCFGR */ >>>> + env->gpr[rd] = env->immucfgr; >>>> + break; >>>> + >>>> + case TO_SPR(0, 16): /* NPC */ >>>> + env->gpr[rd] = env->npc; >>>> + break; >>>> + >>>> + case TO_SPR(0, 17): /* SR */ >>>> + env->gpr[rd] = env->sr; >>>> + break; >>>> + >>>> + case TO_SPR(0, 18): /* PPC */ >>>> + env->gpr[rd] = env->ppc; >>>> + break; >>>> + >>>> + case TO_SPR(0, 32): /* EPCR */ >>>> + env->gpr[rd] = env->epcr; >>>> + break; >>>> + >>>> + case TO_SPR(0, 48): /* EEAR */ >>>> + env->gpr[rd] = env->eear; >>>> + break; >>>> + >>>> + case TO_SPR(0, 64): /* ESR */ >>>> + env->gpr[rd] = env->esr; >>>> + break; >>>> + >>>> + case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */ >>>> + idx = spr - TO_SPR(1, 512); >>>> + env->gpr[rd] = env->tlb->dtlb[0][idx].mr; >>>> + break; >>>> + >>>> + case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ >>>> + idx = spr - TO_SPR(1, 640); >>>> + env->gpr[rd] = env->tlb->dtlb[0][idx].tr; >>>> + break; >>>> + case TO_SPR(1, 768) ... TO_SPR(1, 895): /* DTLBW1MR 0-127 */ >>>> + case TO_SPR(1, 896) ... TO_SPR(1, 1023): /* DTLBW1TR 0-127 */ >>>> + case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */ >>>> + case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */ >>>> + 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 */ >>>> + idx = spr - TO_SPR(2, 512); >>>> + env->gpr[rd] = env->tlb->itlb[0][idx].mr; >>>> + break; >>>> + >>>> + case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */ >>>> + idx = spr - TO_SPR(2, 640); >>>> + env->gpr[rd] = env->tlb->itlb[0][idx].tr; >>>> + break; >>>> + case TO_SPR(2, 768) ... TO_SPR(2, 895): /* ITLBW1MR 0-127 */ >>>> + case TO_SPR(2, 896) ... TO_SPR(2, 1023): /* ITLBW1TR 0-127 */ >>>> + case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */ >>>> + case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */ >>>> + case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */ >>>> + case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */ >>>> + break; >>>> + case TO_SPR(9, 0): /* PICMR */ >>>> + env->gpr[rd] = env->picmr; >>>> + break; >>>> + case TO_SPR(9, 2): /* PICSR */ >>>> + env->gpr[rd] = env->picsr; >>>> + break; >>>> + case TO_SPR(10, 0): /* TTMR */ >>>> + env->gpr[rd] = env->ttmr; >>>> + break; >>>> + case TO_SPR(10, 1): /* TTCR */ >>>> + env->gpr[rd] = cpu_openrisc_get_count(env); >>> >>> [2] >>> >>>> + break; >>>> + default: >>>> + break; >>>> + } >>>> +#endif >>>> +} >>>> diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c >>>> index d4f894b..11eb0a5 100644 >>>> --- a/target-openrisc/translate.c >>>> +++ b/target-openrisc/translate.c >>>> @@ -1241,10 +1241,30 @@ static void dec_misc(DisasContext *dc, >>>> CPUOpenRISCState *env, uint32_t insn) >>>> >>>> case 0x2d: /*l.mfspr*/ >>>> LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16); >>>> + { >>>> + TCGv_i32 ti = tcg_const_i32(I16); >>>> + TCGv td = tcg_const_tl(rd); >>>> + TCGv ta = tcg_const_tl(ra); >>>> + gen_helper_mfspr(cpu_env, td, ta, ti); >>> >>> The helper should a return target_ulong, so the line would become >>> gen_helper_mfspr(cpu_R[rd], cpu_env, td, cpu_R[ra], ti); >>> >>> Then the register moves inside the mfspr helper could be avoided: >>> [1] >>>> + int spr = env->gpr[ra] | offset; >>> int spr = ra | offset; >>> >>> As an example [2]: >>>> + env->gpr[rd] = cpu_openrisc_get_count(env); >>> return cpu_openrisc_get_count(env); >>> >>>> + tcg_temp_free_i32(ti); >>>> + tcg_temp_free(td); >>>> + tcg_temp_free(ta); >>>> + } >>> >>> Also here you could try later to avoid to compile sys_helper.c for >>> user emulator by surrounding the previous block by #ifndef >>> CONFIG_USER_ONLY/#endif (ditto for mtspr). >>> >>>> break; >>>> >>>> case 0x30: /*l.mtspr*/ >>>> LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11); >>>> + { >>>> + TCGv_i32 im = tcg_const_i32(tmp); >>>> + TCGv ta = tcg_temp_new(); >>>> + TCGv tb = tcg_temp_new(); >>>> + tcg_gen_mov_tl(ta, cpu_R[ra]); >>>> + tcg_gen_mov_tl(tb, cpu_R[rb]); >>>> + gen_helper_mtspr(cpu_env, ta, tb, im); >>> >>> Simply >>> gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im); >>> >>>> + tcg_temp_free_i32(im); >>>> + tcg_temp_free(ta); >>>> + tcg_temp_free(tb); >>>> + } >>>> break; >>>> >>>> case 0x34: /*l.sd*/ >>>> -- >>>> 1.7.9.5 >>>> >>>> >> >> Regards, >> Jia.