diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-09-05 09:33:01 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-09-05 09:33:01 +0100 |
commit | 500efcfcf0fe2e0dae1d25637a13435ce7b6e421 (patch) | |
tree | 3a79d3ae876bc02eea9bd1dbb4e4029fbd4b10d8 | |
parent | a8b5ad8e1faef0d1bb3e550530328e8ec76fe87c (diff) | |
parent | 9e3bab08d3e3f5808cc35a59af1912bfb6fe96fd (diff) |
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: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | linux-user/openrisc/target_elf.h | 2 | ||||
-rw-r--r-- | target/openrisc/cpu.c | 30 | ||||
-rw-r--r-- | target/openrisc/cpu.h | 24 | ||||
-rw-r--r-- | target/openrisc/disas.c | 81 | ||||
-rw-r--r-- | target/openrisc/fpu_helper.c | 49 | ||||
-rw-r--r-- | target/openrisc/helper.h | 6 | ||||
-rw-r--r-- | target/openrisc/insns.decode | 45 | ||||
-rw-r--r-- | target/openrisc/machine.c | 11 | ||||
-rw-r--r-- | target/openrisc/sys_helper.c | 36 | ||||
-rw-r--r-- | target/openrisc/translate.c | 710 |
10 files changed, 770 insertions, 224 deletions
diff --git a/linux-user/openrisc/target_elf.h b/linux-user/openrisc/target_elf.h index 40ceb025c9..265ecd3079 100644 --- a/linux-user/openrisc/target_elf.h +++ b/linux-user/openrisc/target_elf.h @@ -9,6 +9,6 @@ #define OPENRISC_TARGET_ELF_H static inline const char *cpu_get_model(uint32_t eflags) { - return "or1200"; + return "any"; } #endif diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c index f19e482a55..506aec6bfb 100644 --- a/target/openrisc/cpu.c +++ b/target/openrisc/cpu.c @@ -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) diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index 561f0f7fad..0ad02eab79 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -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 */ diff --git a/target/openrisc/disas.c b/target/openrisc/disas.c index 7091832347..ce112640b9 100644 --- a/target/openrisc/disas.c +++ b/target/openrisc/disas.c @@ -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) diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c index b9d2ebbb8c..59e1413279 100644 --- a/target/openrisc/fpu_helper.c +++ b/target/openrisc/fpu_helper.c @@ -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 diff --git a/target/openrisc/helper.h b/target/openrisc/helper.h index 96d79a8113..d847814a28 100644 --- a/target/openrisc/helper.h +++ b/target/openrisc/helper.h @@ -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(ftoid, TCG_CALL_NO_RWG, i64, env, i64) 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_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) FOP_CMP(eq) FOP_CMP(lt) FOP_CMP(le) +FOP_CMP(un) +FOP_CMP(ueq) +FOP_CMP(ule) +FOP_CMP(ult) #undef FOP_CMP /* interrupt */ diff --git a/target/openrisc/insns.decode b/target/openrisc/insns.decode index 7df81c1f22..0d6f7c29f8 100644 --- a/target/openrisc/insns.decode +++ b/target/openrisc/insns.decode @@ -22,6 +22,9 @@ &ab a b &dal d a l &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 @@ -99,6 +102,8 @@ l_maci 010011 ----- a:5 i:s16 l_movhi 000110 d:5 ----0 k:16 l_macrc 000110 d:5 ----1 00000000 00000000 +l_adrp 000010 d:5 i:s21 + #### # Arithmetic Instructions #### @@ -187,3 +192,43 @@ lf_sfgt_s 110010 ----- a:5 b:5 --- 00001010 lf_sfge_s 110010 ----- a:5 b:5 --- 00001011 lf_sflt_s 110010 ----- a:5 b:5 --- 00001100 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 diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c index 0a96404dc6..b92985d99b 100644 --- a/target/openrisc/machine.c +++ b/target/openrisc/machine.c @@ -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 = { .name = "cpu", .version_id = 1, .minimum_version_id = 1, + .post_load = cpu_post_load, .fields = (VMStateField[]) { VMSTATE_CPU(), VMSTATE_STRUCT(env, OpenRISCCPU, 1, vmstate_env, CPUOpenRISCState), diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index 1053409a04..d9fe6c5948 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -37,12 +37,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) CPUState *cs = env_cpu(env); target_ulong mr; int idx; +#endif switch (spr) { - case TO_SPR(0, 0): /* VR */ - env->vr = rb; - break; - +#ifndef CONFIG_USER_ONLY case TO_SPR(0, 11): /* EVBAR */ env->evbar = rb; break; @@ -62,10 +60,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) cpu_set_sr(env, rb); break; - case TO_SPR(0, 18): /* PPC */ - env->ppc = rb; - break; - case TO_SPR(0, 32): /* EPCR */ env->epcr = rb; break; @@ -187,10 +181,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) } cpu_openrisc_timer_update(cpu); break; - default: +#endif + + case TO_SPR(0, 20): /* FPCSR */ + cpu_set_fpcsr(env, rb); break; } -#endif } 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); CPUState *cs = env_cpu(env); int idx; +#endif switch (spr) { +#ifndef CONFIG_USER_ONLY case TO_SPR(0, 0): /* VR */ - return env->vr & SPR_VR; + return env->vr; case TO_SPR(0, 1): /* UPR */ - return env->upr; /* TT, DM, IM, UP present */ + return env->upr; case TO_SPR(0, 2): /* CPUCFGR */ return env->cpucfgr; case TO_SPR(0, 3): /* DMMUCFGR */ - return env->dmmucfgr; /* 1Way, 64 entries */ + return env->dmmucfgr; case TO_SPR(0, 4): /* 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 */ return env->evbar; @@ -305,11 +309,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, case TO_SPR(10, 1): /* TTCR */ cpu_openrisc_count_update(cpu); return cpu_openrisc_count_get(cpu); +#endif - default: - break; + case TO_SPR(0, 20): /* FPCSR */ + return env->fpcsr; } -#endif /* for rd is passed in, if rd unchanged, just keep it back. */ return rd; diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c index b189c506c5..6addbac8d6 100644 --- a/target/openrisc/translate.c +++ b/target/openrisc/translate.c @@ -45,9 +45,14 @@ typedef struct DisasContext { uint32_t mem_idx; uint32_t tb_flags; uint32_t delayed_branch; + uint32_t cpucfgr; + uint32_t avr; /* If not -1, jmp_pc contains this value and so is a direct jump. */ target_ulong jmp_pc_imm; + + /* The temporary corresponding to register 0 for this compilation. */ + TCGv R0; } DisasContext; static inline bool is_user(DisasContext *dc) @@ -63,8 +68,7 @@ static inline bool is_user(DisasContext *dc) #include "decode.inc.c" static TCGv cpu_sr; -static TCGv cpu_R[32]; -static TCGv cpu_R0; +static TCGv cpu_regs[32]; static TCGv cpu_pc; static TCGv jmp_pc; /* l.jr/l.jalr temp pc */ static TCGv cpu_ppc; @@ -117,12 +121,11 @@ void openrisc_translate_init(void) offsetof(CPUOpenRISCState, mac), "mac"); for (i = 0; i < 32; i++) { - cpu_R[i] = tcg_global_mem_new(cpu_env, - offsetof(CPUOpenRISCState, - shadow_gpr[0][i]), - regnames[i]); + cpu_regs[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUOpenRISCState, + shadow_gpr[0][i]), + regnames[i]); } - cpu_R0 = cpu_R[0]; } static void gen_exception(DisasContext *dc, unsigned int excp) @@ -139,38 +142,40 @@ static void gen_illegal_exception(DisasContext *dc) dc->base.is_jmp = DISAS_NORETURN; } -/* not used yet, open it when we need or64. */ -/*#ifdef TARGET_OPENRISC64 -static void check_ob64s(DisasContext *dc) +static bool check_v1_3(DisasContext *dc) { - if (!(dc->flags & CPUCFGR_OB64S)) { - gen_illegal_exception(dc); - } + return dc->avr >= 0x01030000; } -static void check_of64s(DisasContext *dc) +static bool check_of32s(DisasContext *dc) { - if (!(dc->flags & CPUCFGR_OF64S)) { - gen_illegal_exception(dc); - } + return dc->cpucfgr & CPUCFGR_OF32S; } -static void check_ov64s(DisasContext *dc) +static bool check_of64a32s(DisasContext *dc) { - if (!(dc->flags & CPUCFGR_OV64S)) { - gen_illegal_exception(dc); + return dc->cpucfgr & CPUCFGR_OF64A32S; +} + +static TCGv cpu_R(DisasContext *dc, int reg) +{ + if (reg == 0) { + return dc->R0; + } else { + return cpu_regs[reg]; } } -#endif*/ -/* We're about to write to REG. On the off-chance that the user is - writing to R0, re-instate the architectural register. */ -#define check_r0_write(reg) \ - do { \ - if (unlikely(reg == 0)) { \ - cpu_R[0] = cpu_R0; \ - } \ - } while (0) +/* + * We're about to write to REG. On the off-chance that the user is + * writing to R0, re-instate the architectural register. + */ +static void check_r0_write(DisasContext *dc, int reg) +{ + if (unlikely(reg == 0)) { + dc->R0 = cpu_regs[0]; + } +} static void gen_ove_cy(DisasContext *dc) { @@ -436,99 +441,99 @@ static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb) static bool trans_l_add(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - gen_add(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + gen_add(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_addc(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - gen_addc(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + gen_addc(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sub(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - gen_sub(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + gen_sub(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_and(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - tcg_gen_and_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + tcg_gen_and_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_or(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - tcg_gen_or_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + tcg_gen_or_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_xor(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - tcg_gen_xor_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + tcg_gen_xor_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sll(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - tcg_gen_shl_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + tcg_gen_shl_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_srl(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - tcg_gen_shr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + tcg_gen_shr_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sra(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - tcg_gen_sar_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + tcg_gen_sar_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_ror(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - tcg_gen_rotr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + tcg_gen_rotr_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_exths(DisasContext *dc, arg_da *a) { - check_r0_write(a->d); - tcg_gen_ext16s_tl(cpu_R[a->d], cpu_R[a->a]); + check_r0_write(dc, a->d); + tcg_gen_ext16s_tl(cpu_R(dc, a->d), cpu_R(dc, a->a)); return true; } static bool trans_l_extbs(DisasContext *dc, arg_da *a) { - check_r0_write(a->d); - tcg_gen_ext8s_tl(cpu_R[a->d], cpu_R[a->a]); + check_r0_write(dc, a->d); + tcg_gen_ext8s_tl(cpu_R(dc, a->d), cpu_R(dc, a->a)); return true; } static bool trans_l_exthz(DisasContext *dc, arg_da *a) { - check_r0_write(a->d); - tcg_gen_ext16u_tl(cpu_R[a->d], cpu_R[a->a]); + check_r0_write(dc, a->d); + tcg_gen_ext16u_tl(cpu_R(dc, a->d), cpu_R(dc, a->a)); return true; } static bool trans_l_extbz(DisasContext *dc, arg_da *a) { - check_r0_write(a->d); - tcg_gen_ext8u_tl(cpu_R[a->d], cpu_R[a->a]); + check_r0_write(dc, a->d); + tcg_gen_ext8u_tl(cpu_R(dc, a->d), cpu_R(dc, a->a)); return true; } @@ -536,67 +541,67 @@ static bool trans_l_cmov(DisasContext *dc, arg_dab *a) { TCGv zero; - check_r0_write(a->d); + check_r0_write(dc, a->d); zero = tcg_const_tl(0); - tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[a->d], cpu_sr_f, zero, - cpu_R[a->a], cpu_R[a->b]); + tcg_gen_movcond_tl(TCG_COND_NE, cpu_R(dc, a->d), cpu_sr_f, zero, + cpu_R(dc, a->a), cpu_R(dc, a->b)); tcg_temp_free(zero); return true; } static bool trans_l_ff1(DisasContext *dc, arg_da *a) { - check_r0_write(a->d); - tcg_gen_ctzi_tl(cpu_R[a->d], cpu_R[a->a], -1); - tcg_gen_addi_tl(cpu_R[a->d], cpu_R[a->d], 1); + check_r0_write(dc, a->d); + tcg_gen_ctzi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), -1); + tcg_gen_addi_tl(cpu_R(dc, a->d), cpu_R(dc, a->d), 1); return true; } static bool trans_l_fl1(DisasContext *dc, arg_da *a) { - check_r0_write(a->d); - tcg_gen_clzi_tl(cpu_R[a->d], cpu_R[a->a], TARGET_LONG_BITS); - tcg_gen_subfi_tl(cpu_R[a->d], TARGET_LONG_BITS, cpu_R[a->d]); + check_r0_write(dc, a->d); + tcg_gen_clzi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), TARGET_LONG_BITS); + tcg_gen_subfi_tl(cpu_R(dc, a->d), TARGET_LONG_BITS, cpu_R(dc, a->d)); return true; } static bool trans_l_mul(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - gen_mul(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + gen_mul(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_mulu(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - gen_mulu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + gen_mulu(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_div(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - gen_div(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + gen_div(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_divu(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - gen_divu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); + check_r0_write(dc, a->d); + gen_divu(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_muld(DisasContext *dc, arg_ab *a) { - gen_muld(dc, cpu_R[a->a], cpu_R[a->b]); + gen_muld(dc, cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_muldu(DisasContext *dc, arg_ab *a) { - gen_muldu(dc, cpu_R[a->a], cpu_R[a->b]); + gen_muldu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } @@ -615,7 +620,7 @@ static bool trans_l_jal(DisasContext *dc, arg_l_jal *a) target_ulong tmp_pc = dc->base.pc_next + a->n * 4; target_ulong ret_pc = dc->base.pc_next + 8; - tcg_gen_movi_tl(cpu_R[9], ret_pc); + tcg_gen_movi_tl(cpu_regs[9], ret_pc); /* Optimize jal being used to load the PC for PIC. */ if (tmp_pc != ret_pc) { tcg_gen_movi_tl(jmp_pc, tmp_pc); @@ -654,15 +659,15 @@ static bool trans_l_bnf(DisasContext *dc, arg_l_bf *a) static bool trans_l_jr(DisasContext *dc, arg_l_jr *a) { - tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]); + tcg_gen_mov_tl(jmp_pc, cpu_R(dc, a->b)); dc->delayed_branch = 2; return true; } static bool trans_l_jalr(DisasContext *dc, arg_l_jalr *a) { - tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]); - tcg_gen_movi_tl(cpu_R[9], dc->base.pc_next + 8); + tcg_gen_mov_tl(jmp_pc, cpu_R(dc, a->b)); + tcg_gen_movi_tl(cpu_regs[9], dc->base.pc_next + 8); dc->delayed_branch = 2; return true; } @@ -671,12 +676,12 @@ static bool trans_l_lwa(DisasContext *dc, arg_load *a) { TCGv ea; - check_r0_write(a->d); + check_r0_write(dc, a->d); ea = tcg_temp_new(); - tcg_gen_addi_tl(ea, cpu_R[a->a], a->i); - tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, MO_TEUL); + tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i); + tcg_gen_qemu_ld_tl(cpu_R(dc, a->d), ea, dc->mem_idx, MO_TEUL); tcg_gen_mov_tl(cpu_lock_addr, ea); - tcg_gen_mov_tl(cpu_lock_value, cpu_R[a->d]); + tcg_gen_mov_tl(cpu_lock_value, cpu_R(dc, a->d)); tcg_temp_free(ea); return true; } @@ -685,10 +690,10 @@ static void do_load(DisasContext *dc, arg_load *a, MemOp mop) { TCGv ea; - check_r0_write(a->d); + check_r0_write(dc, a->d); ea = tcg_temp_new(); - tcg_gen_addi_tl(ea, cpu_R[a->a], a->i); - tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, mop); + tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i); + tcg_gen_qemu_ld_tl(cpu_R(dc, a->d), ea, dc->mem_idx, mop); tcg_temp_free(ea); } @@ -734,13 +739,13 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a) TCGLabel *lab_fail, *lab_done; ea = tcg_temp_new(); - tcg_gen_addi_tl(ea, cpu_R[a->a], a->i); + tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i); /* For TB_FLAGS_R0_0, the branch below invalidates the temporary assigned - to cpu_R[0]. Since l.swa is quite often immediately followed by a + to cpu_regs[0]. Since l.swa is quite often immediately followed by a branch, don't bother reallocating; finish the TB using the "real" R0. This also takes care of RB input across the branch. */ - cpu_R[0] = cpu_R0; + dc->R0 = cpu_regs[0]; lab_fail = gen_new_label(); lab_done = gen_new_label(); @@ -749,7 +754,7 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a) val = tcg_temp_new(); tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value, - cpu_R[a->b], dc->mem_idx, MO_TEUL); + cpu_regs[a->b], dc->mem_idx, MO_TEUL); tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value); tcg_temp_free(val); @@ -766,8 +771,8 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a) static void do_store(DisasContext *dc, arg_store *a, MemOp mop) { TCGv t0 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_R[a->a], a->i); - tcg_gen_qemu_st_tl(cpu_R[a->b], t0, dc->mem_idx, mop); + tcg_gen_addi_tl(t0, cpu_R(dc, a->a), a->i); + tcg_gen_qemu_st_tl(cpu_R(dc, a->b), t0, dc->mem_idx, mop); tcg_temp_free(t0); } @@ -794,13 +799,26 @@ static bool trans_l_nop(DisasContext *dc, arg_l_nop *a) return true; } +static bool trans_l_adrp(DisasContext *dc, arg_l_adrp *a) +{ + if (!check_v1_3(dc)) { + return false; + } + check_r0_write(dc, a->d); + + tcg_gen_movi_i32(cpu_R(dc, a->d), + (dc->base.pc_next & TARGET_PAGE_MASK) + + ((target_long)a->i << TARGET_PAGE_BITS)); + return true; +} + static bool trans_l_addi(DisasContext *dc, arg_rri *a) { TCGv t0; - check_r0_write(a->d); + check_r0_write(dc, a->d); t0 = tcg_const_tl(a->i); - gen_add(dc, cpu_R[a->d], cpu_R[a->a], t0); + gen_add(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), t0); tcg_temp_free(t0); return true; } @@ -809,9 +827,9 @@ static bool trans_l_addic(DisasContext *dc, arg_rri *a) { TCGv t0; - check_r0_write(a->d); + check_r0_write(dc, a->d); t0 = tcg_const_tl(a->i); - gen_addc(dc, cpu_R[a->d], cpu_R[a->a], t0); + gen_addc(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), t0); tcg_temp_free(t0); return true; } @@ -820,9 +838,9 @@ static bool trans_l_muli(DisasContext *dc, arg_rri *a) { TCGv t0; - check_r0_write(a->d); + check_r0_write(dc, a->d); t0 = tcg_const_tl(a->i); - gen_mul(dc, cpu_R[a->d], cpu_R[a->a], t0); + gen_mul(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), t0); tcg_temp_free(t0); return true; } @@ -832,42 +850,42 @@ static bool trans_l_maci(DisasContext *dc, arg_l_maci *a) TCGv t0; t0 = tcg_const_tl(a->i); - gen_mac(dc, cpu_R[a->a], t0); + gen_mac(dc, cpu_R(dc, a->a), t0); tcg_temp_free(t0); return true; } static bool trans_l_andi(DisasContext *dc, arg_rrk *a) { - check_r0_write(a->d); - tcg_gen_andi_tl(cpu_R[a->d], cpu_R[a->a], a->k); + check_r0_write(dc, a->d); + tcg_gen_andi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->k); return true; } static bool trans_l_ori(DisasContext *dc, arg_rrk *a) { - check_r0_write(a->d); - tcg_gen_ori_tl(cpu_R[a->d], cpu_R[a->a], a->k); + check_r0_write(dc, a->d); + tcg_gen_ori_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->k); return true; } static bool trans_l_xori(DisasContext *dc, arg_rri *a) { - check_r0_write(a->d); - tcg_gen_xori_tl(cpu_R[a->d], cpu_R[a->a], a->i); + check_r0_write(dc, a->d); + tcg_gen_xori_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->i); return true; } static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a) { - check_r0_write(a->d); + check_r0_write(dc, a->d); if (is_user(dc)) { gen_illegal_exception(dc); } else { TCGv spr = tcg_temp_new(); - tcg_gen_ori_tl(spr, cpu_R[a->a], a->k); - gen_helper_mfspr(cpu_R[a->d], cpu_env, cpu_R[a->d], spr); + tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k); + gen_helper_mfspr(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d), spr); tcg_temp_free(spr); } return true; @@ -894,8 +912,8 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a) dc->base.is_jmp = DISAS_EXIT; spr = tcg_temp_new(); - tcg_gen_ori_tl(spr, cpu_R[a->a], a->k); - gen_helper_mtspr(cpu_env, spr, cpu_R[a->b]); + tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k); + gen_helper_mtspr(cpu_env, spr, cpu_R(dc, a->b)); tcg_temp_free(spr); } return true; @@ -903,188 +921,202 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a) static bool trans_l_mac(DisasContext *dc, arg_ab *a) { - gen_mac(dc, cpu_R[a->a], cpu_R[a->b]); + gen_mac(dc, cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_msb(DisasContext *dc, arg_ab *a) { - gen_msb(dc, cpu_R[a->a], cpu_R[a->b]); + gen_msb(dc, cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_macu(DisasContext *dc, arg_ab *a) { - gen_macu(dc, cpu_R[a->a], cpu_R[a->b]); + gen_macu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_msbu(DisasContext *dc, arg_ab *a) { - gen_msbu(dc, cpu_R[a->a], cpu_R[a->b]); + gen_msbu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_slli(DisasContext *dc, arg_dal *a) { - check_r0_write(a->d); - tcg_gen_shli_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1)); + check_r0_write(dc, a->d); + tcg_gen_shli_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), + a->l & (TARGET_LONG_BITS - 1)); return true; } static bool trans_l_srli(DisasContext *dc, arg_dal *a) { - check_r0_write(a->d); - tcg_gen_shri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1)); + check_r0_write(dc, a->d); + tcg_gen_shri_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), + a->l & (TARGET_LONG_BITS - 1)); return true; } static bool trans_l_srai(DisasContext *dc, arg_dal *a) { - check_r0_write(a->d); - tcg_gen_sari_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1)); + check_r0_write(dc, a->d); + tcg_gen_sari_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), + a->l & (TARGET_LONG_BITS - 1)); return true; } static bool trans_l_rori(DisasContext *dc, arg_dal *a) { - check_r0_write(a->d); - tcg_gen_rotri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1)); + check_r0_write(dc, a->d); + tcg_gen_rotri_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), + a->l & (TARGET_LONG_BITS - 1)); return true; } static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a) { - check_r0_write(a->d); - tcg_gen_movi_tl(cpu_R[a->d], a->k << 16); + check_r0_write(dc, a->d); + tcg_gen_movi_tl(cpu_R(dc, a->d), a->k << 16); return true; } static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a) { - check_r0_write(a->d); - tcg_gen_trunc_i64_tl(cpu_R[a->d], cpu_mac); + check_r0_write(dc, a->d); + tcg_gen_trunc_i64_tl(cpu_R(dc, a->d), cpu_mac); tcg_gen_movi_i64(cpu_mac, 0); return true; } static bool trans_l_sfeq(DisasContext *dc, arg_ab *a) { - tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); + tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, + cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sfne(DisasContext *dc, arg_ab *a) { - tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); + tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, + cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sfgtu(DisasContext *dc, arg_ab *a) { - tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); + tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, + cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sfgeu(DisasContext *dc, arg_ab *a) { - tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); + tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, + cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sfltu(DisasContext *dc, arg_ab *a) { - tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); + tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, + cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sfleu(DisasContext *dc, arg_ab *a) { - tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); + tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, + cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sfgts(DisasContext *dc, arg_ab *a) { - tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); + tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, + cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sfges(DisasContext *dc, arg_ab *a) { - tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); + tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, + cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sflts(DisasContext *dc, arg_ab *a) { - tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); + tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, + cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sfles(DisasContext *dc, arg_ab *a) { - tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); + tcg_gen_setcond_tl(TCG_COND_LE, + cpu_sr_f, cpu_R(dc, a->a), cpu_R(dc, a->b)); return true; } static bool trans_l_sfeqi(DisasContext *dc, arg_ai *a) { - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], a->i); + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R(dc, a->a), a->i); return true; } static bool trans_l_sfnei(DisasContext *dc, arg_ai *a) { - tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], a->i); + tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R(dc, a->a), a->i); return true; } static bool trans_l_sfgtui(DisasContext *dc, arg_ai *a) { - tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], a->i); + tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R(dc, a->a), a->i); return true; } static bool trans_l_sfgeui(DisasContext *dc, arg_ai *a) { - tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], a->i); + tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R(dc, a->a), a->i); return true; } static bool trans_l_sfltui(DisasContext *dc, arg_ai *a) { - tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], a->i); + tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R(dc, a->a), a->i); return true; } static bool trans_l_sfleui(DisasContext *dc, arg_ai *a) { - tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], a->i); + tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R(dc, a->a), a->i); return true; } static bool trans_l_sfgtsi(DisasContext *dc, arg_ai *a) { - tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], a->i); + tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R(dc, a->a), a->i); return true; } static bool trans_l_sfgesi(DisasContext *dc, arg_ai *a) { - tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], a->i); + tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R(dc, a->a), a->i); return true; } static bool trans_l_sfltsi(DisasContext *dc, arg_ai *a) { - tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], a->i); + tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R(dc, a->a), a->i); return true; } static bool trans_l_sflesi(DisasContext *dc, arg_ai *a) { - tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], a->i); + tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R(dc, a->a), a->i); return true; } @@ -1131,124 +1163,430 @@ static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a) return true; } -static void do_fp2(DisasContext *dc, arg_da *a, +static bool do_fp2(DisasContext *dc, arg_da *a, void (*fn)(TCGv, TCGv_env, TCGv)) { - check_r0_write(a->d); - fn(cpu_R[a->d], cpu_env, cpu_R[a->a]); + if (!check_of32s(dc)) { + return false; + } + check_r0_write(dc, a->d); + fn(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->a)); gen_helper_update_fpcsr(cpu_env); + return true; } -static void do_fp3(DisasContext *dc, arg_dab *a, +static bool do_fp3(DisasContext *dc, arg_dab *a, void (*fn)(TCGv, TCGv_env, TCGv, TCGv)) { - check_r0_write(a->d); - fn(cpu_R[a->d], cpu_env, cpu_R[a->a], cpu_R[a->b]); + if (!check_of32s(dc)) { + return false; + } + check_r0_write(dc, a->d); + fn(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->a), cpu_R(dc, a->b)); gen_helper_update_fpcsr(cpu_env); + return true; } -static void do_fpcmp(DisasContext *dc, arg_ab *a, +static bool do_fpcmp(DisasContext *dc, arg_ab *a, void (*fn)(TCGv, TCGv_env, TCGv, TCGv), bool inv, bool swap) { + if (!check_of32s(dc)) { + return false; + } if (swap) { - fn(cpu_sr_f, cpu_env, cpu_R[a->b], cpu_R[a->a]); + fn(cpu_sr_f, cpu_env, cpu_R(dc, a->b), cpu_R(dc, a->a)); } else { - fn(cpu_sr_f, cpu_env, cpu_R[a->a], cpu_R[a->b]); + fn(cpu_sr_f, cpu_env, cpu_R(dc, a->a), cpu_R(dc, a->b)); } if (inv) { tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1); } gen_helper_update_fpcsr(cpu_env); + return true; } static bool trans_lf_add_s(DisasContext *dc, arg_dab *a) { - do_fp3(dc, a, gen_helper_float_add_s); - return true; + return do_fp3(dc, a, gen_helper_float_add_s); } static bool trans_lf_sub_s(DisasContext *dc, arg_dab *a) { - do_fp3(dc, a, gen_helper_float_sub_s); - return true; + return do_fp3(dc, a, gen_helper_float_sub_s); } static bool trans_lf_mul_s(DisasContext *dc, arg_dab *a) { - do_fp3(dc, a, gen_helper_float_mul_s); - return true; + return do_fp3(dc, a, gen_helper_float_mul_s); } static bool trans_lf_div_s(DisasContext *dc, arg_dab *a) { - do_fp3(dc, a, gen_helper_float_div_s); - return true; + return do_fp3(dc, a, gen_helper_float_div_s); } static bool trans_lf_rem_s(DisasContext *dc, arg_dab *a) { - do_fp3(dc, a, gen_helper_float_rem_s); + return do_fp3(dc, a, gen_helper_float_rem_s); return true; } static bool trans_lf_itof_s(DisasContext *dc, arg_da *a) { - do_fp2(dc, a, gen_helper_itofs); - return true; + return do_fp2(dc, a, gen_helper_itofs); } static bool trans_lf_ftoi_s(DisasContext *dc, arg_da *a) { - do_fp2(dc, a, gen_helper_ftois); - return true; + return do_fp2(dc, a, gen_helper_ftois); } static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a) { - check_r0_write(a->d); - gen_helper_float_madd_s(cpu_R[a->d], cpu_env, cpu_R[a->d], - cpu_R[a->a], cpu_R[a->b]); + if (!check_of32s(dc)) { + return false; + } + check_r0_write(dc, a->d); + gen_helper_float_madd_s(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d), + cpu_R(dc, a->a), cpu_R(dc, a->b)); gen_helper_update_fpcsr(cpu_env); return true; } static bool trans_lf_sfeq_s(DisasContext *dc, arg_ab *a) { - do_fpcmp(dc, a, gen_helper_float_eq_s, false, false); - return true; + return do_fpcmp(dc, a, gen_helper_float_eq_s, false, false); } static bool trans_lf_sfne_s(DisasContext *dc, arg_ab *a) { - do_fpcmp(dc, a, gen_helper_float_eq_s, true, false); - return true; + return do_fpcmp(dc, a, gen_helper_float_eq_s, true, false); } static bool trans_lf_sfgt_s(DisasContext *dc, arg_ab *a) { - do_fpcmp(dc, a, gen_helper_float_lt_s, false, true); - return true; + return do_fpcmp(dc, a, gen_helper_float_lt_s, false, true); } static bool trans_lf_sfge_s(DisasContext *dc, arg_ab *a) { - do_fpcmp(dc, a, gen_helper_float_le_s, false, true); - return true; + return do_fpcmp(dc, a, gen_helper_float_le_s, false, true); } static bool trans_lf_sflt_s(DisasContext *dc, arg_ab *a) { - do_fpcmp(dc, a, gen_helper_float_lt_s, false, false); - return true; + return do_fpcmp(dc, a, gen_helper_float_lt_s, false, false); } static bool trans_lf_sfle_s(DisasContext *dc, arg_ab *a) { - do_fpcmp(dc, a, gen_helper_float_le_s, false, false); + return do_fpcmp(dc, a, gen_helper_float_le_s, false, false); +} + +static bool trans_lf_sfueq_s(DisasContext *dc, arg_ab *a) +{ + if (!check_v1_3(dc)) { + return false; + } + return do_fpcmp(dc, a, gen_helper_float_ueq_s, false, false); +} + +static bool trans_lf_sfult_s(DisasContext *dc, arg_ab *a) +{ + if (!check_v1_3(dc)) { + return false; + } + return do_fpcmp(dc, a, gen_helper_float_ult_s, false, false); +} + +static bool trans_lf_sfugt_s(DisasContext *dc, arg_ab *a) +{ + if (!check_v1_3(dc)) { + return false; + } + return do_fpcmp(dc, a, gen_helper_float_ult_s, false, true); +} + +static bool trans_lf_sfule_s(DisasContext *dc, arg_ab *a) +{ + if (!check_v1_3(dc)) { + return false; + } + return do_fpcmp(dc, a, gen_helper_float_ule_s, false, false); +} + +static bool trans_lf_sfuge_s(DisasContext *dc, arg_ab *a) +{ + if (!check_v1_3(dc)) { + return false; + } + return do_fpcmp(dc, a, gen_helper_float_ule_s, false, true); +} + +static bool trans_lf_sfun_s(DisasContext *dc, arg_ab *a) +{ + if (!check_v1_3(dc)) { + return false; + } + return do_fpcmp(dc, a, gen_helper_float_un_s, false, false); +} + +static bool check_pair(DisasContext *dc, int r, int p) +{ + return r + 1 + p < 32; +} + +static void load_pair(DisasContext *dc, TCGv_i64 t, int r, int p) +{ + tcg_gen_concat_i32_i64(t, cpu_R(dc, r + 1 + p), cpu_R(dc, r)); +} + +static void save_pair(DisasContext *dc, TCGv_i64 t, int r, int p) +{ + tcg_gen_extr_i64_i32(cpu_R(dc, r + 1 + p), cpu_R(dc, r), t); +} + +static bool do_dp3(DisasContext *dc, arg_dab_pair *a, + void (*fn)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64)) +{ + TCGv_i64 t0, t1; + + if (!check_of64a32s(dc) || + !check_pair(dc, a->a, a->ap) || + !check_pair(dc, a->b, a->bp) || + !check_pair(dc, a->d, a->dp)) { + return false; + } + check_r0_write(dc, a->d); + + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + load_pair(dc, t0, a->a, a->ap); + load_pair(dc, t1, a->b, a->bp); + fn(t0, cpu_env, t0, t1); + save_pair(dc, t0, a->d, a->dp); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + + gen_helper_update_fpcsr(cpu_env); + return true; +} + +static bool do_dp2(DisasContext *dc, arg_da_pair *a, + void (*fn)(TCGv_i64, TCGv_env, TCGv_i64)) +{ + TCGv_i64 t0; + + if (!check_of64a32s(dc) || + !check_pair(dc, a->a, a->ap) || + !check_pair(dc, a->d, a->dp)) { + return false; + } + check_r0_write(dc, a->d); + + t0 = tcg_temp_new_i64(); + load_pair(dc, t0, a->a, a->ap); + fn(t0, cpu_env, t0); + save_pair(dc, t0, a->d, a->dp); + tcg_temp_free_i64(t0); + + gen_helper_update_fpcsr(cpu_env); return true; } +static bool do_dpcmp(DisasContext *dc, arg_ab_pair *a, + void (*fn)(TCGv, TCGv_env, TCGv_i64, TCGv_i64), + bool inv, bool swap) +{ + TCGv_i64 t0, t1; + + if (!check_of64a32s(dc) || + !check_pair(dc, a->a, a->ap) || + !check_pair(dc, a->b, a->bp)) { + return false; + } + + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + load_pair(dc, t0, a->a, a->ap); + load_pair(dc, t1, a->b, a->bp); + if (swap) { + fn(cpu_sr_f, cpu_env, t1, t0); + } else { + fn(cpu_sr_f, cpu_env, t0, t1); + } + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + + if (inv) { + tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1); + } + gen_helper_update_fpcsr(cpu_env); + return true; +} + +static bool trans_lf_add_d(DisasContext *dc, arg_dab_pair *a) +{ + return do_dp3(dc, a, gen_helper_float_add_d); +} + +static bool trans_lf_sub_d(DisasContext *dc, arg_dab_pair *a) +{ + return do_dp3(dc, a, gen_helper_float_sub_d); +} + +static bool trans_lf_mul_d(DisasContext *dc, arg_dab_pair *a) +{ + return do_dp3(dc, a, gen_helper_float_mul_d); +} + +static bool trans_lf_div_d(DisasContext *dc, arg_dab_pair *a) +{ + return do_dp3(dc, a, gen_helper_float_div_d); +} + +static bool trans_lf_rem_d(DisasContext *dc, arg_dab_pair *a) +{ + return do_dp3(dc, a, gen_helper_float_rem_d); +} + +static bool trans_lf_itof_d(DisasContext *dc, arg_da_pair *a) +{ + return do_dp2(dc, a, gen_helper_itofd); +} + +static bool trans_lf_ftoi_d(DisasContext *dc, arg_da_pair *a) +{ + return do_dp2(dc, a, gen_helper_ftoid); +} + +static bool trans_lf_stod_d(DisasContext *dc, arg_lf_stod_d *a) +{ + TCGv_i64 t0; + + if (!check_of64a32s(dc) || + !check_pair(dc, a->d, a->dp)) { + return false; + } + check_r0_write(dc, a->d); + + t0 = tcg_temp_new_i64(); + gen_helper_stod(t0, cpu_env, cpu_R(dc, a->a)); + save_pair(dc, t0, a->d, a->dp); + tcg_temp_free_i64(t0); + + gen_helper_update_fpcsr(cpu_env); + return true; +} + +static bool trans_lf_dtos_d(DisasContext *dc, arg_lf_dtos_d *a) +{ + TCGv_i64 t0; + + if (!check_of64a32s(dc) || + !check_pair(dc, a->a, a->ap)) { + return false; + } + check_r0_write(dc, a->d); + + t0 = tcg_temp_new_i64(); + load_pair(dc, t0, a->a, a->ap); + gen_helper_dtos(cpu_R(dc, a->d), cpu_env, t0); + tcg_temp_free_i64(t0); + + gen_helper_update_fpcsr(cpu_env); + return true; +} + +static bool trans_lf_madd_d(DisasContext *dc, arg_dab_pair *a) +{ + TCGv_i64 t0, t1, t2; + + if (!check_of64a32s(dc) || + !check_pair(dc, a->a, a->ap) || + !check_pair(dc, a->b, a->bp) || + !check_pair(dc, a->d, a->dp)) { + return false; + } + check_r0_write(dc, a->d); + + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + t2 = tcg_temp_new_i64(); + load_pair(dc, t0, a->d, a->dp); + load_pair(dc, t1, a->a, a->ap); + load_pair(dc, t2, a->b, a->bp); + gen_helper_float_madd_d(t0, cpu_env, t0, t1, t2); + save_pair(dc, t0, a->d, a->dp); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + tcg_temp_free_i64(t2); + + gen_helper_update_fpcsr(cpu_env); + return true; +} + +static bool trans_lf_sfeq_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_eq_d, false, false); +} + +static bool trans_lf_sfne_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_eq_d, true, false); +} + +static bool trans_lf_sfgt_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_lt_d, false, true); +} + +static bool trans_lf_sfge_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_le_d, false, true); +} + +static bool trans_lf_sflt_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_lt_d, false, false); +} + +static bool trans_lf_sfle_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_le_d, false, false); +} + +static bool trans_lf_sfueq_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_ueq_d, false, false); +} + +static bool trans_lf_sfule_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_ule_d, false, false); +} + +static bool trans_lf_sfuge_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_ule_d, false, true); +} + +static bool trans_lf_sfult_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_ult_d, false, false); +} + +static bool trans_lf_sfugt_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_ult_d, false, true); +} + +static bool trans_lf_sfun_d(DisasContext *dc, arg_ab_pair *a) +{ + return do_dpcmp(dc, a, gen_helper_float_un_d, false, false); +} + static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs) { DisasContext *dc = container_of(dcb, DisasContext, base); @@ -1258,6 +1596,8 @@ static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs) dc->mem_idx = cpu_mmu_index(env, false); dc->tb_flags = dc->base.tb->flags; dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0; + dc->cpucfgr = env->cpucfgr; + dc->avr = env->avr; dc->jmp_pc_imm = -1; bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4; @@ -1271,9 +1611,9 @@ static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs) /* Allow the TCG optimizer to see that R0 == 0, when it's true, which is the common case. */ if (dc->tb_flags & TB_FLAGS_R0_0) { - cpu_R[0] = tcg_const_tl(0); + dc->R0 = tcg_const_tl(0); } else { - cpu_R[0] = cpu_R0; + dc->R0 = cpu_regs[0]; } } |