mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
target-hppa: Implement loads and stores
Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
@@ -2,4 +2,7 @@ DEF_HELPER_2(excp, noreturn, env, int)
|
|||||||
DEF_HELPER_FLAGS_2(tsv, TCG_CALL_NO_WG, void, env, tl)
|
DEF_HELPER_FLAGS_2(tsv, TCG_CALL_NO_WG, void, env, tl)
|
||||||
DEF_HELPER_FLAGS_2(tcond, TCG_CALL_NO_WG, void, env, tl)
|
DEF_HELPER_FLAGS_2(tcond, TCG_CALL_NO_WG, void, env, tl)
|
||||||
|
|
||||||
|
DEF_HELPER_FLAGS_3(stby_b, TCG_CALL_NO_WG, void, env, tl, tl)
|
||||||
|
DEF_HELPER_FLAGS_3(stby_e, TCG_CALL_NO_WG, void, env, tl, tl)
|
||||||
|
|
||||||
DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env)
|
DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
#include "exec/helper-proto.h"
|
#include "exec/helper-proto.h"
|
||||||
|
#include "exec/cpu_ldst.h"
|
||||||
|
|
||||||
void QEMU_NORETURN HELPER(excp)(CPUHPPAState *env, int excp)
|
void QEMU_NORETURN HELPER(excp)(CPUHPPAState *env, int excp)
|
||||||
{
|
{
|
||||||
@@ -54,6 +55,83 @@ void HELPER(tcond)(CPUHPPAState *env, target_ulong cond)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void atomic_store_3(CPUHPPAState *env, target_ulong addr, uint32_t val,
|
||||||
|
uint32_t mask, uintptr_t ra)
|
||||||
|
{
|
||||||
|
uint32_t old, new, cmp;
|
||||||
|
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
uint32_t *haddr = g2h(addr - 1);
|
||||||
|
old = *haddr;
|
||||||
|
while (1) {
|
||||||
|
new = (old & ~mask) | (val & mask);
|
||||||
|
cmp = atomic_cmpxchg(haddr, old, new);
|
||||||
|
if (cmp == old) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
old = cmp;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error "Not implemented."
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void HELPER(stby_b)(CPUHPPAState *env, target_ulong addr, target_ulong val)
|
||||||
|
{
|
||||||
|
uintptr_t ra = GETPC();
|
||||||
|
|
||||||
|
switch (addr & 3) {
|
||||||
|
case 3:
|
||||||
|
cpu_stb_data_ra(env, addr, val, ra);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
cpu_stw_data_ra(env, addr, val, ra);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* The 3 byte store must appear atomic. */
|
||||||
|
if (parallel_cpus) {
|
||||||
|
atomic_store_3(env, addr, val, 0x00ffffffu, ra);
|
||||||
|
} else {
|
||||||
|
cpu_stb_data_ra(env, addr, val >> 16, ra);
|
||||||
|
cpu_stw_data_ra(env, addr + 1, val, ra);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cpu_stl_data_ra(env, addr, val, ra);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HELPER(stby_e)(CPUHPPAState *env, target_ulong addr, target_ulong val)
|
||||||
|
{
|
||||||
|
uintptr_t ra = GETPC();
|
||||||
|
|
||||||
|
switch (addr & 3) {
|
||||||
|
case 3:
|
||||||
|
/* The 3 byte store must appear atomic. */
|
||||||
|
if (parallel_cpus) {
|
||||||
|
atomic_store_3(env, addr - 3, val, 0xffffff00u, ra);
|
||||||
|
} else {
|
||||||
|
cpu_stw_data_ra(env, addr - 3, val >> 16, ra);
|
||||||
|
cpu_stb_data_ra(env, addr - 1, val >> 8, ra);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
cpu_stw_data_ra(env, addr - 2, val >> 16, ra);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
cpu_stb_data_ra(env, addr - 1, val >> 24, ra);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Nothing is stored, but protection is checked and the
|
||||||
|
cacheline is marked dirty. */
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
probe_write(env, addr, cpu_mmu_index(env, 0), ra);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HELPER(loaded_fr0)(CPUHPPAState *env)
|
void HELPER(loaded_fr0)(CPUHPPAState *env)
|
||||||
{
|
{
|
||||||
uint32_t shadow = env->fr[0] >> 32;
|
uint32_t shadow = env->fr[0] >> 32;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user