aboutsummaryrefslogtreecommitdiff
path: root/target-alpha/op_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2011-05-20 13:04:35 -0700
committerRichard Henderson <rth@anchor.twiddle.net>2011-05-31 10:18:04 -0700
commit2374e73edafff0586cbfb67c333c5a7588f81fd5 (patch)
treec6fc0c8343d9178e1fafe6064b00b80e63a422a1 /target-alpha/op_helper.c
parent352e48b0f492359559cb46f8b3222bac9c461ac4 (diff)
target-alpha: Fix translation of PALmode memory insns.
All of the "raw" memory accesses should be "phys" instead. Fix some confusion about argument ordering of the store routines. Fix the implementation of store-conditional. Delete the "alt-mode" helpers. Because we only implement two mmu modes, let /a imply user-mode unconditionally. Leave some combinations of virt access without permission checks as unimplemented. There are too many hoops through which to jump, and these insns will not be needed in the emulation palcode. Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-alpha/op_helper.c')
-rw-r--r--target-alpha/op_helper.c147
1 files changed, 34 insertions, 113 deletions
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 4ccb10b0f4..a90c7a6490 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1188,150 +1188,71 @@ void helper_mtpr (int iprn, uint64_t val)
{
cpu_alpha_mtpr(env, iprn, val, NULL);
}
-
-void helper_set_alt_mode (void)
-{
- env->saved_mode = env->ps & 0xC;
- env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
-}
-
-void helper_restore_mode (void)
-{
- env->ps = (env->ps & ~0xC) | env->saved_mode;
-}
-
#endif
/*****************************************************************************/
/* Softmmu support */
#if !defined (CONFIG_USER_ONLY)
-
-/* XXX: the two following helpers are pure hacks.
- * Hopefully, we emulate the PALcode, then we should never see
- * HW_LD / HW_ST instructions.
- */
-uint64_t helper_ld_virt_to_phys (uint64_t virtaddr)
-{
- uint64_t tlb_addr, physaddr;
- int index, mmu_idx;
- void *retaddr;
-
- mmu_idx = cpu_mmu_index(env);
- index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
- if ((virtaddr & TARGET_PAGE_MASK) ==
- (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend;
- } else {
- /* the page is not in the TLB : fill it */
- retaddr = GETPC();
- tlb_fill(virtaddr, 0, mmu_idx, retaddr);
- goto redo;
- }
- return physaddr;
-}
-
-uint64_t helper_st_virt_to_phys (uint64_t virtaddr)
-{
- uint64_t tlb_addr, physaddr;
- int index, mmu_idx;
- void *retaddr;
-
- mmu_idx = cpu_mmu_index(env);
- index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
- if ((virtaddr & TARGET_PAGE_MASK) ==
- (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend;
- } else {
- /* the page is not in the TLB : fill it */
- retaddr = GETPC();
- tlb_fill(virtaddr, 1, mmu_idx, retaddr);
- goto redo;
- }
- return physaddr;
-}
-
-void helper_ldl_raw(uint64_t t0, uint64_t t1)
+uint64_t helper_ldl_phys(uint64_t p)
{
- ldl_raw(t1, t0);
+ return (int32_t)ldl_phys(p);
}
-void helper_ldq_raw(uint64_t t0, uint64_t t1)
+uint64_t helper_ldq_phys(uint64_t p)
{
- ldq_raw(t1, t0);
+ return ldq_phys(p);
}
-void helper_ldl_l_raw(uint64_t t0, uint64_t t1)
+uint64_t helper_ldl_l_phys(uint64_t p)
{
- env->lock = t1;
- ldl_raw(t1, t0);
+ env->lock_addr = p;
+ return env->lock_value = (int32_t)ldl_phys(p);
}
-void helper_ldq_l_raw(uint64_t t0, uint64_t t1)
+uint64_t helper_ldq_l_phys(uint64_t p)
{
- env->lock = t1;
- ldl_raw(t1, t0);
+ env->lock_addr = p;
+ return env->lock_value = ldl_phys(p);
}
-void helper_ldl_kernel(uint64_t t0, uint64_t t1)
+void helper_stl_phys(uint64_t p, uint64_t v)
{
- ldl_kernel(t1, t0);
+ stl_phys(p, v);
}
-void helper_ldq_kernel(uint64_t t0, uint64_t t1)
+void helper_stq_phys(uint64_t p, uint64_t v)
{
- ldq_kernel(t1, t0);
+ stq_phys(p, v);
}
-void helper_ldl_data(uint64_t t0, uint64_t t1)
+uint64_t helper_stl_c_phys(uint64_t p, uint64_t v)
{
- ldl_data(t1, t0);
-}
+ uint64_t ret = 0;
-void helper_ldq_data(uint64_t t0, uint64_t t1)
-{
- ldq_data(t1, t0);
-}
-
-void helper_stl_raw(uint64_t t0, uint64_t t1)
-{
- stl_raw(t1, t0);
-}
-
-void helper_stq_raw(uint64_t t0, uint64_t t1)
-{
- stq_raw(t1, t0);
-}
-
-uint64_t helper_stl_c_raw(uint64_t t0, uint64_t t1)
-{
- uint64_t ret;
-
- if (t1 == env->lock) {
- stl_raw(t1, t0);
- ret = 0;
- } else
- ret = 1;
-
- env->lock = 1;
+ if (p == env->lock_addr) {
+ int32_t old = ldl_phys(p);
+ if (old == (int32_t)env->lock_value) {
+ stl_phys(p, v);
+ ret = 1;
+ }
+ }
+ env->lock_addr = -1;
return ret;
}
-uint64_t helper_stq_c_raw(uint64_t t0, uint64_t t1)
+uint64_t helper_stq_c_phys(uint64_t p, uint64_t v)
{
- uint64_t ret;
+ uint64_t ret = 0;
- if (t1 == env->lock) {
- stq_raw(t1, t0);
- ret = 0;
- } else
- ret = 1;
-
- env->lock = 1;
+ if (p == env->lock_addr) {
+ uint64_t old = ldq_phys(p);
+ if (old == env->lock_value) {
+ stq_phys(p, v);
+ ret = 1;
+ }
+ }
+ env->lock_addr = -1;
return ret;
}