diff options
Diffstat (limited to 'target-arm/translate.c')
-rw-r--r-- | target-arm/translate.c | 65 |
1 files changed, 42 insertions, 23 deletions
diff --git a/target-arm/translate.c b/target-arm/translate.c index 9116529306..2bd573354f 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -217,12 +217,16 @@ static void gen_exception_internal(int excp) tcg_temp_free_i32(tcg_excp); } -static void gen_exception(int excp, uint32_t syndrome) +static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el) { TCGv_i32 tcg_excp = tcg_const_i32(excp); TCGv_i32 tcg_syn = tcg_const_i32(syndrome); + TCGv_i32 tcg_el = tcg_const_i32(target_el); - gen_helper_exception_with_syndrome(cpu_env, tcg_excp, tcg_syn); + gen_helper_exception_with_syndrome(cpu_env, tcg_excp, + tcg_syn, tcg_el); + + tcg_temp_free_i32(tcg_el); tcg_temp_free_i32(tcg_syn); tcg_temp_free_i32(tcg_excp); } @@ -250,7 +254,8 @@ static void gen_step_complete_exception(DisasContext *s) * of the exception, and our syndrome information is always correct. */ gen_ss_advance(s); - gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex)); + gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex), + default_exception_el(s)); s->is_jmp = DISAS_EXC; } @@ -1013,11 +1018,12 @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp) s->is_jmp = DISAS_JUMP; } -static void gen_exception_insn(DisasContext *s, int offset, int excp, int syn) +static void gen_exception_insn(DisasContext *s, int offset, int excp, + int syn, uint32_t target_el) { gen_set_condexec(s); gen_set_pc_im(s, s->pc - offset); - gen_exception(excp, syn); + gen_exception(excp, syn, target_el); s->is_jmp = DISAS_JUMP; } @@ -3040,7 +3046,8 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn) */ if (!s->cpacr_fpen) { gen_exception_insn(s, 4, EXCP_UDEF, - syn_fp_access_trap(1, 0xe, s->thumb)); + syn_fp_access_trap(1, 0xe, s->thumb), + default_exception_el(s)); return 0; } @@ -4358,7 +4365,8 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn) */ if (!s->cpacr_fpen) { gen_exception_insn(s, 4, EXCP_UDEF, - syn_fp_access_trap(1, 0xe, s->thumb)); + syn_fp_access_trap(1, 0xe, s->thumb), + default_exception_el(s)); return 0; } @@ -5096,7 +5104,8 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) */ if (!s->cpacr_fpen) { gen_exception_insn(s, 4, EXCP_UDEF, - syn_fp_access_trap(1, 0xe, s->thumb)); + syn_fp_access_trap(1, 0xe, s->thumb), + default_exception_el(s)); return 0; } @@ -7960,7 +7969,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) /* bkpt */ ARCH(5); gen_exception_insn(s, 4, EXCP_BKPT, - syn_aa32_bkpt(imm16, false)); + syn_aa32_bkpt(imm16, false), + default_exception_el(s)); break; case 2: /* Hypervisor call (v7) */ @@ -9021,7 +9031,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) break; default: illegal_op: - gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized()); + gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), + default_exception_el(s)); break; } } @@ -10858,7 +10869,8 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) { int imm8 = extract32(insn, 0, 8); ARCH(5); - gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true)); + gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true), + default_exception_el(s)); break; } @@ -11013,11 +11025,13 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) } return; undef32: - gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized()); + gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), + default_exception_el(s)); return; illegal_op: undef: - gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized()); + gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(), + default_exception_el(s)); } /* generate intermediate code in gen_opc_buf and gen_opparam_buf for @@ -11057,6 +11071,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, dc->condjmp = 0; dc->aarch64 = 0; + dc->el3_is_aa64 = arm_el_is_aa64(env, 3); dc->thumb = ARM_TBFLAG_THUMB(tb->flags); dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags); dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1; @@ -11216,7 +11231,8 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, * bits should be zero. */ assert(num_insns == 0); - gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0)); + gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0), + default_exception_el(dc)); goto done_generating; } @@ -11276,13 +11292,14 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, gen_set_condexec(dc); if (dc->is_jmp == DISAS_SWI) { gen_ss_advance(dc); - gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb)); + gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb), + default_exception_el(dc)); } else if (dc->is_jmp == DISAS_HVC) { gen_ss_advance(dc); - gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm)); + gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2); } else if (dc->is_jmp == DISAS_SMC) { gen_ss_advance(dc); - gen_exception(EXCP_SMC, syn_aa32_smc()); + gen_exception(EXCP_SMC, syn_aa32_smc(), 3); } else if (dc->ss_active) { gen_step_complete_exception(dc); } else { @@ -11297,13 +11314,14 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, gen_set_condexec(dc); if (dc->is_jmp == DISAS_SWI && !dc->condjmp) { gen_ss_advance(dc); - gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb)); + gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb), + default_exception_el(dc)); } else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) { gen_ss_advance(dc); - gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm)); + gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2); } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) { gen_ss_advance(dc); - gen_exception(EXCP_SMC, syn_aa32_smc()); + gen_exception(EXCP_SMC, syn_aa32_smc(), 3); } else if (dc->ss_active) { gen_step_complete_exception(dc); } else { @@ -11341,13 +11359,14 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, gen_helper_wfe(cpu_env); break; case DISAS_SWI: - gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb)); + gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb), + default_exception_el(dc)); break; case DISAS_HVC: - gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm)); + gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2); break; case DISAS_SMC: - gen_exception(EXCP_SMC, syn_aa32_smc()); + gen_exception(EXCP_SMC, syn_aa32_smc(), 3); break; } if (dc->condjmp) { |