Commit 500efcfc authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/rth/tags/pull-or1k-20190904' into staging



Updates for arch v1.3.

# gpg: Signature made Wed 04 Sep 2019 21:30:41 BST
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* remotes/rth/tags/pull-or1k-20190904:
  target/openrisc: Update cpu "any" to v1.3
  target/openrisc: Implement l.adrp
  target/openrisc: Implement move to/from FPCSR
  target/openrisc: Implement unordered fp comparisons
  target/openrisc: Add support for ORFPX64A32
  target/openrisc: Check CPUCFG_OF32S for float insns
  target/openrisc: Fix lf.ftoi.s
  target/openrisc: Add VR2 and AVR special processor registers
  target/openrisc: Move VR, UPR, DMMCFGR, IMMCFGR to cpu init
  target/openrisc: Make VR and PPC read-only
  target/openrisc: Cache R0 in DisasContext
  target/openrisc: Replace cpu register array with a function
  target/openrisc: Add DisasContext parameter to check_r0_write

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents a8b5ad8e 9e3bab08
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -9,6 +9,6 @@
#define OPENRISC_TARGET_ELF_H
static inline const char *cpu_get_model(uint32_t eflags)
{
    return "or1200";
    return "any";
}
#endif
+22 −8
Original line number Diff line number Diff line
@@ -55,13 +55,7 @@ static void openrisc_cpu_reset(CPUState *s)
    cpu->env.sr = SR_FO | SR_SM;
    cpu->env.lock_addr = -1;
    s->exception_index = -1;

    cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP |
                   UPR_PMP;
    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
                      | (DMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2))
                      | (IMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
    cpu_set_fpcsr(&cpu->env, 0);

#ifndef CONFIG_USER_ONLY
    cpu->env.picmr = 0x00000000;
@@ -117,15 +111,35 @@ static void or1200_initfn(Object *obj)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(obj);

    cpu->env.vr = 0x13000008;
    cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | UPR_PMP;
    cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_OF32S |
                       CPUCFGR_EVBARP;

    /* 1Way, TLB_SIZE entries.  */
    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
                      | (DMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2))
                      | (IMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
}

static void openrisc_any_initfn(Object *obj)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(obj);

    cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_EVBARP;
    cpu->env.vr = 0x13000040;   /* Obsolete VER + UVRP for new SPRs */
    cpu->env.vr2 = 0;           /* No version specific id */
    cpu->env.avr = 0x01030000;  /* Architecture v1.3 */

    cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | UPR_PMP;
    cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_OF32S |
                       CPUCFGR_AVRP | CPUCFGR_EVBARP | CPUCFGR_OF64A32S;

    /* 1Way, TLB_SIZE entries.  */
    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
                      | (DMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2))
                      | (IMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
}

static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
+13 −11
Original line number Diff line number Diff line
@@ -68,9 +68,6 @@ enum {
                                      (reg) |= ((v & 0x1f) << 2);\
                                  } while (0)

/* Version Register */
#define SPR_VR 0xFFFF003F

/* Interrupt */
#define NR_IRQS  32

@@ -99,11 +96,12 @@ enum {
    CPUCFGR_OF32S = (1 << 7),
    CPUCFGR_OF64S = (1 << 8),
    CPUCFGR_OV64S = (1 << 9),
    /* CPUCFGR_ND = (1 << 10), */
    /* CPUCFGR_AVRP = (1 << 11), */
    CPUCFGR_ND = (1 << 10),
    CPUCFGR_AVRP = (1 << 11),
    CPUCFGR_EVBARP = (1 << 12),
    /* CPUCFGR_ISRP = (1 << 13), */
    /* CPUCFGR_AECSRP = (1 << 14), */
    CPUCFGR_ISRP = (1 << 13),
    CPUCFGR_AECSRP = (1 << 14),
    CPUCFGR_OF64A32S = (1 << 15),
};

/* DMMU configure register */
@@ -263,10 +261,6 @@ typedef struct CPUOpenRISCState {
    target_ulong sr_cy;       /* the SR_CY bit, values 0, 1.  */
    target_long  sr_ov;       /* the SR_OV bit (in the sign bit only) */
    uint32_t sr;              /* Supervisor register, without SR_{F,CY,OV} */
    uint32_t vr;              /* Version register */
    uint32_t upr;             /* Unit presence register */
    uint32_t dmmucfgr;        /* DMMU configure register */
    uint32_t immucfgr;        /* IMMU configure register */
    uint32_t esr;             /* Exception supervisor register */
    uint32_t evbar;           /* Exception vector base address register */
    uint32_t pmr;             /* Power Management Register */
@@ -286,7 +280,13 @@ typedef struct CPUOpenRISCState {
    struct {} end_reset_fields;

    /* Fields from here on are preserved across CPU reset. */
    uint32_t vr;              /* Version register */
    uint32_t vr2;             /* Version register 2 */
    uint32_t avr;             /* Architecture version register */
    uint32_t upr;             /* Unit presence register */
    uint32_t cpucfgr;         /* CPU configure register */
    uint32_t dmmucfgr;        /* DMMU configure register */
    uint32_t immucfgr;        /* IMMU configure register */

#ifndef CONFIG_USER_ONLY
    QEMUTimer *timer;
@@ -413,6 +413,8 @@ static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val)
    env->sr = (val & ~(SR_F | SR_CY | SR_OV)) | SR_FO;
}

void cpu_set_fpcsr(CPUOpenRISCState *env, uint32_t val);

#define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0

