* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "cpu.h"
-#include "helper.h"
+#include "exec/helper-proto.h"
+#include "exec/cpu_ldst.h"
//#define DEBUG_MMU
//#define DEBUG_MXCC
#define QT0 (env->qt0)
#define QT1 (env->qt1)
-#if !defined(CONFIG_USER_ONLY)
-static void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env,
- target_ulong addr, int is_write,
- int is_user, uintptr_t retaddr);
-#include "exec/softmmu_exec.h"
-#define MMUSUFFIX _mmu
-#define ALIGNED_ONLY
-
-#define SHIFT 0
-#include "exec/softmmu_template.h"
-
-#define SHIFT 1
-#include "exec/softmmu_template.h"
-
-#define SHIFT 2
-#include "exec/softmmu_template.h"
-
-#define SHIFT 3
-#include "exec/softmmu_template.h"
-#endif
-
#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
/* Calculates TSB pointer value for fault page size 8k or 64k */
static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register,
#endif
+#if defined(TARGET_SPARC64) || defined(CONFIG_USER_ONLY)
static inline target_ulong address_mask(CPUSPARCState *env1, target_ulong addr)
{
#ifdef TARGET_SPARC64
#endif
return addr;
}
+#endif
+#ifdef TARGET_SPARC64
/* returns true if access using this ASI is to have address translated by MMU
otherwise access is to raw physical address */
+/* TODO: check sparc32 bits */
static inline int is_translating_asi(int asi)
{
-#ifdef TARGET_SPARC64
/* Ultrasparc IIi translating asi
- note this list is defined by cpu implementation
*/
default:
return 0;
}
-#else
- /* TODO: check sparc32 bits */
- return 0;
-#endif
}
static inline target_ulong asi_address_mask(CPUSPARCState *env,
return addr;
}
}
+#endif
void helper_check_align(CPUSPARCState *env, target_ulong addr, uint32_t align)
{
{
switch (size) {
case 1:
- ret = ldub_raw(addr);
+ ret = cpu_ldub_data(env, addr);
break;
case 2:
- ret = lduw_raw(addr);
+ ret = cpu_lduw_data(env, addr);
break;
case 4:
- ret = ldl_raw(addr);
+ ret = cpu_ldl_data(env, addr);
break;
default:
case 8:
- ret = ldq_raw(addr);
+ ret = cpu_ldq_data(env, addr);
break;
}
}
{
switch (size) {
case 1:
- stb_raw(addr, val);
+ cpu_stb_data(env, addr, val);
break;
case 2:
- stw_raw(addr, val);
+ cpu_stw_data(env, addr, val);
break;
case 4:
- stl_raw(addr, val);
+ cpu_stl_data(env, addr, val);
break;
case 8:
default:
- stq_raw(addr, val);
+ cpu_stq_data(env, addr, val);
break;
}
}
unsigned int i;
target_ulong val;
- helper_check_align(env, addr, 3);
addr = asi_address_mask(env, asi, addr);
switch (asi) {
helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x19, 8);
}
+ return;
+ case 0xd2: /* 16-bit floating point load primary */
+ case 0xd3: /* 16-bit floating point load secondary */
+ case 0xda: /* 16-bit floating point load primary, LE */
+ case 0xdb: /* 16-bit floating point load secondary, LE */
+ helper_check_align(env, addr, 1);
+ /* Fall through */
+ case 0xd0: /* 8-bit floating point load primary */
+ case 0xd1: /* 8-bit floating point load secondary */
+ case 0xd8: /* 8-bit floating point load primary, LE */
+ case 0xd9: /* 8-bit floating point load secondary, LE */
+ val = env->fpr[rd / 2].l.lower;
+ helper_st_asi(env, addr, val, asi & 0x8d, ((asi & 2) >> 1) + 1);
return;
default:
+ helper_check_align(env, addr, 3);
break;
}
break;
}
#else
- u.ll.upper = ldq_raw(address_mask(env, addr));
- u.ll.lower = ldq_raw(address_mask(env, addr + 8));
+ u.ll.upper = cpu_ldq_data(env, address_mask(env, addr));
+ u.ll.lower = cpu_ldq_data(env, address_mask(env, addr + 8));
QT0 = u.q;
#endif
}
}
#else
u.q = QT0;
- stq_raw(address_mask(env, addr), u.ll.upper);
- stq_raw(address_mask(env, addr + 8), u.ll.lower);
+ cpu_stq_data(env, address_mask(env, addr), u.ll.upper);
+ cpu_stq_data(env, address_mask(env, addr + 8), u.ll.lower);
#endif
}
#endif
#if !defined(CONFIG_USER_ONLY)
-static void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env,
- target_ulong addr, int is_write,
- int is_user, uintptr_t retaddr)
+void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cs,
+ vaddr addr, int is_write,
+ int is_user, uintptr_t retaddr)
{
- SPARCCPU *cpu = sparc_env_get_cpu(env);
+ SPARCCPU *cpu = SPARC_CPU(cs);
+ CPUSPARCState *env = &cpu->env;
+
#ifdef DEBUG_UNALIGNED
printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
"\n", addr, env->pc);