qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v5 12/16] target-or32: Add system instructions


From: Blue Swirl
Subject: Re: [Qemu-devel] [PATCH v5 12/16] target-or32: Add system instructions
Date: Tue, 19 Jun 2012 18:25:15 +0000

On Tue, Jun 19, 2012 at 8:02 AM, Jia Liu <address@hidden> 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.

>
>    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?

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;

> }
>
>
>    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 <address@hidden> wrote:
>> On Mon, Jun 18, 2012 at 1:03 AM, Jia Liu <address@hidden> wrote:
>>> Add OpenRISC system instruction support.
>>>
>>> Signed-off-by: Jia Liu <address@hidden>
>>> ---
>>>  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 <address@hidden>
>>> + *                          Zhizhou Zhang <address@hidden>
>>> + *
>>> + * 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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]