From f350479701ad619d98e2999404cd246f38b2000f Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 17 Apr 2022 10:43:33 -0700 Subject: [PATCH] target/arm: Extend store_cpu_offset to take field size Currently we assume all fields are 32-bit. Prepare for fields of a single byte, using sizeof_field(). Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell [PMM: use sizeof_field() instead of raw sizeof()] Signed-off-by: Peter Maydell --- target/arm/translate-a32.h | 13 +++++-------- target/arm/translate.c | 21 ++++++++++++++++++++- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h index 5be4b9b8346bc..09010ad2dada7 100644 --- a/target/arm/translate-a32.h +++ b/target/arm/translate-a32.h @@ -61,17 +61,14 @@ static inline TCGv_i32 load_cpu_offset(int offset) #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name)) -static inline void store_cpu_offset(TCGv_i32 var, int offset) -{ - tcg_gen_st_i32(var, cpu_env, offset); - tcg_temp_free_i32(var); -} +void store_cpu_offset(TCGv_i32 var, int offset, int size); -#define store_cpu_field(var, name) \ - store_cpu_offset(var, offsetof(CPUARMState, name)) +#define store_cpu_field(var, name) \ + store_cpu_offset(var, offsetof(CPUARMState, name), \ + sizeof_field(CPUARMState, name)) #define store_cpu_field_constant(val, name) \ - tcg_gen_st_i32(tcg_constant_i32(val), cpu_env, offsetof(CPUARMState, name)) + store_cpu_field(tcg_constant_i32(val), name) /* Create a new temporary and set it to the value of a CPU register. */ static inline TCGv_i32 load_reg(DisasContext *s, int reg) diff --git a/target/arm/translate.c b/target/arm/translate.c index 6018fee2ef1a5..1314406b19389 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -180,6 +180,25 @@ typedef enum ISSInfo { ISSIs16Bit = (1 << 8), } ISSInfo; +/* + * Store var into env + offset to a member with size bytes. + * Free var after use. + */ +void store_cpu_offset(TCGv_i32 var, int offset, int size) +{ + switch (size) { + case 1: + tcg_gen_st8_i32(var, cpu_env, offset); + break; + case 4: + tcg_gen_st_i32(var, cpu_env, offset); + break; + default: + g_assert_not_reached(); + } + tcg_temp_free_i32(var); +} + /* Save the syndrome information for a Data Abort */ static void disas_set_da_iss(DisasContext *s, MemOp memop, ISSInfo issinfo) { @@ -4852,7 +4871,7 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64, tcg_temp_free_i32(tmp); } else { TCGv_i32 tmp = load_reg(s, rt); - store_cpu_offset(tmp, ri->fieldoffset); + store_cpu_offset(tmp, ri->fieldoffset, 4); } } }