提交 500efcfc 编写于 作者: P Peter Maydell

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: NPeter Maydell <peter.maydell@linaro.org>
...@@ -9,6 +9,6 @@ ...@@ -9,6 +9,6 @@
#define OPENRISC_TARGET_ELF_H #define OPENRISC_TARGET_ELF_H
static inline const char *cpu_get_model(uint32_t eflags) static inline const char *cpu_get_model(uint32_t eflags)
{ {
return "or1200"; return "any";
} }
#endif #endif
...@@ -55,13 +55,7 @@ static void openrisc_cpu_reset(CPUState *s) ...@@ -55,13 +55,7 @@ static void openrisc_cpu_reset(CPUState *s)
cpu->env.sr = SR_FO | SR_SM; cpu->env.sr = SR_FO | SR_SM;
cpu->env.lock_addr = -1; cpu->env.lock_addr = -1;
s->exception_index = -1; s->exception_index = -1;
cpu_set_fpcsr(&cpu->env, 0);
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));
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
cpu->env.picmr = 0x00000000; cpu->env.picmr = 0x00000000;
...@@ -117,15 +111,35 @@ static void or1200_initfn(Object *obj) ...@@ -117,15 +111,35 @@ static void or1200_initfn(Object *obj)
{ {
OpenRISCCPU *cpu = OPENRISC_CPU(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 | cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_OF32S |
CPUCFGR_EVBARP; 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) static void openrisc_any_initfn(Object *obj)
{ {
OpenRISCCPU *cpu = OPENRISC_CPU(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) static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
......
...@@ -68,9 +68,6 @@ enum { ...@@ -68,9 +68,6 @@ enum {
(reg) |= ((v & 0x1f) << 2);\ (reg) |= ((v & 0x1f) << 2);\
} while (0) } while (0)
/* Version Register */
#define SPR_VR 0xFFFF003F
/* Interrupt */ /* Interrupt */
#define NR_IRQS 32 #define NR_IRQS 32
...@@ -99,11 +96,12 @@ enum { ...@@ -99,11 +96,12 @@ enum {
CPUCFGR_OF32S = (1 << 7), CPUCFGR_OF32S = (1 << 7),
CPUCFGR_OF64S = (1 << 8), CPUCFGR_OF64S = (1 << 8),
CPUCFGR_OV64S = (1 << 9), CPUCFGR_OV64S = (1 << 9),
/* CPUCFGR_ND = (1 << 10), */ CPUCFGR_ND = (1 << 10),
/* CPUCFGR_AVRP = (1 << 11), */ CPUCFGR_AVRP = (1 << 11),
CPUCFGR_EVBARP = (1 << 12), CPUCFGR_EVBARP = (1 << 12),
/* CPUCFGR_ISRP = (1 << 13), */ CPUCFGR_ISRP = (1 << 13),
/* CPUCFGR_AECSRP = (1 << 14), */ CPUCFGR_AECSRP = (1 << 14),
CPUCFGR_OF64A32S = (1 << 15),
}; };
/* DMMU configure register */ /* DMMU configure register */
...@@ -263,10 +261,6 @@ typedef struct CPUOpenRISCState { ...@@ -263,10 +261,6 @@ typedef struct CPUOpenRISCState {
target_ulong sr_cy; /* the SR_CY bit, values 0, 1. */ target_ulong sr_cy; /* the SR_CY bit, values 0, 1. */
target_long sr_ov; /* the SR_OV bit (in the sign bit only) */ 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 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 esr; /* Exception supervisor register */
uint32_t evbar; /* Exception vector base address register */ uint32_t evbar; /* Exception vector base address register */
uint32_t pmr; /* Power Management Register */ uint32_t pmr; /* Power Management Register */
...@@ -286,7 +280,13 @@ typedef struct CPUOpenRISCState { ...@@ -286,7 +280,13 @@ typedef struct CPUOpenRISCState {
struct {} end_reset_fields; struct {} end_reset_fields;
/* Fields from here on are preserved across CPU reset. */ /* 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 cpucfgr; /* CPU configure register */
uint32_t dmmucfgr; /* DMMU configure register */
uint32_t immucfgr; /* IMMU configure register */
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
QEMUTimer *timer; QEMUTimer *timer;
...@@ -413,6 +413,8 @@ static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val) ...@@ -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; 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 #define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_INT_0
#endif /* OPENRISC_CPU_H */ #endif /* OPENRISC_CPU_H */
...@@ -98,6 +98,7 @@ INSN(sw, "%d(r%d), r%d", a->i, a->a, a->b) ...@@ -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(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(sh, "%d(r%d), r%d", a->i, a->a, a->b)
INSN(nop, "") 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(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(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) 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) ...@@ -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(sfge, s, "r%d, r%d", a->a, a->b)
FP_INSN(sflt, 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(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)
...@@ -61,9 +61,22 @@ void HELPER(update_fpcsr)(CPUOpenRISCState *env) ...@@ -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) 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) uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)
...@@ -73,12 +86,22 @@ 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) 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) 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) \ #define FLOAT_CALC(name) \
...@@ -125,4 +148,24 @@ target_ulong helper_float_ ## name ## _s(CPUOpenRISCState *env, \ ...@@ -125,4 +148,24 @@ target_ulong helper_float_ ## name ## _s(CPUOpenRISCState *env, \
FLOAT_CMP(le, le) FLOAT_CMP(le, le)
FLOAT_CMP(lt, lt) FLOAT_CMP(lt, lt)
FLOAT_CMP(eq, eq_quiet) FLOAT_CMP(eq, eq_quiet)
FLOAT_CMP(un, unordered_quiet)
#undef FLOAT_CMP #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
...@@ -30,6 +30,8 @@ DEF_HELPER_FLAGS_2(itofd, TCG_CALL_NO_RWG, i64, env, i64) ...@@ -30,6 +30,8 @@ DEF_HELPER_FLAGS_2(itofd, TCG_CALL_NO_RWG, i64, env, i64)
DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_RWG, i32, env, i32) DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_RWG, i32, env, i32)
DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_RWG, i64, env, i64) DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_RWG, i64, env, i64)
DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_RWG, i32, env, i32) DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_RWG, i32, env, i32)
DEF_HELPER_FLAGS_2(stod, TCG_CALL_NO_RWG, i64, env, i32)
DEF_HELPER_FLAGS_2(dtos, TCG_CALL_NO_RWG, i32, env, i64)
DEF_HELPER_FLAGS_4(float_madd_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32) DEF_HELPER_FLAGS_4(float_madd_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_4(float_madd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) DEF_HELPER_FLAGS_4(float_madd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
...@@ -50,6 +52,10 @@ DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_RWG, tl, env, i64, i64) ...@@ -50,6 +52,10 @@ DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_RWG, tl, env, i64, i64)
FOP_CMP(eq) FOP_CMP(eq)
FOP_CMP(lt) FOP_CMP(lt)
FOP_CMP(le) FOP_CMP(le)
FOP_CMP(un)
FOP_CMP(ueq)
FOP_CMP(ule)
FOP_CMP(ult)
#undef FOP_CMP #undef FOP_CMP
/* interrupt */ /* interrupt */
......
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
&ab a b &ab a b
&dal d a l &dal d a l
&ai a i &ai a i
&dab_pair d a b dp ap bp
&ab_pair a b ap bp
&da_pair d a dp ap
#### ####
# System Instructions # System Instructions
...@@ -99,6 +102,8 @@ l_maci 010011 ----- a:5 i:s16 ...@@ -99,6 +102,8 @@ l_maci 010011 ----- a:5 i:s16
l_movhi 000110 d:5 ----0 k:16 l_movhi 000110 d:5 ----0 k:16
l_macrc 000110 d:5 ----1 00000000 00000000 l_macrc 000110 d:5 ----1 00000000 00000000
l_adrp 000010 d:5 i:s21
#### ####
# Arithmetic Instructions # Arithmetic Instructions
#### ####
...@@ -187,3 +192,43 @@ lf_sfgt_s 110010 ----- a:5 b:5 --- 00001010 ...@@ -187,3 +192,43 @@ lf_sfgt_s 110010 ----- a:5 b:5 --- 00001010
lf_sfge_s 110010 ----- a:5 b:5 --- 00001011 lf_sfge_s 110010 ----- a:5 b:5 --- 00001011
lf_sflt_s 110010 ----- a:5 b:5 --- 00001100 lf_sflt_s 110010 ----- a:5 b:5 --- 00001100
lf_sfle_s 110010 ----- a:5 b:5 --- 00001101 lf_sfle_s 110010 ----- a:5 b:5 --- 00001101
lf_sfueq_s 110010 ----- a:5 b:5 --- 00101000
lf_sfuge_s 110010 ----- a:5 b:5 --- 00101011
lf_sfugt_s 110010 ----- a:5 b:5 --- 00101010
lf_sfule_s 110010 ----- a:5 b:5 --- 00101101
lf_sfult_s 110010 ----- a:5 b:5 --- 00101100
lf_sfun_s 110010 ----- a:5 b:5 --- 00101110
####
# DP Instructions
####
@dab_pair ...... d:5 a:5 b:5 dp:1 ap:1 bp:1 ........ &dab_pair
@ab_pair ...... ..... a:5 b:5 . ap:1 bp:1 ........ &ab_pair
@da_pair ...... d:5 a:5 ..... dp:1 ap:1 . ........ &da_pair
lf_add_d 110010 ..... ..... ..... ... 00010000 @dab_pair
lf_sub_d 110010 ..... ..... ..... ... 00010001 @dab_pair
lf_mul_d 110010 ..... ..... ..... ... 00010010 @dab_pair
lf_div_d 110010 ..... ..... ..... ... 00010011 @dab_pair
lf_rem_d 110010 ..... ..... ..... ... 00010110 @dab_pair
lf_madd_d 110010 ..... ..... ..... ... 00010111 @dab_pair
lf_itof_d 110010 ..... ..... 00000 ..0 00010100 @da_pair
lf_ftoi_d 110010 ..... ..... 00000 ..0 00010101 @da_pair
lf_stod_d 110010 d:5 a:5 00000 dp:1 0 0 00110100
lf_dtos_d 110010 d:5 a:5 00000 0 ap:1 0 00110101
lf_sfeq_d 110010 00000 ..... ..... 0.. 00011000 @ab_pair
lf_sfne_d 110010 00000 ..... ..... 0.. 00011001 @ab_pair
lf_sfgt_d 110010 00000 ..... ..... 0.. 00011010 @ab_pair
lf_sfge_d 110010 00000 ..... ..... 0.. 00011011 @ab_pair
lf_sflt_d 110010 00000 ..... ..... 0.. 00011100 @ab_pair
lf_sfle_d 110010 00000 ..... ..... 0.. 00011101 @ab_pair
lf_sfueq_d 110010 00000 ..... ..... 0.. 00111000 @ab_pair
lf_sfuge_d 110010 00000 ..... ..... 0.. 00111011 @ab_pair
lf_sfugt_d 110010 00000 ..... ..... 0.. 00111010 @ab_pair
lf_sfule_d 110010 00000 ..... ..... 0.. 00111101 @ab_pair
lf_sfult_d 110010 00000 ..... ..... 0.. 00111100 @ab_pair
lf_sfun_d 110010 00000 ..... ..... 0.. 00111110 @ab_pair
...@@ -121,10 +121,21 @@ static const VMStateDescription vmstate_env = { ...@@ -121,10 +121,21 @@ static const VMStateDescription vmstate_env = {
} }
}; };
static int cpu_post_load(void *opaque, int version_id)
{
OpenRISCCPU *cpu = opaque;
CPUOpenRISCState *env = &cpu->env;
/* Update env->fp_status to match env->fpcsr. */
cpu_set_fpcsr(env, env->fpcsr);
return 0;
}
const VMStateDescription vmstate_openrisc_cpu = { const VMStateDescription vmstate_openrisc_cpu = {
.name = "cpu", .name = "cpu",
.version_id = 1, .version_id = 1,
.minimum_version_id = 1, .minimum_version_id = 1,
.post_load = cpu_post_load,
.fields = (VMStateField[]) { .fields = (VMStateField[]) {
VMSTATE_CPU(), VMSTATE_CPU(),
VMSTATE_STRUCT(env, OpenRISCCPU, 1, vmstate_env, CPUOpenRISCState), VMSTATE_STRUCT(env, OpenRISCCPU, 1, vmstate_env, CPUOpenRISCState),
......
...@@ -37,12 +37,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) ...@@ -37,12 +37,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
target_ulong mr; target_ulong mr;
int idx; int idx;
#endif
switch (spr) { switch (spr) {
case TO_SPR(0, 0): /* VR */ #ifndef CONFIG_USER_ONLY
env->vr = rb;
break;
case TO_SPR(0, 11): /* EVBAR */ case TO_SPR(0, 11): /* EVBAR */
env->evbar = rb; env->evbar = rb;
break; break;
...@@ -62,10 +60,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) ...@@ -62,10 +60,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
cpu_set_sr(env, rb); cpu_set_sr(env, rb);
break; break;
case TO_SPR(0, 18): /* PPC */
env->ppc = rb;
break;
case TO_SPR(0, 32): /* EPCR */ case TO_SPR(0, 32): /* EPCR */
env->epcr = rb; env->epcr = rb;
break; break;
...@@ -187,10 +181,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) ...@@ -187,10 +181,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
} }
cpu_openrisc_timer_update(cpu); cpu_openrisc_timer_update(cpu);
break; break;
default: #endif
case TO_SPR(0, 20): /* FPCSR */
cpu_set_fpcsr(env, rb);
break; break;
} }
#endif
} }
target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
...@@ -201,23 +197,31 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, ...@@ -201,23 +197,31 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
OpenRISCCPU *cpu = env_archcpu(env); OpenRISCCPU *cpu = env_archcpu(env);
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
int idx; int idx;
#endif
switch (spr) { switch (spr) {
#ifndef CONFIG_USER_ONLY
case TO_SPR(0, 0): /* VR */ case TO_SPR(0, 0): /* VR */
return env->vr & SPR_VR; return env->vr;
case TO_SPR(0, 1): /* UPR */ case TO_SPR(0, 1): /* UPR */
return env->upr; /* TT, DM, IM, UP present */ return env->upr;
case TO_SPR(0, 2): /* CPUCFGR */ case TO_SPR(0, 2): /* CPUCFGR */
return env->cpucfgr; return env->cpucfgr;
case TO_SPR(0, 3): /* DMMUCFGR */ case TO_SPR(0, 3): /* DMMUCFGR */
return env->dmmucfgr; /* 1Way, 64 entries */ return env->dmmucfgr;
case TO_SPR(0, 4): /* IMMUCFGR */ case TO_SPR(0, 4): /* IMMUCFGR */
return env->immucfgr; return env->immucfgr;
case TO_SPR(0, 9): /* VR2 */
return env->vr2;
case TO_SPR(0, 10): /* AVR */
return env->avr;
case TO_SPR(0, 11): /* EVBAR */ case TO_SPR(0, 11): /* EVBAR */
return env->evbar; return env->evbar;
...@@ -305,11 +309,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, ...@@ -305,11 +309,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
case TO_SPR(10, 1): /* TTCR */ case TO_SPR(10, 1): /* TTCR */
cpu_openrisc_count_update(cpu); cpu_openrisc_count_update(cpu);
return cpu_openrisc_count_get(cpu); return cpu_openrisc_count_get(cpu);
#endif
default: case TO_SPR(0, 20): /* FPCSR */
break; return env->fpcsr;
} }
#endif
/* for rd is passed in, if rd unchanged, just keep it back. */ /* for rd is passed in, if rd unchanged, just keep it back. */
return rd; return rd;
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册