diff options
| -rw-r--r-- | MAINTAINERS | 6 | ||||
| -rw-r--r-- | accel/tcg/atomic_template.h | 87 | ||||
| -rw-r--r-- | docs/devel/tracing.txt | 5 | ||||
| -rw-r--r-- | hw/mips/boston.c | 3 | ||||
| -rw-r--r-- | hw/mips/mips_malta.c | 2 | ||||
| -rw-r--r-- | hw/pci-host/xilinx-pcie.c | 5 | ||||
| -rw-r--r-- | include/exec/cpu_ldst_useronly_template.h | 11 | ||||
| -rw-r--r-- | migration/trace-events | 2 | ||||
| -rw-r--r-- | qapi/trace-events | 2 | ||||
| -rw-r--r-- | scripts/tracetool/__init__.py | 2 | ||||
| -rw-r--r-- | target/mips/gdbstub.c | 3 | ||||
| -rw-r--r-- | target/mips/op_helper.c | 3 | ||||
| -rw-r--r-- | target/mips/translate.c | 28 | ||||
| -rw-r--r-- | trace/mem-internal.h | 54 | ||||
| -rw-r--r-- | trace/mem.h | 2 |
15 files changed, 156 insertions, 59 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 8c626f6a07..42a1892d6a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -187,7 +187,7 @@ F: disas/microblaze.c MIPS M: Aurelien Jarno <aurelien@aurel32.net> -M: Yongbok Kim <yongbok.kim@mips.com> +M: Aleksandar Markovic <aleksandar.markovic@mips.com> S: Maintained F: target/mips/ F: hw/mips/ @@ -718,7 +718,7 @@ S: Maintained F: hw/mips/mips_malta.c Mipssim -M: Yongbok Kim <yongbok.kim@mips.com> +M: Aleksandar Markovic <aleksandar.markovic@mips.com> S: Odd Fixes F: hw/mips/mips_mipssim.c F: hw/net/mipsnet.c @@ -729,7 +729,7 @@ S: Maintained F: hw/mips/mips_r4k.c Fulong 2E -M: Yongbok Kim <yongbok.kim@mips.com> +M: Aleksandar Markovic <aleksandar.markovic@mips.com> S: Odd Fixes F: hw/mips/mips_fulong2e.c F: hw/isa/vt82c686.c diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h index 3f41ef2782..d751bcba48 100644 --- a/accel/tcg/atomic_template.h +++ b/accel/tcg/atomic_template.h @@ -18,30 +18,37 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include "trace/mem.h" + #if DATA_SIZE == 16 # define SUFFIX o # define DATA_TYPE Int128 # define BSWAP bswap128 +# define SHIFT 4 #elif DATA_SIZE == 8 # define SUFFIX q # define DATA_TYPE uint64_t # define SDATA_TYPE int64_t # define BSWAP bswap64 +# define SHIFT 3 #elif DATA_SIZE == 4 # define SUFFIX l # define DATA_TYPE uint32_t # define SDATA_TYPE int32_t # define BSWAP bswap32 +# define SHIFT 2 #elif DATA_SIZE == 2 # define SUFFIX w # define DATA_TYPE uint16_t # define SDATA_TYPE int16_t # define BSWAP bswap16 +# define SHIFT 1 #elif DATA_SIZE == 1 # define SUFFIX b # define DATA_TYPE uint8_t # define SDATA_TYPE int8_t # define BSWAP +# define SHIFT 0 #else # error unsupported data size #endif @@ -52,14 +59,37 @@ # define ABI_TYPE uint32_t #endif +#define ATOMIC_TRACE_RMW do { \ + uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false); \ + \ + trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info); \ + trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, \ + info | TRACE_MEM_ST); \ + } while (0) + +#define ATOMIC_TRACE_LD do { \ + uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false); \ + \ + trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info); \ + } while (0) + +# define ATOMIC_TRACE_ST do { \ + uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, true); \ + \ + trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info); \ + } while (0) + /* Define host-endian atomic operations. Note that END is used within the ATOMIC_NAME macro, and redefined below. */ #if DATA_SIZE == 1 # define END +# define MEND _be /* either le or be would be fine */ #elif defined(HOST_WORDS_BIGENDIAN) # define END _be +# define MEND _be #else # define END _le +# define MEND _le #endif ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr, @@ -67,7 +97,10 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr, { ATOMIC_MMU_DECLS; DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; - DATA_TYPE ret = atomic_cmpxchg__nocheck(haddr, cmpv, newv); + DATA_TYPE ret; + + ATOMIC_TRACE_RMW; + ret = atomic_cmpxchg__nocheck(haddr, cmpv, newv); ATOMIC_MMU_CLEANUP; return ret; } @@ -77,6 +110,8 @@ ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS) { ATOMIC_MMU_DECLS; DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP; + + ATOMIC_TRACE_LD; __atomic_load(haddr, &val, __ATOMIC_RELAXED); ATOMIC_MMU_CLEANUP; return val; @@ -87,6 +122,8 @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr, { ATOMIC_MMU_DECLS; DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; + + ATOMIC_TRACE_ST; __atomic_store(haddr, &val, __ATOMIC_RELAXED); ATOMIC_MMU_CLEANUP; } @@ -96,7 +133,10 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, { ATOMIC_MMU_DECLS; DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; - DATA_TYPE ret = atomic_xchg__nocheck(haddr, val); + DATA_TYPE ret; + + ATOMIC_TRACE_RMW; + ret = atomic_xchg__nocheck(haddr, val); ATOMIC_MMU_CLEANUP; return ret; } @@ -107,7 +147,10 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \ { \ ATOMIC_MMU_DECLS; \ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \ - DATA_TYPE ret = atomic_##X(haddr, val); \ + DATA_TYPE ret; \ + \ + ATOMIC_TRACE_RMW; \ + ret = atomic_##X(haddr, val); \ ATOMIC_MMU_CLEANUP; \ return ret; \ } @@ -126,6 +169,9 @@ GEN_ATOMIC_HELPER(xor_fetch) /* These helpers are, as a whole, full barriers. Within the helper, * the leading barrier is explicit and the trailing barrier is within * cmpxchg primitive. + * + * Trace this load + RMW loop as a single RMW op. This way, regardless + * of CF_PARALLEL's value, we'll trace just a read and a write. */ #define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET) \ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \ @@ -134,6 +180,8 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \ ATOMIC_MMU_DECLS; \ XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \ XDATA_TYPE cmp, old, new, val = xval; \ + \ + ATOMIC_TRACE_RMW; \ smp_mb(); \ cmp = atomic_read__nocheck(haddr); \ do { \ @@ -158,6 +206,7 @@ GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new) #endif /* DATA SIZE >= 16 */ #undef END +#undef MEND #if DATA_SIZE > 1 @@ -165,8 +214,10 @@ GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new) within the ATOMIC_NAME macro. */ #ifdef HOST_WORDS_BIGENDIAN # define END _le +# define MEND _le #else # define END _be +# define MEND _be #endif ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr, @@ -174,7 +225,10 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr, { ATOMIC_MMU_DECLS; DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; - DATA_TYPE ret = atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv)); + DATA_TYPE ret; + + ATOMIC_TRACE_RMW; + ret = atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv)); ATOMIC_MMU_CLEANUP; return BSWAP(ret); } @@ -184,6 +238,8 @@ ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS) { ATOMIC_MMU_DECLS; DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP; + + ATOMIC_TRACE_LD; __atomic_load(haddr, &val, __ATOMIC_RELAXED); ATOMIC_MMU_CLEANUP; return BSWAP(val); @@ -194,6 +250,8 @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr, { ATOMIC_MMU_DECLS; DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; + + ATOMIC_TRACE_ST; val = BSWAP(val); __atomic_store(haddr, &val, __ATOMIC_RELAXED); ATOMIC_MMU_CLEANUP; @@ -204,7 +262,10 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, { ATOMIC_MMU_DECLS; DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; - ABI_TYPE ret = atomic_xchg__nocheck(haddr, BSWAP(val)); + ABI_TYPE ret; + + ATOMIC_TRACE_RMW; + ret = atomic_xchg__nocheck(haddr, BSWAP(val)); ATOMIC_MMU_CLEANUP; return BSWAP(ret); } @@ -215,7 +276,10 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \ { \ ATOMIC_MMU_DECLS; \ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \ - DATA_TYPE ret = atomic_##X(haddr, BSWAP(val)); \ + DATA_TYPE ret; \ + \ + ATOMIC_TRACE_RMW; \ + ret = atomic_##X(haddr, BSWAP(val)); \ ATOMIC_MMU_CLEANUP; \ return BSWAP(ret); \ } @@ -232,6 +296,9 @@ GEN_ATOMIC_HELPER(xor_fetch) /* These helpers are, as a whole, full barriers. Within the helper, * the leading barrier is explicit and the trailing barrier is within * cmpxchg primitive. + * + * Trace this load + RMW loop as a single RMW op. This way, regardless + * of CF_PARALLEL's value, we'll trace just a read and a write. */ #define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET) \ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \ @@ -240,6 +307,8 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \ ATOMIC_MMU_DECLS; \ XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \ XDATA_TYPE ldo, ldn, old, new, val = xval; \ + \ + ATOMIC_TRACE_RMW; \ smp_mb(); \ ldn = atomic_read__nocheck(haddr); \ do { \ @@ -271,11 +340,17 @@ GEN_ATOMIC_HELPER_FN(add_fetch, ADD, DATA_TYPE, new) #endif /* DATA_SIZE >= 16 */ #undef END +#undef MEND #endif /* DATA_SIZE > 1 */ +#undef ATOMIC_TRACE_ST +#undef ATOMIC_TRACE_LD +#undef ATOMIC_TRACE_RMW + #undef BSWAP #undef ABI_TYPE #undef DATA_TYPE #undef SDATA_TYPE #undef SUFFIX #undef DATA_SIZE +#undef SHIFT diff --git a/docs/devel/tracing.txt b/docs/devel/tracing.txt index 07abbb345c..6f815ecbd7 100644 --- a/docs/devel/tracing.txt +++ b/docs/devel/tracing.txt @@ -104,6 +104,11 @@ Trace events should use types as follows: * For everything else, use primitive scalar types (char, int, long) with the appropriate signedness. + * Avoid floating point types (float and double) because SystemTap does not + support them. In most cases it is possible to round to an integer type + instead. This may require scaling the value first by multiplying it by 1000 + or the like when digits after the decimal point need to be preserved. + Format strings should reflect the types defined in the trace event. Take special care to use PRId64 and PRIu64 for int64_t and uint64_t types, respectively. This ensures portability between 32- and 64-bit platforms. diff --git a/hw/mips/boston.c b/hw/mips/boston.c index 52cce19766..14e6f955d2 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -471,8 +471,7 @@ static void boston_mach_init(MachineState *machine) sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1); flash = g_new(MemoryRegion, 1); - memory_region_init_rom_nomigrate(flash, NULL, - "boston.flash", 128 * M_BYTE, &err); + memory_region_init_rom(flash, NULL, "boston.flash", 128 * M_BYTE, &err); memory_region_add_subregion_overlap(sys_mem, 0x18000000, flash, 0); ddr = g_new(MemoryRegion, 1); diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 494f84e290..b9d92bf47e 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -1152,7 +1152,7 @@ void mips_malta_init(MachineState *machine) * handled by an overlapping region as the resulting ROM code subpage * regions are not executable. */ - memory_region_init_ram_nomigrate(bios_copy, NULL, "bios.1fc", BIOS_SIZE, + memory_region_init_ram(bios_copy, NULL, "bios.1fc", BIOS_SIZE, &error_fatal); if (!rom_copy(memory_region_get_ram_ptr(bios_copy), FLASH_ADDRESS, BIOS_SIZE)) { diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c index 044e312dc1..b0a31b917d 100644 --- a/hw/pci-host/xilinx-pcie.c +++ b/hw/pci-host/xilinx-pcie.c @@ -120,9 +120,8 @@ static void xilinx_pcie_host_realize(DeviceState *dev, Error **errp) memory_region_init(&s->mmio, OBJECT(s), "mmio", UINT64_MAX); memory_region_set_enabled(&s->mmio, false); - /* dummy I/O region */ - memory_region_init_ram_nomigrate(&s->io, OBJECT(s), "io", 16, NULL); - memory_region_set_enabled(&s->io, false); + /* dummy PCI I/O region (not visible to the CPU) */ + memory_region_init(&s->io, OBJECT(s), "io", 16); /* interrupt out */ qdev_init_gpio_out_named(dev, &s->irq, "interrupt_out", 1); diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_ldst_useronly_template.h index c168f31bba..e30e58ed4a 100644 --- a/include/exec/cpu_ldst_useronly_template.h +++ b/include/exec/cpu_ldst_useronly_template.h @@ -33,20 +33,24 @@ #define SUFFIX q #define USUFFIX q #define DATA_TYPE uint64_t +#define SHIFT 3 #elif DATA_SIZE == 4 #define SUFFIX l #define USUFFIX l #define DATA_TYPE uint32_t +#define SHIFT 2 #elif DATA_SIZE == 2 #define SUFFIX w #define USUFFIX uw #define DATA_TYPE uint16_t #define DATA_STYPE int16_t +#define SHIFT 1 #elif DATA_SIZE == 1 #define SUFFIX b #define USUFFIX ub #define DATA_TYPE uint8_t #define DATA_STYPE int8_t +#define SHIFT 0 #else #error unsupported data size #endif @@ -63,7 +67,7 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) #if !defined(CODE_ACCESS) trace_guest_mem_before_exec( ENV_GET_CPU(env), ptr, - trace_mem_build_info(DATA_SIZE, false, MO_TE, false)); + trace_mem_build_info(SHIFT, false, MO_TE, false)); #endif return glue(glue(ld, USUFFIX), _p)(g2h(ptr)); } @@ -87,7 +91,7 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) #if !defined(CODE_ACCESS) trace_guest_mem_before_exec( ENV_GET_CPU(env), ptr, - trace_mem_build_info(DATA_SIZE, true, MO_TE, false)); + trace_mem_build_info(SHIFT, true, MO_TE, false)); #endif return glue(glue(lds, SUFFIX), _p)(g2h(ptr)); } @@ -113,7 +117,7 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr, #if !defined(CODE_ACCESS) trace_guest_mem_before_exec( ENV_GET_CPU(env), ptr, - trace_mem_build_info(DATA_SIZE, false, MO_TE, true)); + trace_mem_build_info(SHIFT, false, MO_TE, true)); #endif glue(glue(st, SUFFIX), _p)(g2h(ptr), v); } @@ -136,3 +140,4 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, #undef SUFFIX #undef USUFFIX #undef DATA_SIZE +#undef SHIFT diff --git a/migration/trace-events b/migration/trace-events index 8b9edfbfef..9430f3cbe0 100644 --- a/migration/trace-events +++ b/migration/trace-events @@ -145,7 +145,7 @@ migrate_global_state_post_load(const char *state) "loaded state: %s" migrate_global_state_pre_save(const char *state) "saved state: %s" migration_thread_low_pending(uint64_t pending) "%" PRIu64 migrate_state_too_big(void) "" -migrate_transferred(uint64_t tranferred, uint64_t time_spent, double bandwidth, uint64_t size) "transferred %" PRIu64 " time_spent %" PRIu64 " bandwidth %g max_size %" PRId64 +migrate_transferred(uint64_t tranferred, uint64_t time_spent, uint64_t bandwidth, uint64_t size) "transferred %" PRIu64 " time_spent %" PRIu64 " bandwidth %" PRIu64 " max_size %" PRId64 process_incoming_migration_co_end(int ret, int ps) "ret=%d postcopy-state=%d" process_incoming_migration_co_postcopy_end_main(void) "" migration_set_incoming_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s" diff --git a/qapi/trace-events b/qapi/trace-events index 9e9008a1dc..70e049ea80 100644 --- a/qapi/trace-events +++ b/qapi/trace-events @@ -29,6 +29,6 @@ visit_type_int64(void *v, const char *name, int64_t *obj) "v=%p name=%s obj=%p" visit_type_size(void *v, const char *name, uint64_t *obj) "v=%p name=%s obj=%p" visit_type_bool(void *v, const char *name, bool *obj) "v=%p name=%s obj=%p" visit_type_str(void *v, const char *name, char **obj) "v=%p name=%s obj=%p" -visit_type_number(void *v, const char *name, double *obj) "v=%p name=%s obj=%p" +visit_type_number(void *v, const char *name, void *obj) "v=%p name=%s obj=%p" visit_type_any(void *v, const char *name, void *obj) "v=%p name=%s obj=%p" visit_type_null(void *v, const char *name, void *obj) "v=%p name=%s obj=%p" diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index b20fac34a3..0e3c9e146c 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -53,8 +53,6 @@ ALLOWED_TYPES = [ "bool", "unsigned", "signed", - "float", - "double", "int8_t", "uint8_t", "int16_t", diff --git a/target/mips/gdbstub.c b/target/mips/gdbstub.c index 6d1fb70f2c..18e0e6dce4 100644 --- a/target/mips/gdbstub.c +++ b/target/mips/gdbstub.c @@ -39,7 +39,7 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr0); default: if (env->CP0_Status & (1 << CP0St_FR)) { - return gdb_get_regl(mem_buf, + return gdb_get_reg64(mem_buf, env->active_fpu.fpr[n - 38].d); } else { return gdb_get_regl(mem_buf, @@ -100,6 +100,7 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) break; default: if (env->CP0_Status & (1 << CP0St_FR)) { + uint64_t tmp = ldq_p(mem_buf); env->active_fpu.fpr[n - 38].d = tmp; } else { env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp; diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 9025f42366..41d3634289 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -2627,6 +2627,9 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt) (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask)); break; default: + if (env->insn_flags & ISA_MIPS32R6) { + do_raise_exception(env, EXCP_RI, GETPC()); + } return; } restore_fp_status(env); diff --git a/target/mips/translate.c b/target/mips/translate.c index e57d71e485..20b43c0337 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2112,7 +2112,7 @@ OP_ST_ATOMIC(scd,st64,ld64,0x7); #undef OP_ST_ATOMIC static void gen_base_offset_addr (DisasContext *ctx, TCGv addr, - int base, int16_t offset) + int base, int offset) { if (base == 0) { tcg_gen_movi_tl(addr, offset); @@ -2140,7 +2140,7 @@ static target_ulong pc_relative_pc (DisasContext *ctx) /* Load */ static void gen_ld(DisasContext *ctx, uint32_t opc, - int rt, int base, int16_t offset) + int rt, int base, int offset) { TCGv t0, t1, t2; int mem_idx = ctx->mem_idx; @@ -2337,7 +2337,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, /* Store */ static void gen_st (DisasContext *ctx, uint32_t opc, int rt, - int base, int16_t offset) + int base, int offset) { TCGv t0 = tcg_temp_new(); TCGv t1 = tcg_temp_new(); @@ -2433,11 +2433,8 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt, /* Load and store */ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, - int base, int16_t offset) + TCGv t0) { - TCGv t0 = tcg_temp_new(); - - gen_base_offset_addr(ctx, t0, base, offset); /* Don't do NOP if destination is zero: we must perform the actual memory access. */ switch (opc) { @@ -2480,15 +2477,15 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, default: MIPS_INVAL("flt_ldst"); generate_exception_end(ctx, EXCP_RI); - goto out; + break; } - out: - tcg_temp_free(t0); } static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, int rs, int16_t imm) { + TCGv t0 = tcg_temp_new(); + if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { check_cp1_enabled(ctx); switch (op) { @@ -2497,16 +2494,18 @@ static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, check_insn(ctx, ISA_MIPS2); /* Fallthrough */ default: - gen_flt_ldst(ctx, op, rt, rs, imm); + gen_base_offset_addr(ctx, t0, rs, imm); + gen_flt_ldst(ctx, op, rt, t0); } } else { generate_exception_err(ctx, EXCP_CpU, 1); } + tcg_temp_free(t0); } /* Arithmetic with immediate operand */ static void gen_arith_imm(DisasContext *ctx, uint32_t opc, - int rt, int rs, int16_t imm) + int rt, int rs, int imm) { target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ @@ -20713,6 +20712,11 @@ void cpu_state_reset(CPUMIPSState *env) env->CP0_Status |= (1 << CP0St_FR); } + if (env->CP0_Config3 & (1 << CP0C3_ISA)) { + /* microMIPS on reset when Config3.ISA == {1, 3} */ + env->hflags |= MIPS_HFLAG_M16; + } + /* MSA */ if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { msa_reset(env); diff --git a/trace/mem-internal.h b/trace/mem-internal.h index ddda934253..f6efaf6d6b 100644 --- a/trace/mem-internal.h +++ b/trace/mem-internal.h @@ -10,37 +10,45 @@ #ifndef TRACE__MEM_INTERNAL_H #define TRACE__MEM_INTERNAL_H -static inline uint8_t trace_mem_get_info(TCGMemOp op, bool store) +#define TRACE_MEM_SZ_SHIFT_MASK 0x7 /* size shift mask */ +#define TRACE_MEM_SE (1ULL << 3) /* sign extended (y/n) */ +#define TRACE_MEM_BE (1ULL << 4) /* big endian (y/n) */ +#define TRACE_MEM_ST (1ULL << 5) /* store (y/n) */ + +static inline uint8_t trace_mem_build_info( + int size_shift, bool sign_extend, TCGMemOp endianness, bool store) { - uint8_t res = op; - bool be = (op & MO_BSWAP) == MO_BE; - - /* remove untraced fields */ - res &= (1ULL << 4) - 1; - /* make endianness absolute */ - res &= ~MO_BSWAP; - if (be) { - res |= 1ULL << 3; + uint8_t res; + + res = size_shift & TRACE_MEM_SZ_SHIFT_MASK; + if (sign_extend) { + res |= TRACE_MEM_SE; + } + if (endianness == MO_BE) { + res |= TRACE_MEM_BE; } - /* add fields */ if (store) { - res |= 1ULL << 4; + res |= TRACE_MEM_ST; } - return res; } -static inline uint8_t trace_mem_build_info( - TCGMemOp size, bool sign_extend, TCGMemOp endianness, bool store) +static inline uint8_t trace_mem_get_info(TCGMemOp op, bool store) { - uint8_t res = 0; - res |= size; - res |= (sign_extend << 2); - if (endianness == MO_BE) { - res |= (1ULL << 3); - } - res |= (store << 4); - return res; + return trace_mem_build_info(op & MO_SIZE, !!(op & MO_SIGN), + op & MO_BSWAP, store); +} + +static inline +uint8_t trace_mem_build_info_no_se_be(int size_shift, bool store) +{ + return trace_mem_build_info(size_shift, false, MO_BE, store); +} + +static inline +uint8_t trace_mem_build_info_no_se_le(int size_shift, bool store) +{ + return trace_mem_build_info(size_shift, false, MO_LE, store); } #endif /* TRACE__MEM_INTERNAL_H */ diff --git a/trace/mem.h b/trace/mem.h index 9c88bcb4e6..2b58196e53 100644 --- a/trace/mem.h +++ b/trace/mem.h @@ -25,7 +25,7 @@ static uint8_t trace_mem_get_info(TCGMemOp op, bool store); * * Return a value for the 'info' argument in guest memory access traces. */ -static uint8_t trace_mem_build_info(TCGMemOp size, bool sign_extend, +static uint8_t trace_mem_build_info(int size_shift, bool sign_extend, TCGMemOp endianness, bool store); |