target-arm: Give CPSR setting on 32-bit exception return its own helper

The rules for setting the CPSR on a 32-bit exception return are
subtly different from those for setting the CPSR via an instruction
like MSR or CPS. (In particular, in Hyp mode changing the mode bits
is not valid via MSR or CPS.) Split the exception-return case into
its own helper for setting CPSR, so we can eventually handle them
differently in the helper function.

Backports commit 235ea1f5c89abf30e452539b973b0dbe43d3fe2b from qemu
This commit is contained in:
Peter Maydell 2018-02-20 22:06:30 -05:00 committed by Lioncash
parent 46284f1a41
commit 6ae2357be6
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
17 changed files with 38 additions and 3 deletions

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_aarch64
#define gen_helper_cpsr_read gen_helper_cpsr_read_aarch64
#define gen_helper_cpsr_write gen_helper_cpsr_write_aarch64
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_aarch64
#define gen_helper_crc32_arm gen_helper_crc32_arm_aarch64
#define gen_helper_crc32c gen_helper_crc32c_aarch64
#define gen_helper_crypto_aese gen_helper_crypto_aese_aarch64
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_aarch64
#define helper_cpsr_read helper_cpsr_read_aarch64
#define helper_cpsr_write helper_cpsr_write_aarch64
#define helper_cpsr_write_eret helper_cpsr_write_eret_aarch64
#define helper_crc32_arm helper_crc32_arm_aarch64
#define helper_crc32c helper_crc32c_aarch64
#define helper_crypto_aese helper_crypto_aese_aarch64

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_aarch64eb
#define gen_helper_cpsr_read gen_helper_cpsr_read_aarch64eb
#define gen_helper_cpsr_write gen_helper_cpsr_write_aarch64eb
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_aarch64eb
#define gen_helper_crc32_arm gen_helper_crc32_arm_aarch64eb
#define gen_helper_crc32c gen_helper_crc32c_aarch64eb
#define gen_helper_crypto_aese gen_helper_crypto_aese_aarch64eb
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_aarch64eb
#define helper_cpsr_read helper_cpsr_read_aarch64eb
#define helper_cpsr_write helper_cpsr_write_aarch64eb
#define helper_cpsr_write_eret helper_cpsr_write_eret_aarch64eb
#define helper_crc32_arm helper_crc32_arm_aarch64eb
#define helper_crc32c helper_crc32c_aarch64eb
#define helper_crypto_aese helper_crypto_aese_aarch64eb

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_arm
#define gen_helper_cpsr_read gen_helper_cpsr_read_arm
#define gen_helper_cpsr_write gen_helper_cpsr_write_arm
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_arm
#define gen_helper_crc32_arm gen_helper_crc32_arm_arm
#define gen_helper_crc32c gen_helper_crc32c_arm
#define gen_helper_crypto_aese gen_helper_crypto_aese_arm
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_arm
#define helper_cpsr_read helper_cpsr_read_arm
#define helper_cpsr_write helper_cpsr_write_arm
#define helper_cpsr_write_eret helper_cpsr_write_eret_arm
#define helper_crc32_arm helper_crc32_arm_arm
#define helper_crc32c helper_crc32c_arm
#define helper_crypto_aese helper_crypto_aese_arm

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_armeb
#define gen_helper_cpsr_read gen_helper_cpsr_read_armeb
#define gen_helper_cpsr_write gen_helper_cpsr_write_armeb
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_armeb
#define gen_helper_crc32_arm gen_helper_crc32_arm_armeb
#define gen_helper_crc32c gen_helper_crc32c_armeb
#define gen_helper_crypto_aese gen_helper_crypto_aese_armeb
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_armeb
#define helper_cpsr_read helper_cpsr_read_armeb
#define helper_cpsr_write helper_cpsr_write_armeb
#define helper_cpsr_write_eret helper_cpsr_write_eret_armeb
#define helper_crc32_arm helper_crc32_arm_armeb
#define helper_crc32c helper_crc32c_armeb
#define helper_crypto_aese helper_crypto_aese_armeb

View file