#endif /* OPENRISC_CPU_H */
+81 −0
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ INSN(sw, "%d(r%d), r%d", a->i, a->a, a->b)
INSN(sb,     "%d(r%d), r%d", a->i, a->a, a->b)
INSN(sh,     "%d(r%d), r%d", a->i, a->a, a->b)
INSN(nop,    "")
INSN(adrp,   "r%d, %d", a->d, a->i)
INSN(addi,   "r%d, r%d, %d", a->d, a->a, a->i)
INSN(addic,  "r%d, r%d, %d", a->d, a->a, a->i)
INSN(muli,   "r%d, r%d, %d", a->d, a->a, a->i)
@@ -166,3 +167,83 @@ FP_INSN(sfgt, s, "r%d, r%d", a->a, a->b)
FP_INSN(sfge, s, "r%d, r%d", a->a, a->b)
FP_INSN(sflt, s, "r%d, r%d", a->a, a->b)
FP_INSN(sfle, s, "r%d, r%d", a->a, a->b)
FP_INSN(sfun, s, "r%d, r%d", a->a, a->b)
FP_INSN(sfueq, s, "r%d, r%d", a->a, a->b)
FP_INSN(sfuge, s, "r%d, r%d", a->a, a->b)
FP_INSN(sfugt, s, "r%d, r%d", a->a, a->b)
FP_INSN(sfule, s, "r%d, r%d", a->a, a->b)
FP_INSN(sfult, s, "r%d, r%d", a->a, a->b)

FP_INSN(add, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
        a->d, a->d + a->dp + 1,
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sub, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
        a->d, a->d + a->dp + 1,
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(mul, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
        a->d, a->d + a->dp + 1,
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(div, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
        a->d, a->d + a->dp + 1,
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(rem, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
        a->d, a->d + a->dp + 1,
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(madd, d, "r%d,r%d, r%d,r%d, r%d,r%d",
        a->d, a->d + a->dp + 1,
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)

FP_INSN(itof, d, "r%d,r%d, r%d,r%d",
        a->d, a->d + a->dp + 1,
        a->a, a->a + a->ap + 1)
FP_INSN(ftoi, d, "r%d,r%d, r%d,r%d",
        a->d, a->d + a->dp + 1,
        a->a, a->a + a->ap + 1)

FP_INSN(stod, d, "r%d,r%d, r%d",
        a->d, a->d + a->dp + 1, a->a)
FP_INSN(dtos, d, "r%d r%d,r%d",
        a->d, a->a, a->a + a->ap + 1)

FP_INSN(sfeq, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sfne, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sfgt, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sfge, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sflt, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sfle, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sfun, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sfueq, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sfuge, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sfugt, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sfule, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
FP_INSN(sfult, d, "r%d,r%d, r%d,r%d",
        a->a, a->a + a->ap + 1,
        a->b, a->b + a->bp + 1)
+46 −3
Original line number Diff line number Diff line
@@ -61,9 +61,22 @@ void HELPER(update_fpcsr)(CPUOpenRISCState *env)
    }
}

void cpu_set_fpcsr(CPUOpenRISCState *env, uint32_t val)
{
    static const int rm_to_sf[] = {
        float_round_nearest_even,
        float_round_to_zero,
        float_round_up,
        float_round_down
    };

    env->fpcsr = val & 0x7ff;
    set_float_rounding_mode(rm_to_sf[extract32(val, 1, 2)], &env->fp_status);
}

uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
{
    return int32_to_float64(val, &env->fp_status);
    return int64_to_float64(val, &env->fp_status);
}

uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)
@@ -73,12 +86,22 @@ uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)

uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val)
{
    return float32_to_int64(val, &env->fp_status);
    return float64_to_int64_round_to_zero(val, &env->fp_status);
}

uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val)
{
    return float32_to_int32(val, &env->fp_status);
    return float32_to_int32_round_to_zero(val, &env->fp_status);
}

uint64_t HELPER(stod)(CPUOpenRISCState *env, uint32_t val)
{
    return float32_to_float64(val, &env->fp_status);
}

uint32_t HELPER(dtos)(CPUOpenRISCState *env, uint64_t val)
{
    return float64_to_float32(val, &env->fp_status);
}

#define FLOAT_CALC(name)                                                  \
@@ -125,4 +148,24 @@ target_ulong helper_float_ ## name ## _s(CPUOpenRISCState *env, \
FLOAT_CMP(le, le)
FLOAT_CMP(lt, lt)
FLOAT_CMP(eq, eq_quiet)
FLOAT_CMP(un, unordered_quiet)
#undef FLOAT_CMP

#define FLOAT_UCMP(name, expr) \
target_ulong helper_float_ ## name ## _d(CPUOpenRISCState *env,           \
                                         uint64_t fdt0, uint64_t fdt1)    \
{                                                                         \
    int r = float64_compare_quiet(fdt0, fdt1, &env->fp_status);           \
    return expr;                                                          \
}                                                                         \
target_ulong helper_float_ ## name ## _s(CPUOpenRISCState *env,           \
                                         uint32_t fdt0, uint32_t fdt1)    \
{                                                                         \
    int r = float32_compare_quiet(fdt0, fdt1, &env->fp_status);           \
    return expr;                                                          \
}

FLOAT_UCMP(ueq, r == float_relation_equal || r == float_relation_unordered)
FLOAT_UCMP(ult, r == float_relation_less || r == float_relation_unordered)
FLOAT_UCMP(ule, r != float_relation_greater)
#undef FLOAT_UCMP
Loading