From patchwork Sun Jul 24 17:11:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 106536 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 21A22B6F83 for ; Mon, 25 Jul 2011 03:14:25 +1000 (EST) Received: from localhost ([::1]:54165 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ql2Fx-0007Z1-UX for incoming@patchwork.ozlabs.org; Sun, 24 Jul 2011 13:14:21 -0400 Received: from eggs.gnu.org ([140.186.70.92]:57663) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ql2Fb-0006QR-Ko for qemu-devel@nongnu.org; Sun, 24 Jul 2011 13:14:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ql2FC-0005Mk-CV for qemu-devel@nongnu.org; Sun, 24 Jul 2011 13:13:59 -0400 Received: from mail-fx0-f47.google.com ([209.85.161.47]:58230) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ql2FC-0005Lw-4d for qemu-devel@nongnu.org; Sun, 24 Jul 2011 13:13:34 -0400 Received: by mail-fx0-f47.google.com with SMTP id 11so8355253fxg.34 for ; Sun, 24 Jul 2011 10:13:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=KU7CunGsHqXhxS4/0PybS86mshk7zYM90fwKG0W4Sfg=; b=iEFA7Suk++krT5vpMUxQ6jPPMugKWwK9lqaokBgHRxGxaSmDUt5FyHOCM29N9nh32M WLTJ4BO27zhnRA3TrCve4vf1ZMpU8HX2LVLnZmHdwdJ0qxpFLYoGenRyaD/Hvm+ZRIMB C5HWziV+tyYin6hKFMKXHYp3KoYiIy9o/p8uk= Received: by 10.204.8.151 with SMTP id h23mr1104877bkh.233.1311527608596; Sun, 24 Jul 2011 10:13:28 -0700 (PDT) Received: from octofox.metropolis ([188.134.19.124]) by mx.google.com with ESMTPS id p16sm1070796bku.64.2011.07.24.10.13.25 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 24 Jul 2011 10:13:27 -0700 (PDT) Received: by octofox.metropolis (sSMTP sendmail emulation); Sun, 24 Jul 2011 21:13:21 +0400 From: Max Filippov To: qemu-devel@nongnu.org Date: Sun, 24 Jul 2011 21:11:00 +0400 Message-Id: <1311527469-12963-23-git-send-email-jcmvbkbc@gmail.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1311527469-12963-1-git-send-email-jcmvbkbc@gmail.com> References: <1311527469-12963-1-git-send-email-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.161.47 Cc: jcmvbkbc@gmail.com Subject: [Qemu-devel] [PATCH v2 22/31] target-xtensa: implement unaligned exception option X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org See ISA, 4.4.4 for details. Correct (aligned as per ISA) address for unaligned access is generated in case this option is not enabled. Signed-off-by: Max Filippov --- v1 -> v2 changes: - use ALIGNED_ONLY to handle unaligned memory access; --- target-xtensa/helper.c | 4 ++- target-xtensa/op_helper.c | 26 ++++++++++++++++++++++++ target-xtensa/translate.c | 47 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index 84fe9e2..cde1b27 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -45,7 +45,9 @@ void cpu_reset(CPUXtensaState *env) static const XtensaConfig core_config[] = { { .name = "sample-xtensa-core", - .options = -1, + .options = -1 ^ + (XTENSA_OPTION_BIT(XTENSA_OPTION_HW_ALIGNMENT) | + XTENSA_OPTION_BIT(XTENSA_OPTION_MMU)), .nareg = 64, .ndepc = 1, .excm_level = 16, diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index 482fb0c..85de3a0 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -29,6 +29,10 @@ #include "helpers.h" #include "host-utils.h" +static void do_unaligned_access(target_ulong addr, int is_write, int is_user, + void *retaddr); + +#define ALIGNED_ONLY #define MMUSUFFIX _mmu #define SHIFT 0 @@ -43,6 +47,28 @@ #define SHIFT 3 #include "softmmu_template.h" +static void do_restore_state(void *pc_ptr) +{ + TranslationBlock *tb; + uint32_t pc = (uint32_t)(intptr_t)pc_ptr; + + tb = tb_find_pc(pc); + if (tb) { + cpu_restore_state(tb, env, pc); + } +} + +static void do_unaligned_access(target_ulong addr, int is_write, int is_user, + void *retaddr) +{ + if (xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) && + !xtensa_option_enabled(env->config, XTENSA_OPTION_HW_ALIGNMENT)) { + do_restore_state(retaddr); + HELPER(exception_cause_vaddr)( + env->pc, LOAD_STORE_ALIGNMENT_CAUSE, addr); + } +} + void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) { tlb_set_page(cpu_single_env, diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 889c9b2..62588d6 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -203,6 +203,16 @@ static void gen_exception_cause(DisasContext *dc, uint32_t cause) tcg_temp_free(_cause); } +static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause, + TCGv_i32 vaddr) +{ + TCGv_i32 _pc = tcg_const_i32(dc->pc); + TCGv_i32 _cause = tcg_const_i32(cause); + gen_helper_exception_cause_vaddr(_pc, _cause, vaddr); + tcg_temp_free(_pc); + tcg_temp_free(_cause); +} + static void gen_check_privilege(DisasContext *dc) { if (dc->cring) { @@ -397,6 +407,23 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) } } +static void gen_load_store_alignment(DisasContext *dc, int shift, + TCGv_i32 addr, bool no_hw_alignment) +{ + if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) { + tcg_gen_andi_i32(addr, addr, ~0 << shift); + } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) && + no_hw_alignment) { + int label = gen_new_label(); + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_andi_i32(tmp, addr, ~(~0 << shift)); + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); + gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr); + gen_set_label(label); + tcg_temp_free(tmp); + } +} + static void disas_xtensa_insn(DisasContext *dc) { #define HAS_OPTION(opt) do { \ @@ -1322,6 +1349,9 @@ static void disas_xtensa_insn(DisasContext *dc) #define gen_load_store(type, shift) do { \ TCGv_i32 addr = tcg_temp_new_i32(); \ tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \ + if (shift) { \ + gen_load_store_alignment(dc, shift, addr, false); \ + } \ tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \ tcg_temp_free(addr); \ } while (0) @@ -1451,6 +1481,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 9: /*L16SI*/ gen_load_store(ld16s, 1); break; +#undef gen_load_store case 10: /*MOVI*/ tcg_gen_movi_i32(cpu_R[RRI8_T], @@ -1458,9 +1489,17 @@ static void disas_xtensa_insn(DisasContext *dc) ((RRI8_S & 0x8) ? 0xfffff000 : 0)); break; +#define gen_load_store_no_hw_align(type) do { \ + TCGv_i32 addr = tcg_temp_local_new_i32(); \ + tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); \ + gen_load_store_alignment(dc, 2, addr, true); \ + tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \ + tcg_temp_free(addr); \ + } while (0) + case 11: /*L32AIy*/ HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO); - gen_load_store(ld32u, 2); /*TODO acquire?*/ + gen_load_store_no_hw_align(ld32u); /*TODO acquire?*/ break; case 12: /*ADDI*/ @@ -1480,6 +1519,7 @@ static void disas_xtensa_insn(DisasContext *dc) tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]); tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); + gen_load_store_alignment(dc, 2, addr, true); tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring); tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T], cpu_SR[SCOMPARE1], label); @@ -1494,15 +1534,15 @@ static void disas_xtensa_insn(DisasContext *dc) case 15: /*S32RIy*/ HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO); - gen_load_store(st32, 2); /*TODO release?*/ + gen_load_store_no_hw_align(st32); /*TODO release?*/ break; +#undef gen_load_store_no_hw_align default: /*reserved*/ RESERVED(); break; } break; -#undef gen_load_store case 3: /*LSCIp*/ HAS_OPTION(XTENSA_OPTION_COPROCESSOR); @@ -1708,6 +1748,7 @@ static void disas_xtensa_insn(DisasContext *dc) #define gen_narrow_load_store(type) do { \ TCGv_i32 addr = tcg_temp_new_i32(); \ tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \ + gen_load_store_alignment(dc, 2, addr, false); \ tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \ tcg_temp_free(addr); \ } while (0)