diff options
author | aurel32 | 2008-09-30 08:45:44 +0200 |
---|---|---|
committer | aurel32 | 2008-09-30 08:45:44 +0200 |
commit | 8bb6e981e09c914783c0a7d43c711de4e4f36ad4 (patch) | |
tree | 2860f7b6df5a342b0f684bb365ec99f895bab733 /target-alpha/op_helper.c | |
parent | target-alpha: convert locked load/store to TCG (diff) | |
download | qemu-8bb6e981e09c914783c0a7d43c711de4e4f36ad4.tar.gz qemu-8bb6e981e09c914783c0a7d43c711de4e4f36ad4.tar.xz qemu-8bb6e981e09c914783c0a7d43c711de4e4f36ad4.zip |
target-alpha: convert palcode ops to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5360 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-alpha/op_helper.c')
-rw-r--r-- | target-alpha/op_helper.c | 155 |
1 files changed, 129 insertions, 26 deletions
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index bd20d33aab..393187eb79 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -22,19 +22,11 @@ #include "host-utils.h" #include "softfloat.h" -#include "op_helper.h" - void helper_tb_flush (void) { tlb_flush(env, 1); } -void cpu_dump_EA (target_ulong EA); -void helper_print_mem_EA (target_ulong EA) -{ - cpu_dump_EA(EA); -} - /*****************************************************************************/ /* Exceptions processing helpers */ void helper_excp (int excp, int error) @@ -990,19 +982,48 @@ uint64_t helper_cvtqlsv (uint64_t a) return __helper_cvtql(a, 1, 1); } +/* PALcode support special instructions */ #if !defined (CONFIG_USER_ONLY) -void helper_mfpr (int iprn) +void helper_hw_rei (void) +{ + env->pc = env->ipr[IPR_EXC_ADDR] & ~3; + env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1; + /* XXX: re-enable interrupts and memory mapping */ +} + +void helper_hw_ret (uint64_t a) +{ + env->pc = a & ~3; + env->ipr[IPR_EXC_ADDR] = a & 1; + /* XXX: re-enable interrupts and memory mapping */ +} + +uint64_t helper_mfpr (int iprn, uint64_t val) +{ + uint64_t tmp; + + if (cpu_alpha_mfpr(env, iprn, &tmp) == 0) + val = tmp; + + return val; +} + +void helper_mtpr (int iprn, uint64_t val) { - uint64_t val; + cpu_alpha_mtpr(env, iprn, val, NULL); +} - if (cpu_alpha_mfpr(env, iprn, &val) == 0) - T0 = val; +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_mtpr (int iprn) +void helper_restore_mode (void) { - cpu_alpha_mtpr(env, iprn, T0, NULL); + env->ps = (env->ps & ~0xC) | env->saved_mode; } + #endif /*****************************************************************************/ @@ -1013,48 +1034,130 @@ void helper_mtpr (int iprn) * Hopefully, we emulate the PALcode, then we should never see * HW_LD / HW_ST instructions. */ -void helper_ld_phys_to_virt (void) +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 = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: tlb_addr = env->tlb_table[mmu_idx][index].addr_read; - if ((T0 & TARGET_PAGE_MASK) == + if ((virtaddr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = T0 + env->tlb_table[mmu_idx][index].addend; + physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend; } else { /* the page is not in the TLB : fill it */ retaddr = GETPC(); - tlb_fill(T0, 0, mmu_idx, retaddr); + tlb_fill(virtaddr, 0, mmu_idx, retaddr); goto redo; } - T0 = physaddr; + return physaddr; } -void helper_st_phys_to_virt (void) +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 = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: tlb_addr = env->tlb_table[mmu_idx][index].addr_write; - if ((T0 & TARGET_PAGE_MASK) == + if ((virtaddr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = T0 + env->tlb_table[mmu_idx][index].addend; + physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend; } else { /* the page is not in the TLB : fill it */ retaddr = GETPC(); - tlb_fill(T0, 1, mmu_idx, retaddr); + tlb_fill(virtaddr, 1, mmu_idx, retaddr); goto redo; } - T0 = physaddr; + return physaddr; +} + +void helper_ldl_raw(uint64_t t0, uint64_t t1) +{ + ldl_raw(t1, t0); +} + +void helper_ldq_raw(uint64_t t0, uint64_t t1) +{ + ldq_raw(t1, t0); +} + +void helper_ldl_l_raw(uint64_t t0, uint64_t t1) +{ + env->lock = t1; + ldl_raw(t1, t0); +} + +void helper_ldq_l_raw(uint64_t t0, uint64_t t1) +{ + env->lock = t1; + ldl_raw(t1, t0); +} + +void helper_ldl_kernel(uint64_t t0, uint64_t t1) +{ + ldl_kernel(t1, t0); +} + +void helper_ldq_kernel(uint64_t t0, uint64_t t1) +{ + ldq_kernel(t1, t0); +} + +void helper_ldl_data(uint64_t t0, uint64_t t1) +{ + ldl_data(t1, t0); +} + +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; + + return ret; +} + +uint64_t helper_stq_c_raw(uint64_t t0, uint64_t t1) +{ + uint64_t ret; + + if (t1 == env->lock) { + stq_raw(t1, t0); + ret = 0; + } else + ret = 1; + + env->lock = 1; + + return ret; } #define MMUSUFFIX _mmu |