/* we restore the process signal mask as the sigreturn should
do it (XXX: use sigsetjmp) */
sigprocmask(SIG_SETMASK, old_set, NULL);
- do_raise_exception_err(env->exception_index, env->error_code);
+ raise_exception_err(env, env->exception_index, env->error_code);
} else {
/* activate soft MMU for this block */
cpu_resume_from_signal(env, puc);
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-void do_raise_exception_err (uint32_t exception, int error_code);
-void do_raise_exception (uint32_t exception);
+void raise_exception_err (CPUState *env, int exception, int error_code);
+void raise_exception (CPUState *env, int exception);
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
int rw, int access_type);
//#define DEBUG_EXCEPTIONS
//#define FLUSH_ALL_TLBS
+/*****************************************************************************/
+/* Exceptions processing */
+
+void raise_exception_err (CPUState *env, int exception, int error_code)
+{
+#if 0
+ printf("Raise exception %3x code : %d\n", exception, error_code);
+#endif
+ env->exception_index = exception;
+ env->error_code = error_code;
+ cpu_loop_exit();
+}
+
+void raise_exception (CPUState *env, int exception)
+{
+ helper_raise_exception_err(exception, 0);
+}
+
/*****************************************************************************/
/* PowerPC MMU emulation */
#include "def-helper.h"
+DEF_HELPER_2(raise_exception_err, void, i32, i32)
+DEF_HELPER_0(raise_debug, void)
+
DEF_HELPER_2(fcmpo, i32, i64, i64)
DEF_HELPER_2(fcmpu, i32, i64, i64)
#include "helper_regs.h"
#include "op_helper.h"
-/* Generate exceptions */
-void OPPROTO op_raise_exception_err (void)
-{
- do_raise_exception_err(PARAM1, PARAM2);
-}
-
-void OPPROTO op_debug (void)
-{
- do_raise_exception(EXCP_DEBUG);
-}
-
#if !defined(CONFIG_USER_ONLY)
/* Segment registers load and store */
void OPPROTO op_load_sr (void)
/*****************************************************************************/
/* Exceptions processing helpers */
-void do_raise_exception_err (uint32_t exception, int error_code)
+void helper_raise_exception_err (uint32_t exception, uint32_t error_code)
{
-#if 0
- printf("Raise exception %3x code : %d\n", exception, error_code);
-#endif
- env->exception_index = exception;
- env->error_code = error_code;
- cpu_loop_exit();
+ raise_exception_err(env, exception, error_code);
}
-void do_raise_exception (uint32_t exception)
+void helper_raise_debug (void)
{
- do_raise_exception_err(exception, 0);
+ raise_exception(env, EXCP_DEBUG);
}
+
/*****************************************************************************/
/* Registers load and stores */
target_ulong helper_load_cr (void)
/* Update the floating-point enabled exception summary */
env->fpscr |= 1 << FPSCR_FEX;
if (msr_fe0 != 0 || msr_fe1 != 0)
- do_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_FP | op);
+ raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_FP | op);
}
return ret;
}
/* Update the floating-point enabled exception summary */
env->fpscr |= 1 << FPSCR_FEX;
if (msr_fe0 != 0 || msr_fe1 != 0) {
- do_raise_exception_err(POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX);
+ raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX);
}
} else {
/* Set the result to infinity */
(env->error_code & POWERPC_EXCP_FP)) {
/* Differred floating-point exception after target FPR update */
if (msr_fe0 != 0 || msr_fe1 != 0)
- do_raise_exception_err(env->exception_index, env->error_code);
+ raise_exception_err(env, env->exception_index, env->error_code);
} else if (env->fp_status.float_exception_flags & float_flag_overflow) {
float_overflow_excp();
} else if (env->fp_status.float_exception_flags & float_flag_underflow) {
(env->error_code & POWERPC_EXCP_FP)) {
/* Differred floating-point exception after target FPR update */
if (msr_fe0 != 0 || msr_fe1 != 0)
- do_raise_exception_err(env->exception_index, env->error_code);
+ raise_exception_err(env, env->exception_index, env->error_code);
}
RETURN();
#endif
T0 = hreg_store_msr(env, T0, 0);
if (T0 != 0) {
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
- do_raise_exception(T0);
+ raise_exception(env, T0);
}
}
((int32_t)T0 == (int32_t)T1 && (flags & 0x04)) ||
((uint32_t)T0 < (uint32_t)T1 && (flags & 0x02)) ||
((uint32_t)T0 > (uint32_t)T1 && (flags & 0x01))))) {
- do_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
+ raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
}
}
((int64_t)T0 == (int64_t)T1 && (flags & 0x04)) ||
((uint64_t)T0 < (uint64_t)T1 && (flags & 0x02)) ||
((uint64_t)T0 > (uint64_t)T1 && (flags & 0x01)))))
- do_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
+ raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
}
#endif
if (loglevel != 0) {
fprintf(logfile, "No DCR environment\n");
}
- do_raise_exception_err(POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
+ raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
} else if (unlikely(ppc_dcr_read(env->dcr_env, T0, &val) != 0)) {
if (loglevel != 0) {
fprintf(logfile, "DCR read error %d %03x\n", (int)T0, (int)T0);
}
- do_raise_exception_err(POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
+ raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
} else {
T0 = val;
}
if (loglevel != 0) {
fprintf(logfile, "No DCR environment\n");
}
- do_raise_exception_err(POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
+ raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
} else if (unlikely(ppc_dcr_write(env->dcr_env, T0, T1) != 0)) {
if (loglevel != 0) {
fprintf(logfile, "DCR write error %d %03x\n", (int)T0, (int)T0);
}
- do_raise_exception_err(POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
+ raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
}
}
cpu_restore_state(tb, env, pc, NULL);
}
}
- do_raise_exception_err(env->exception_index, env->error_code);
+ raise_exception_err(env, env->exception_index, env->error_code);
}
env = saved_env;
}
if (likely(T1 != 0)) {
if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
(PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
- do_raise_exception_err(POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL |
- POWERPC_EXCP_INVAL_LSWX);
+ raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL |
+ POWERPC_EXCP_INVAL_LSWX);
} else {
glue(do_lsw, MEMSUFFIX)(PARAM1);
}
if (likely(T1 != 0)) {
if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
(PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
- do_raise_exception_err(POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL |
- POWERPC_EXCP_INVAL_LSWX);
+ raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL |
+ POWERPC_EXCP_INVAL_LSWX);
} else {
glue(do_lsw_64, MEMSUFFIX)(PARAM1);
}
void OPPROTO glue(op_lwarx, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
T1 = glue(ldu32, MEMSUFFIX)((uint32_t)T0);
env->reserve = (uint32_t)T0;
void OPPROTO glue(op_lwarx_64, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
T1 = glue(ldu32, MEMSUFFIX)((uint64_t)T0);
env->reserve = (uint64_t)T0;
void OPPROTO glue(op_ldarx, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
T1 = glue(ldu64, MEMSUFFIX)((uint32_t)T0);
env->reserve = (uint32_t)T0;
void OPPROTO glue(op_ldarx_64, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
T1 = glue(ldu64, MEMSUFFIX)((uint64_t)T0);
env->reserve = (uint64_t)T0;
void OPPROTO glue(op_lwarx_le, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
T1 = glue(ldu32r, MEMSUFFIX)((uint32_t)T0);
env->reserve = (uint32_t)T0;
void OPPROTO glue(op_lwarx_le_64, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
T1 = glue(ldu32r, MEMSUFFIX)((uint64_t)T0);
env->reserve = (uint64_t)T0;
void OPPROTO glue(op_ldarx_le, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
T1 = glue(ldu64r, MEMSUFFIX)((uint32_t)T0);
env->reserve = (uint32_t)T0;
void OPPROTO glue(op_ldarx_le_64, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
T1 = glue(ldu64r, MEMSUFFIX)((uint64_t)T0);
env->reserve = (uint64_t)T0;
void OPPROTO glue(op_stwcx, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
if (unlikely(env->reserve != (uint32_t)T0)) {
env->crf[0] = xer_so;
void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
if (unlikely(env->reserve != (uint64_t)T0)) {
env->crf[0] = xer_so;
void OPPROTO glue(op_stdcx, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
if (unlikely(env->reserve != (uint32_t)T0)) {
env->crf[0] = xer_so;
void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
if (unlikely(env->reserve != (uint64_t)T0)) {
env->crf[0] = xer_so;
void OPPROTO glue(op_stwcx_le, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
if (unlikely(env->reserve != (uint32_t)T0)) {
env->crf[0] = xer_so;
void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
if (unlikely(env->reserve != (uint64_t)T0)) {
env->crf[0] = xer_so;
void OPPROTO glue(op_stdcx_le, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
if (unlikely(env->reserve != (uint32_t)T0)) {
env->crf[0] = xer_so;
void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void)
{
if (unlikely(T0 & 0x03)) {
- do_raise_exception(POWERPC_EXCP_ALIGN);
+ raise_exception(env, POWERPC_EXCP_ALIGN);
} else {
if (unlikely(env->reserve != (uint64_t)T0)) {
env->crf[0] = xer_so;
#define GEN_EXCP(ctx, excp, error) \
do { \
+ TCGv_i32 t0 = tcg_const_i32(excp); \
+ TCGv_i32 t1 = tcg_const_i32(error); \
if ((ctx)->exception == POWERPC_EXCP_NONE) { \
gen_update_nip(ctx, (ctx)->nip); \
} \
- gen_op_raise_exception_err((excp), (error)); \
+ gen_helper_raise_exception_err(t0, t1); \
+ tcg_temp_free_i32(t0); \
+ tcg_temp_free_i32(t1); \
ctx->exception = (excp); \
} while (0)
}
if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
gen_update_nip(ctx, dest);
- gen_op_debug();
+ gen_helper_raise_debug();
}
}
tcg_gen_exit_tb(0);
for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
if (bp->pc == ctx.nip) {
gen_update_nip(&ctx, ctx.nip);
- gen_op_debug();
+ gen_helper_raise_debug();
break;
}
}
} else if (ctx.exception != POWERPC_EXCP_BRANCH) {
if (unlikely(env->singlestep_enabled)) {
gen_update_nip(&ctx, ctx.nip);
- gen_op_debug();
+ gen_helper_raise_debug();
}
/* Generate the return instruction */
tcg_gen_exit_tb(0);