From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58722) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHbnz-0006YX-Dm for qemu-devel@nongnu.org; Mon, 27 Jun 2016 15:02:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bHbnw-0008CF-Lc for qemu-devel@nongnu.org; Mon, 27 Jun 2016 15:02:47 -0400 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:56475) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHbnu-00088X-Bx for qemu-devel@nongnu.org; Mon, 27 Jun 2016 15:02:44 -0400 From: "Emilio G. Cota" Date: Mon, 27 Jun 2016 15:01:47 -0400 Message-Id: <1467054136-10430-2-git-send-email-cota@braap.org> In-Reply-To: <1467054136-10430-1-git-send-email-cota@braap.org> References: <1467054136-10430-1-git-send-email-cota@braap.org> Subject: [Qemu-devel] [RFC 01/30] softmmu: add cmpxchg helpers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: QEMU Developers , MTTCG Devel Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , Paolo Bonzini , Richard Henderson , Sergey Fedorov , Alvise Rigo , Peter Maydell Signed-off-by: Emilio G. Cota --- softmmu_template.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tcg/tcg.h | 16 +++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/softmmu_template.h b/softmmu_template.h index 208f808..7b519dc 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -548,6 +548,64 @@ void probe_write(CPUArchState *env, target_ulong addr, int mmu_idx, } } #endif + +DATA_TYPE +glue(glue(helper_cmpxchg, SUFFIX), + MMUSUFFIX)(CPUArchState *env, target_ulong addr, DATA_TYPE old, + DATA_TYPE new, TCGMemOpIdx oi, uintptr_t retaddr) +{ + unsigned mmu_idx = get_mmuidx(oi); + int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write; + uintptr_t haddr; + + /* Adjust the given return address. */ + retaddr -= GETPC_ADJ; + + /* If the TLB entry is for a different page, reload and try again. */ + if ((addr & TARGET_PAGE_MASK) + != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { + if (unlikely((addr & (DATA_SIZE - 1)) != 0 + && (get_memop(oi) & MO_AMASK) == MO_ALIGN)) { + cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, + mmu_idx, retaddr); + } + if (!VICTIM_TLB_HIT(addr_write)) { + tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr); + } + tlb_addr = env->tlb_table[mmu_idx][index].addr_write; + } + + /* Handle an IO access. */ + if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) { + /* XXX */ + abort(); + } + + /* Handle slow unaligned access (it spans two pages or IO). */ + if (DATA_SIZE > 1 + && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1 + >= TARGET_PAGE_SIZE)) { + if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) { + cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, + mmu_idx, retaddr); + } + } + + /* Handle aligned access or unaligned access in the same page. */ + if (unlikely((addr & (DATA_SIZE - 1)) != 0 + && (get_memop(oi) & MO_AMASK) == MO_ALIGN)) { + cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, + mmu_idx, retaddr); + } + /* + * If the host allows unaligned accesses, then let the compiler + * do its thing when performing the access on the host. + */ + haddr = addr + env->tlb_table[mmu_idx][index].addend; + return atomic_cmpxchg((DATA_TYPE *)haddr, old, new); +} + #endif /* !defined(SOFTMMU_CODE_ACCESS) */ #undef READ_ACCESS_TYPE diff --git a/tcg/tcg.h b/tcg/tcg.h index 66d7fc0..1fd7ec3 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -1101,6 +1101,22 @@ uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr, # define helper_ret_ldq_cmmu helper_le_ldq_cmmu #endif +uint8_t helper_cmpxchgb_mmu(CPUArchState *env, target_ulong addr, + uint8_t old, uint8_t new, + TCGMemOpIdx oi, uintptr_t retaddr); + +uint16_t helper_cmpxchgw_mmu(CPUArchState *env, target_ulong addr, + uint16_t old, uint16_t new, + TCGMemOpIdx oi, uintptr_t retaddr); + +uint32_t helper_cmpxchgl_mmu(CPUArchState *env, target_ulong addr, + uint32_t old, uint32_t new, + TCGMemOpIdx oi, uintptr_t retaddr); + +uint64_t helper_cmpxchgq_mmu(CPUArchState *env, target_ulong addr, + uint64_t old, uint64_t new, + TCGMemOpIdx oi, uintptr_t retaddr); + #endif /* CONFIG_SOFTMMU */ #endif /* TCG_H */ -- 2.5.0