@ -687,6 +687,7 @@ symbols = (
'gen_helper_clz_arm',
'gen_helper_cpsr_read',
'gen_helper_cpsr_write',
'gen_helper_cpsr_write_eret',
'gen_helper_crc32_arm',
'gen_helper_crc32c',
'gen_helper_crypto_aese',
@ -1406,6 +1407,7 @@ symbols = (
'helper_clz_arm',
'helper_cpsr_read',
'helper_cpsr_write',
'helper_cpsr_write_eret',
'helper_crc32_arm',
'helper_crc32c',
'helper_crypto_aese',

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_m68k
#define gen_helper_cpsr_read gen_helper_cpsr_read_m68k
#define gen_helper_cpsr_write gen_helper_cpsr_write_m68k
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_m68k
#define gen_helper_crc32_arm gen_helper_crc32_arm_m68k
#define gen_helper_crc32c gen_helper_crc32c_m68k
#define gen_helper_crypto_aese gen_helper_crypto_aese_m68k
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_m68k
#define helper_cpsr_read helper_cpsr_read_m68k
#define helper_cpsr_write helper_cpsr_write_m68k
#define helper_cpsr_write_eret helper_cpsr_write_eret_m68k
#define helper_crc32_arm helper_crc32_arm_m68k
#define helper_crc32c helper_crc32c_m68k
#define helper_crypto_aese helper_crypto_aese_m68k

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_mips
#define gen_helper_cpsr_read gen_helper_cpsr_read_mips
#define gen_helper_cpsr_write gen_helper_cpsr_write_mips
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_mips
#define gen_helper_crc32_arm gen_helper_crc32_arm_mips
#define gen_helper_crc32c gen_helper_crc32c_mips
#define gen_helper_crypto_aese gen_helper_crypto_aese_mips
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_mips
#define helper_cpsr_read helper_cpsr_read_mips
#define helper_cpsr_write helper_cpsr_write_mips
#define helper_cpsr_write_eret helper_cpsr_write_eret_mips
#define helper_crc32_arm helper_crc32_arm_mips
#define helper_crc32c helper_crc32c_mips
#define helper_crypto_aese helper_crypto_aese_mips

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_mips64
#define gen_helper_cpsr_read gen_helper_cpsr_read_mips64
#define gen_helper_cpsr_write gen_helper_cpsr_write_mips64
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_mips64
#define gen_helper_crc32_arm gen_helper_crc32_arm_mips64
#define gen_helper_crc32c gen_helper_crc32c_mips64
#define gen_helper_crypto_aese gen_helper_crypto_aese_mips64
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_mips64
#define helper_cpsr_read helper_cpsr_read_mips64
#define helper_cpsr_write helper_cpsr_write_mips64
#define helper_cpsr_write_eret helper_cpsr_write_eret_mips64
#define helper_crc32_arm helper_crc32_arm_mips64
#define helper_crc32c helper_crc32c_mips64
#define helper_crypto_aese helper_crypto_aese_mips64

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_mips64el
#define gen_helper_cpsr_read gen_helper_cpsr_read_mips64el
#define gen_helper_cpsr_write gen_helper_cpsr_write_mips64el
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_mips64el
#define gen_helper_crc32_arm gen_helper_crc32_arm_mips64el
#define gen_helper_crc32c gen_helper_crc32c_mips64el
#define gen_helper_crypto_aese gen_helper_crypto_aese_mips64el
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_mips64el
#define helper_cpsr_read helper_cpsr_read_mips64el
#define helper_cpsr_write helper_cpsr_write_mips64el
#define helper_cpsr_write_eret helper_cpsr_write_eret_mips64el
#define helper_crc32_arm helper_crc32_arm_mips64el
#define helper_crc32c helper_crc32c_mips64el
#define helper_crypto_aese helper_crypto_aese_mips64el

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_mipsel
#define gen_helper_cpsr_read gen_helper_cpsr_read_mipsel
#define gen_helper_cpsr_write gen_helper_cpsr_write_mipsel
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_mipsel
#define gen_helper_crc32_arm gen_helper_crc32_arm_mipsel
#define gen_helper_crc32c gen_helper_crc32c_mipsel
#define gen_helper_crypto_aese gen_helper_crypto_aese_mipsel
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_mipsel
#define helper_cpsr_read helper_cpsr_read_mipsel
#define helper_cpsr_write helper_cpsr_write_mipsel
#define helper_cpsr_write_eret helper_cpsr_write_eret_mipsel
#define helper_crc32_arm helper_crc32_arm_mipsel
#define helper_crc32c helper_crc32c_mipsel
#define helper_crypto_aese helper_crypto_aese_mipsel

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_powerpc
#define gen_helper_cpsr_read gen_helper_cpsr_read_powerpc
#define gen_helper_cpsr_write gen_helper_cpsr_write_powerpc
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_powerpc
#define gen_helper_crc32_arm gen_helper_crc32_arm_powerpc
#define gen_helper_crc32c gen_helper_crc32c_powerpc
#define gen_helper_crypto_aese gen_helper_crypto_aese_powerpc
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_powerpc
#define helper_cpsr_read helper_cpsr_read_powerpc
#define helper_cpsr_write helper_cpsr_write_powerpc
#define helper_cpsr_write_eret helper_cpsr_write_eret_powerpc
#define helper_crc32_arm helper_crc32_arm_powerpc
#define helper_crc32c helper_crc32c_powerpc
#define helper_crypto_aese helper_crypto_aese_powerpc

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_sparc
#define gen_helper_cpsr_read gen_helper_cpsr_read_sparc
#define gen_helper_cpsr_write gen_helper_cpsr_write_sparc
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_sparc
#define gen_helper_crc32_arm gen_helper_crc32_arm_sparc
#define gen_helper_crc32c gen_helper_crc32c_sparc
#define gen_helper_crypto_aese gen_helper_crypto_aese_sparc
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_sparc
#define helper_cpsr_read helper_cpsr_read_sparc
#define helper_cpsr_write helper_cpsr_write_sparc
#define helper_cpsr_write_eret helper_cpsr_write_eret_sparc
#define helper_crc32_arm helper_crc32_arm_sparc
#define helper_crc32c helper_crc32c_sparc
#define helper_crypto_aese helper_crypto_aese_sparc

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_sparc64
#define gen_helper_cpsr_read gen_helper_cpsr_read_sparc64
#define gen_helper_cpsr_write gen_helper_cpsr_write_sparc64
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_sparc64
#define gen_helper_crc32_arm gen_helper_crc32_arm_sparc64
#define gen_helper_crc32c gen_helper_crc32c_sparc64
#define gen_helper_crypto_aese gen_helper_crypto_aese_sparc64
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_sparc64
#define helper_cpsr_read helper_cpsr_read_sparc64
#define helper_cpsr_write helper_cpsr_write_sparc64
#define helper_cpsr_write_eret helper_cpsr_write_eret_sparc64
#define helper_crc32_arm helper_crc32_arm_sparc64
#define helper_crc32c helper_crc32c_sparc64
#define helper_crypto_aese helper_crypto_aese_sparc64

View file

@ -60,6 +60,7 @@ DEF_HELPER_2(pre_smc, void, env, i32)
DEF_HELPER_1(check_breakpoints, void, env)
DEF_HELPER_3(cpsr_write, void, env, i32, i32)
DEF_HELPER_2(cpsr_write_eret, void, env, i32)
DEF_HELPER_1(cpsr_read, i32, env)
DEF_HELPER_3(v7m_msr, void, env, i32, i32)

View file

@ -425,6 +425,12 @@ void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
cpsr_write(env, val, mask);
}
/* Write the CPSR for a 32-bit exception return */
void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
{
cpsr_write(env, val, CPSR_ERET_MASK);
}
/* Access to user mode registers from privileged modes. */
uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
{

View file

@ -4203,7 +4203,7 @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
TCGv_i32 tmp;
store_reg(s, 15, pc);
tmp = load_cpu_field(s->uc, spsr);
gen_set_cpsr(s, tmp, CPSR_ERET_MASK);
gen_helper_cpsr_write_eret(tcg_ctx, tcg_ctx->cpu_env, tmp);
tcg_temp_free_i32(tcg_ctx, tmp);
s->is_jmp = DISAS_JUMP;
}
@ -4212,7 +4212,7 @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
gen_set_cpsr(s, cpsr, CPSR_ERET_MASK);
gen_helper_cpsr_write_eret(tcg_ctx, tcg_ctx->cpu_env, cpsr);
tcg_temp_free_i32(tcg_ctx, cpsr);
store_reg(s, 15, pc);
s->is_jmp = DISAS_JUMP;
@ -9233,7 +9233,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq
if (exc_return) {
/* Restore CPSR from SPSR. */
tmp = load_cpu_field(s->uc, spsr);
gen_set_cpsr(s, tmp, CPSR_ERET_MASK);
gen_helper_cpsr_write_eret(tcg_ctx, tcg_ctx->cpu_env, tmp);
tcg_temp_free_i32(tcg_ctx, tmp);
s->is_jmp = DISAS_JUMP;
}

View file

@ -681,6 +681,7 @@
#define gen_helper_clz_arm gen_helper_clz_arm_x86_64
#define gen_helper_cpsr_read gen_helper_cpsr_read_x86_64
#define gen_helper_cpsr_write gen_helper_cpsr_write_x86_64
#define gen_helper_cpsr_write_eret gen_helper_cpsr_write_eret_x86_64
#define gen_helper_crc32_arm gen_helper_crc32_arm_x86_64
#define gen_helper_crc32c gen_helper_crc32c_x86_64
#define gen_helper_crypto_aese gen_helper_crypto_aese_x86_64
@ -1400,6 +1401,7 @@
#define helper_clz_arm helper_clz_arm_x86_64
#define helper_cpsr_read helper_cpsr_read_x86_64
#define helper_cpsr_write helper_cpsr_write_x86_64
#define helper_cpsr_write_eret helper_cpsr_write_eret_x86_64
#define helper_crc32_arm helper_crc32_arm_x86_64
#define helper_crc32c helper_crc32c_x86_64
#define helper_crypto_aese helper_crypto_aese_x86_64