From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56698) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UkE25-00010q-93 for qemu-devel@nongnu.org; Wed, 05 Jun 2013 09:45:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UkE1z-0002JA-0J for qemu-devel@nongnu.org; Wed, 05 Jun 2013 09:45:45 -0400 Received: from lhrrgout.huawei.com ([194.213.3.17]:44673) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UkE1y-0002Ix-ML for qemu-devel@nongnu.org; Wed, 05 Jun 2013 09:45:38 -0400 Message-ID: <51AF40EE.1000104@huawei.com> Date: Wed, 5 Jun 2013 15:45:18 +0200 From: Claudio Fontana MIME-Version: 1.0 References: <51AF3F25.5050104@huawei.com> In-Reply-To: <51AF3F25.5050104@huawei.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH 2/2] tcg/aarch64: implement user mode qemu ld/st List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Peter Maydell Cc: Laurent Desnogues , Jani Kokkonen , "qemu-devel@nongnu.org" , Richard Henderson From: Jani Kokkonen also put aarch64 in the list of archs that do not need an ldscript. Signed-off-by: Jani Kokkoken Signed-off-by: Claudio Fontana --- configure | 2 +- tcg/aarch64/tcg-target.c | 121 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 117 insertions(+), 6 deletions(-) diff --git a/configure b/configure index f021bdd..d98a9a6 100755 --- a/configure +++ b/configure @@ -4499,7 +4499,7 @@ fi if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then case "$ARCH" in - alpha | s390x) + alpha | s390x | aarch64) # The default placement of the application is fine. ;; *) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 5d0f300..8bb195e 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -24,10 +24,16 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { }; #endif /* NDEBUG */ +#ifdef TARGET_WORDS_BIGENDIAN + #define TCG_LDST_BSWAP 1 +#else + #define TCG_LDST_BSWAP 0 +#endif + static const int tcg_target_reg_alloc_order[] = { TCG_REG_X20, TCG_REG_X21, TCG_REG_X22, TCG_REG_X23, TCG_REG_X24, TCG_REG_X25, TCG_REG_X26, TCG_REG_X27, - TCG_REG_X28, + TCG_REG_X28, /* we will reserve this for GUEST_BASE if configured */ TCG_REG_X9, TCG_REG_X10, TCG_REG_X11, TCG_REG_X12, TCG_REG_X13, TCG_REG_X14, TCG_REG_X15, @@ -51,6 +57,14 @@ static const int tcg_target_call_oarg_regs[1] = { #define TCG_REG_TMP TCG_REG_X8 +#ifndef CONFIG_SOFTMMU +# if defined(CONFIG_USE_GUEST_BASE) +# define TCG_REG_GUEST_BASE TCG_REG_X28 +# else +# define TCG_REG_GUEST_BASE TCG_REG_XZR +# endif +#endif + static inline void reloc_pc26(void *code_ptr, tcg_target_long target) { tcg_target_long offset; uint32_t insn; @@ -713,6 +727,94 @@ static const void * const qemu_st_helpers[4] = { helper_stq_mmu, }; +#else /* !CONFIG_SOFTMMU */ + +static void tcg_out_qemu_ld_direct(TCGContext *s, int opc, TCGReg data_r, + TCGReg addr_r, TCGReg off_r) +{ + switch (opc) { + case 0: + tcg_out_ldst_r(s, LDST_8, LDST_LD, data_r, addr_r, off_r); + break; + case 0 | 4: + tcg_out_ldst_r(s, LDST_8, LDST_LD_S_X, data_r, addr_r, off_r); + break; + case 1: + tcg_out_ldst_r(s, LDST_16, LDST_LD, data_r, addr_r, off_r); + if (TCG_LDST_BSWAP) { + tcg_out_rev16(s, 0, data_r, data_r); + } + break; + case 1 | 4: + if (TCG_LDST_BSWAP) { + tcg_out_ldst_r(s, LDST_16, LDST_LD, data_r, addr_r, off_r); + tcg_out_rev16(s, 0, data_r, data_r); + tcg_out_sxt(s, 1, 1, data_r, data_r); + } else { + tcg_out_ldst_r(s, LDST_16, LDST_LD_S_X, data_r, addr_r, off_r); + } + break; + case 2: + tcg_out_ldst_r(s, LDST_32, LDST_LD, data_r, addr_r, off_r); + if (TCG_LDST_BSWAP) { + tcg_out_rev(s, 0, data_r, data_r); + } + break; + case 2 | 4: + if (TCG_LDST_BSWAP) { + tcg_out_ldst_r(s, LDST_32, LDST_LD, data_r, addr_r, off_r); + tcg_out_rev(s, 0, data_r, data_r); + tcg_out_sxt(s, 1, 2, data_r, data_r); + } else { + tcg_out_ldst_r(s, LDST_32, LDST_LD_S_X, data_r, addr_r, off_r); + } + break; + case 3: + tcg_out_ldst_r(s, LDST_64, LDST_LD, data_r, addr_r, off_r); + if (TCG_LDST_BSWAP) { + tcg_out_rev(s, 1, data_r, data_r); + } + break; + default: + tcg_abort(); + } +} + +static void tcg_out_qemu_st_direct(TCGContext *s, int opc, TCGReg data_r, + TCGReg addr_r, TCGReg off_r) +{ + switch (opc) { + case 0: + tcg_out_ldst_r(s, LDST_8, LDST_ST, data_r, addr_r, off_r); + break; + case 1: + if (TCG_LDST_BSWAP) { + tcg_out_rev16(s, 0, TCG_REG_TMP, data_r); + tcg_out_ldst_r(s, LDST_16, LDST_ST, TCG_REG_TMP, addr_r, off_r); + } else { + tcg_out_ldst_r(s, LDST_16, LDST_ST, data_r, addr_r, off_r); + } + break; + case 2: + if (TCG_LDST_BSWAP) { + tcg_out_rev(s, 0, TCG_REG_TMP, data_r); + tcg_out_ldst_r(s, LDST_32, LDST_ST, TCG_REG_TMP, addr_r, off_r); + } else { + tcg_out_ldst_r(s, LDST_32, LDST_ST, data_r, addr_r, off_r); + } + break; + case 3: + if (TCG_LDST_BSWAP) { + tcg_out_rev(s, 1, TCG_REG_TMP, data_r); + tcg_out_ldst_r(s, LDST_64, LDST_ST, TCG_REG_TMP, addr_r, off_r); + } else { + tcg_out_ldst_r(s, LDST_64, LDST_ST, data_r, addr_r, off_r); + } + break; + default: + tcg_abort(); + } +} #endif /* CONFIG_SOFTMMU */ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) @@ -745,8 +847,9 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) } #else /* !CONFIG_SOFTMMU */ - tcg_abort(); /* TODO */ -#endif + tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, + GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR); +#endif /* CONFIG_SOFTMMU */ } static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) @@ -774,8 +877,9 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) tcg_out_callr(s, TCG_REG_TMP); #else /* !CONFIG_SOFTMMU */ - tcg_abort(); /* TODO */ -#endif + tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, + GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR); +#endif /* CONFIG_SOFTMMU */ } static uint8_t *tb_ret_addr; @@ -1270,6 +1374,13 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, CPU_TEMP_BUF_NLONGS * sizeof(long)); +#if defined(CONFIG_USE_GUEST_BASE) + if (GUEST_BASE) { + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_GUEST_BASE, GUEST_BASE); + tcg_regset_set_reg(s->reserved_regs, TCG_REG_GUEST_BASE); + } +#endif + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); tcg_out_gotor(s, tcg_target_call_iarg_regs[1]); -- 1.8.1