#include "cpu.h"
#include "qemu/host-utils.h"
-#include "helper.h"
+#include "exec/helper-proto.h"
#include "sysemu/sysemu.h"
void helper_raise_exception(CPUSPARCState *env, int tt)
{
- env->exception_index = tt;
- cpu_loop_exit(env);
+ CPUState *cs = CPU(sparc_env_get_cpu(env));
+
+ cs->exception_index = tt;
+ cpu_loop_exit(cs);
}
void helper_debug(CPUSPARCState *env)
{
- env->exception_index = EXCP_DEBUG;
- cpu_loop_exit(env);
+ CPUState *cs = CPU(sparc_env_get_cpu(env));
+
+ cs->exception_index = EXCP_DEBUG;
+ cpu_loop_exit(cs);
}
#ifdef TARGET_SPARC64
#endif
}
-uint64_t helper_tick_get_count(void *opaque)
+uint64_t helper_tick_get_count(CPUSPARCState *env, void *opaque, int mem_idx)
{
#if !defined(CONFIG_USER_ONLY)
- return cpu_tick_get_count(opaque);
+ CPUTimer *timer = opaque;
+
+ if (timer->npt && mem_idx < MMU_KERNEL_IDX) {
+ helper_raise_exception(env, TT_PRIV_INSN);
+ }
+
+ return cpu_tick_get_count(timer);
#else
return 0;
#endif
static target_ulong helper_udiv_common(CPUSPARCState *env, target_ulong a,
target_ulong b, int cc)
{
+ SPARCCPU *cpu = sparc_env_get_cpu(env);
int overflow = 0;
uint64_t x0;
uint32_t x1;
x1 = (b & 0xffffffff);
if (x1 == 0) {
- cpu_restore_state(env, GETPC());
+ cpu_restore_state(CPU(cpu), GETPC());
helper_raise_exception(env, TT_DIV_ZERO);
}
x0 = x0 / x1;
- if (x0 > 0xffffffff) {
- x0 = 0xffffffff;
+ if (x0 > UINT32_MAX) {
+ x0 = UINT32_MAX;
overflow = 1;
}
static target_ulong helper_sdiv_common(CPUSPARCState *env, target_ulong a,
target_ulong b, int cc)
{
+ SPARCCPU *cpu = sparc_env_get_cpu(env);
int overflow = 0;
int64_t x0;
int32_t x1;
x1 = (b & 0xffffffff);
if (x1 == 0) {
- cpu_restore_state(env, GETPC());
+ cpu_restore_state(CPU(cpu), GETPC());
helper_raise_exception(env, TT_DIV_ZERO);
- }
-
- x0 = x0 / x1;
- if ((int32_t) x0 != x0) {
- x0 = x0 < 0 ? 0x80000000 : 0x7fffffff;
+ } else if (x1 == -1 && x0 == INT64_MIN) {
+ x0 = INT32_MAX;
overflow = 1;
+ } else {
+ x0 = x0 / x1;
+ if ((int32_t) x0 != x0) {
+ x0 = x0 < 0 ? INT32_MIN : INT32_MAX;
+ overflow = 1;
+ }
}
if (cc) {
{
if (b == 0) {
/* Raise divide by zero trap. */
- cpu_restore_state(env, GETPC());
+ SPARCCPU *cpu = sparc_env_get_cpu(env);
+
+ cpu_restore_state(CPU(cpu), GETPC());
helper_raise_exception(env, TT_DIV_ZERO);
} else if (b == -1) {
/* Avoid overflow trap with i386 divide insn. */
{
if (b == 0) {
/* Raise divide by zero trap. */
- cpu_restore_state(env, GETPC());
+ SPARCCPU *cpu = sparc_env_get_cpu(env);
+
+ cpu_restore_state(CPU(cpu), GETPC());
helper_raise_exception(env, TT_DIV_ZERO);
}
return a / b;
target_ulong helper_taddcctv(CPUSPARCState *env, target_ulong src1,
target_ulong src2)
{
+ SPARCCPU *cpu = sparc_env_get_cpu(env);
target_ulong dst;
/* Tag overflow occurs if either input has bits 0 or 1 set. */
return dst;
tag_overflow:
- cpu_restore_state(env, GETPC());
+ cpu_restore_state(CPU(cpu), GETPC());
helper_raise_exception(env, TT_TOVF);
}
target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1,
target_ulong src2)
{
+ SPARCCPU *cpu = sparc_env_get_cpu(env);
target_ulong dst;
/* Tag overflow occurs if either input has bits 0 or 1 set. */
return dst;
tag_overflow:
- cpu_restore_state(env, GETPC());
+ cpu_restore_state(CPU(cpu), GETPC());
helper_raise_exception(env, TT_TOVF);
}
#ifndef TARGET_SPARC64
void helper_power_down(CPUSPARCState *env)
{
- env->halted = 1;
- env->exception_index = EXCP_HLT;
+ CPUState *cs = CPU(sparc_env_get_cpu(env));
+
+ cs->halted = 1;
+ cs->exception_index = EXCP_HLT;
env->pc = env->npc;
env->npc = env->pc + 4;
- cpu_loop_exit(env);
+ cpu_loop_exit(cs);
}
#endif