From patchwork Wed Jan 30 23:54:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10789419 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 77071746 for ; Wed, 30 Jan 2019 23:56:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 87BDD2DD1E for ; Wed, 30 Jan 2019 23:56:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 796482DFB1; Wed, 30 Jan 2019 23:56:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D74B42DD1E for ; Wed, 30 Jan 2019 23:56:27 +0000 (UTC) Received: from localhost ([127.0.0.1]:45947 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1goziV-000390-75 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 30 Jan 2019 18:56:27 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56171) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gozhN-0002Cl-BJ for qemu-devel@nongnu.org; Wed, 30 Jan 2019 18:55:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gozhL-0006vA-UL for qemu-devel@nongnu.org; Wed, 30 Jan 2019 18:55:17 -0500 Received: from mail-lj1-x242.google.com ([2a00:1450:4864:20::242]:38647) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gozhL-0006uh-KB for qemu-devel@nongnu.org; Wed, 30 Jan 2019 18:55:15 -0500 Received: by mail-lj1-x242.google.com with SMTP id c19-v6so1092810lja.5 for ; Wed, 30 Jan 2019 15:55:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CALC9WRjIDTDlZd/yG9HWhFgbsYtul3rV7fPyLW3Yck=; b=PYrerDdn5re6e8u7NvX50jvCjiLZ7CDnYLJYrzKMvPTNmyI5UqzbPaK2Qy8eVnMsvE WDf9DKRj/xsPNUk/I1KajOi4je0t0lk1/X+hHqhrVixmU0WUySHaWifQdDmZaqEzw4Dp T6zlM1W13nPcQ1TT/KzmqMWoSkHbJNYYfTD3oYX7U+3/XDnb+IKp14RACkttEFaaPmGj 6H5BgePFRYAbsskH4Wkz3cxX+h1e06kAriKE4joE3TP/xWTKUQrCkm6w3kX8UgL34fO+ /PS7C5bgHGMSLDNIpa+oSSBHsX2Syk0O3T8TEAN7MNb0V8r3xiQ1Z/F2hRQOOFkih2/B I9gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CALC9WRjIDTDlZd/yG9HWhFgbsYtul3rV7fPyLW3Yck=; b=AIgxVkF8Q/boAitHOk/jlNO9wy0Dk7tnZdSfOusopns3OCj3BgdDmsqNQHoUhaBFRm 4v4y3/peeJBVTPqjpk48PNbIF3apsiY3y24+36J5WBtGtk1lEUmPPGnuCNFaqp0BMtQq QrUTy6Airz3vgpIvqdOWbY812rMQ+yIg3J4mtaBM3YQeoIUmS99bZiBqbRuY7jpv7XKJ 5xPLQaZO5ONVU8mKTGudJYQ4c3XOXIQAOzAwwUjTTcvG9SDf+uFNHl9QnQCzm36hZgKo baAYFiEZo7TL73HhWWsKM+k4C9zm8vYrwZy6mhKffIl8LS4Z3wbmdXQakhCFMh9oqVwv CIug== X-Gm-Message-State: AHQUAuZlU6OyBsqIa1EWBuSNcrKvmUsCMFNV2lkQ042hHBqrhD3k2aW/ SKjBHC6qy2ocGyuzREYYvxQam82GTVw= X-Google-Smtp-Source: AHgI3IadD25b6F/Z8uL72cIvuTGWcv15Q6OA1BnKKEdfFbe+cnwB/mi7k8tYoHvi41mFG8kck42//A== X-Received: by 2002:a2e:5816:: with SMTP id m22-v6mr2297353ljb.177.1548892513842; Wed, 30 Jan 2019 15:55:13 -0800 (PST) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id w9sm527752lfc.66.2019.01.30.15.55.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Jan 2019 15:55:13 -0800 (PST) From: Max Filippov To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2019 15:54:40 -0800 Message-Id: <20190130235442.2876-2-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190130235442.2876-1-jcmvbkbc@gmail.com> References: <20190130235442.2876-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::242 Subject: [Qemu-devel] [PATCH 1/3] target/xtensa: sort FLIX instruction opcodes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov , Richard Henderson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Opcodes in different slots may read and write same resources (registers, states). In the absence of resource dependency loops it must be possible to sort opcodes to avoid interference. Record resources used by each opcode in the bundle. Build opcode dependency graph and use topological sort to order its nodes. In case of success translate opcodes in sort order. In case of failure report and raise invalid opcode exception for now. Signed-off-by: Max Filippov --- target/xtensa/translate.c | 202 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 194 insertions(+), 8 deletions(-) diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index a068b6e8335d..b3718d33eec8 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -855,6 +855,138 @@ static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0) return xtensa_isa_length_from_chars(dc->config->isa, &op0); } +struct slot_prop { + XtensaOpcodeOps *ops; + uint32_t arg[MAX_OPCODE_ARGS]; + uint32_t raw_arg[MAX_OPCODE_ARGS]; + uint32_t in[MAX_OPCODE_ARGS]; + uint32_t out[MAX_OPCODE_ARGS]; + unsigned n_in; + unsigned n_out; +}; + +enum resource_type { + XTENSA_CONTROL_FLOW, /* must be first, see op_depends_on */ + XTENSA_REGFILE, + XTENSA_STATE, +}; + +static uint32_t encode_resource(enum resource_type r, unsigned g, unsigned n) +{ + assert(r < 256 && g < 256 && n < 65536); + return (r << 24) | (g << 16) | n; +} + +static bool op_depends_on(const struct slot_prop *a, + const struct slot_prop *b) +{ + unsigned i = 0; + unsigned j = 0; + + if (a->n_out && a->out[0] == encode_resource(XTENSA_CONTROL_FLOW, 0, 0)) { + return true; + } + while (i < a->n_out && j < b->n_in) { + if (a->out[i] < b->in[j]) { + ++i; + } else if (a->out[i] > b->in[j]) { + ++j; + } else { + return true; + } + } + return false; +} + +static bool tsort(struct slot_prop *slot, + struct slot_prop *sorted[], + unsigned n) +{ + struct { + unsigned n_in_edge; + unsigned n_out_edge; + unsigned out_edge[MAX_INSN_SLOTS]; + } node[MAX_INSN_SLOTS]; + + unsigned in[MAX_INSN_SLOTS]; + unsigned i, j; + unsigned n_in = 0; + unsigned n_out = 0; + unsigned n_edge = 0; + + for (i = 0; i < n; ++i) { + node[i].n_in_edge = 0; + node[i].n_out_edge = 0; + } + + for (i = 0; i < n; ++i) { + unsigned n_out_edge = 0; + + for (j = 0; j < n; ++j) { + if (i != j && op_depends_on(slot + j, slot + i)) { + node[i].out_edge[n_out_edge] = j; + ++node[j].n_in_edge; + ++n_out_edge; + ++n_edge; + } + } + node[i].n_out_edge = n_out_edge; + } + + for (i = 0; i < n; ++i) { + if (!node[i].n_in_edge) { + in[n_in] = i; + ++n_in; + } + } + + for (i = 0; i < n_in; ++i) { + unsigned k = in[i]; + + sorted[n_out] = slot + k; + ++n_out; + for (j = 0; j < node[k].n_out_edge; ++j) { + --n_edge; + if (--node[node[k].out_edge[j]].n_in_edge == 0) { + in[n_in] = node[k].out_edge[j]; + ++n_in; + } + } + } + return n_edge == 0; +} + +static void opcode_add_resource(struct slot_prop *op, + uint32_t resource, char direction) +{ + switch (direction) { + case 'i': + assert(op->n_in < ARRAY_SIZE(op->in)); + op->in[op->n_in++] = resource; + break; + case 'o': + assert(op->n_out < ARRAY_SIZE(op->out)); + op->out[op->n_out++] = resource; + break; + case 'm': + assert(op->n_in < ARRAY_SIZE(op->in)); + assert(op->n_out < ARRAY_SIZE(op->out)); + op->in[op->n_in++] = resource; + op->out[op->n_out++] = resource; + break; + default: + g_assert_not_reached(); + } +} + +static int resource_compare(const void *a, const void *b) +{ + const uint32_t *pa = a; + const uint32_t *pb = b; + + return *pa < *pb ? -1 : (*pa > *pb ? 1 : 0); +} + static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) { xtensa_isa isa = dc->config->isa; @@ -864,11 +996,8 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) int slot, slots; unsigned i; uint32_t op_flags = 0; - struct { - XtensaOpcodeOps *ops; - uint32_t arg[MAX_OPCODE_ARGS]; - uint32_t raw_arg[MAX_OPCODE_ARGS]; - } slot_prop[MAX_INSN_SLOTS]; + struct slot_prop slot_prop[MAX_INSN_SLOTS]; + struct slot_prop *ordered[MAX_INSN_SLOTS]; uint32_t debug_cause = 0; uint32_t windowed_register = 0; uint32_t coprocessor = 0; @@ -963,6 +1092,62 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) } } coprocessor |= ops->coprocessor; + + if (slots > 1) { + slot_prop[slot].n_in = 0; + slot_prop[slot].n_out = 0; + + opnds = xtensa_opcode_num_operands(isa, opc); + + for (opnd = 0; opnd < opnds; ++opnd) { + if (xtensa_operand_is_register(isa, opc, opnd)) { + xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd); + uint32_t v = 0; + + xtensa_operand_get_field(isa, opc, opnd, fmt, slot, + dc->slotbuf, &v); + xtensa_operand_decode(isa, opc, opnd, &v); + opcode_add_resource(slot_prop + slot, + encode_resource(XTENSA_REGFILE, rf, v), + xtensa_operand_inout(isa, opc, opnd)); + } + } + + opnds = xtensa_opcode_num_stateOperands(isa, opc); + + for (opnd = 0; opnd < opnds; ++opnd) { + xtensa_state state = xtensa_stateOperand_state(isa, opc, opnd); + + opcode_add_resource(slot_prop + slot, + encode_resource(XTENSA_STATE, 0, state), + xtensa_stateOperand_inout(isa, opc, opnd)); + } + if (xtensa_opcode_is_branch(isa, opc) || + xtensa_opcode_is_jump(isa, opc) || + xtensa_opcode_is_loop(isa, opc) || + xtensa_opcode_is_call(isa, opc)) { + opcode_add_resource(slot_prop + slot, + encode_resource(XTENSA_CONTROL_FLOW, 0, 0), + 'o'); + } + + qsort(slot_prop[slot].in, slot_prop[slot].n_in, sizeof(uint32_t), + resource_compare); + qsort(slot_prop[slot].out, slot_prop[slot].n_out, sizeof(uint32_t), + resource_compare); + } + } + + if (slots > 1) { + if (!tsort(slot_prop, ordered, slots)) { + qemu_log_mask(LOG_UNIMP, + "Circular resource dependencies (pc = %08x)\n", + dc->pc); + gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); + return; + } + } else { + ordered[0] = slot_prop + 0; } if ((op_flags & XTENSA_OP_PRIVILEGED) && @@ -1011,10 +1196,11 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) } for (slot = 0; slot < slots; ++slot) { - XtensaOpcodeOps *ops = slot_prop[slot].ops; + struct slot_prop *pslot = ordered[slot]; + XtensaOpcodeOps *ops = pslot->ops; - dc->raw_arg = slot_prop[slot].raw_arg; - ops->translate(dc, slot_prop[slot].arg, ops->par); + dc->raw_arg = pslot->raw_arg; + ops->translate(dc, pslot->arg, ops->par); } if (dc->base.is_jmp == DISAS_NEXT) { From patchwork Wed Jan 30 23:54:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10789423 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 42B1091E for ; Wed, 30 Jan 2019 23:58:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 54FD42DD1E for ; Wed, 30 Jan 2019 23:58:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4886B2DFB1; Wed, 30 Jan 2019 23:58:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D874E2DD1E for ; Wed, 30 Jan 2019 23:58:21 +0000 (UTC) Received: from localhost ([127.0.0.1]:45961 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gozkL-0004Sg-9r for patchwork-qemu-devel@patchwork.kernel.org; Wed, 30 Jan 2019 18:58:21 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56187) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gozhO-0002Cu-L0 for qemu-devel@nongnu.org; Wed, 30 Jan 2019 18:55:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gozhN-0006vf-Qc for qemu-devel@nongnu.org; Wed, 30 Jan 2019 18:55:18 -0500 Received: from mail-lf1-x141.google.com ([2a00:1450:4864:20::141]:37519) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gozhN-0006vN-Jp for qemu-devel@nongnu.org; Wed, 30 Jan 2019 18:55:17 -0500 Received: by mail-lf1-x141.google.com with SMTP id y11so958523lfj.4 for ; Wed, 30 Jan 2019 15:55:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=FCSvgoGkOWvDkMVrMfOytf4jYXP3UU8jbYEm4OQyMxg=; b=hRR32KXlYDRPkGDoq/fINqZBvr1iHT+Nx3+W0XlMyAZ/4InGX3MkxiIw83J0CkzcJW u1L9BlrGgg9emAgEpVkqdqjaBE+GRUfyzscndwDewMK/eRgafP5wEBnn02pt+Q+sbC3m CsHjrnyngsh3QSFcNOBHST4K4sYsWw9s424OVfrHyI2R2ZrJ8QuxwLQKCVf14ULtXtQu XEzVyE9rE2ohcjImfjDkJ/G6qIeQ4+RIf65r1Gif1VUyhqI1TeqVBJCqCVrRYE9dNfMp zy3/sAKuWcw2poFYdyqVZQ/ok4VUmMObjAo7zB428DLAKwWe+pYPPQe6P7UAlf5IIY4z cLmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=FCSvgoGkOWvDkMVrMfOytf4jYXP3UU8jbYEm4OQyMxg=; b=IYZ0JopicDBiGR0mJWneivjHICsDVd9SHGIsl0HRiE/dEVIbQYxfqKTRvxga/XIyAV 82YbLNREQUO8DU3sjLr0Kjel5UjNj+BOb838aVKpO4/gIYJF5Gha1LmV7iMzAXNhZfYd K35kWl0BTXFcV1rNmjNYcppqYKupjWmOWio9/gS3kpRbQj5nnLxnqAFMCMbcLdusI9wo 11kJXXs6yQ48IDpZomAENlHbUqdQPMQ7vLP+dhZ5PZ6tTWP9mohRXLW+ftyt+JIxmwFA /f8zlCybBqXgb29UyT7xnoZSscCdCrKM19V+lEHhEPMoUwiM/mVjPHd9hB70L670F1F4 tvgw== X-Gm-Message-State: AJcUukdeIKaBzvNnb6WH2DKJYRGhFyl1srwBqvMIj/RYbnLA7RnxeAGA cGIn5anCAb9jvzWTt8AxRkwVOBNil9s= X-Google-Smtp-Source: ALg8bN7PhzomjauKR9ccHVTyeFoQGwn4yw6KR828Jw9haHayM2ut3zVCxa0Pa3U8kYGaklkGTi491g== X-Received: by 2002:a19:a9d2:: with SMTP id s201mr20194664lfe.154.1548892515990; Wed, 30 Jan 2019 15:55:15 -0800 (PST) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id w9sm527752lfc.66.2019.01.30.15.55.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Jan 2019 15:55:15 -0800 (PST) From: Max Filippov To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2019 15:54:41 -0800 Message-Id: <20190130235442.2876-3-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190130235442.2876-1-jcmvbkbc@gmail.com> References: <20190130235442.2876-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::141 Subject: [Qemu-devel] [PATCH 2/3] target/xtensa: add generic instruction post-processing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov , Richard Henderson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Some opcodes may need additional actions at every exit from the translated instruction or may need to amend TB exit slots available to jumps generated for the instruction. Add gen_postprocess function and call it from the gen_jump_slot and from the disas_xtensa_insn. Signed-off-by: Max Filippov --- target/xtensa/cpu.h | 4 ++++ target/xtensa/translate.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index b665bfc0068a..e1002c626954 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -368,9 +368,13 @@ enum { XTENSA_OP_DIVIDE_BY_ZERO = 0x100, + /* Postprocessing flags */ XTENSA_OP_CHECK_INTERRUPTS = 0x200, XTENSA_OP_EXIT_TB_M1 = 0x400, XTENSA_OP_EXIT_TB_0 = 0x800, + XTENSA_OP_SYNC_REGISTER_WINDOW = 0x1000, + + XTENSA_OP_POSTPROCESS = 0x1e00, }; typedef struct XtensaOpcodeOps { diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index b3718d33eec8..f5f5bcfb179a 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -71,6 +71,7 @@ struct DisasContext { unsigned cpenable; + uint32_t op_flags; uint32_t *raw_arg; xtensa_insnbuf insnbuf; xtensa_insnbuf slotbuf; @@ -363,6 +364,8 @@ static bool gen_check_cpenable(DisasContext *dc, uint32_t cp_mask) return true; } +static int gen_postprocess(DisasContext *dc, int slot); + static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot) { tcg_gen_mov_i32(cpu_pc, dest); @@ -372,6 +375,9 @@ static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot) if (dc->base.singlestep_enabled) { gen_exception(dc, EXCP_DEBUG); } else { + if (dc->op_flags & XTENSA_OP_POSTPROCESS) { + slot = gen_postprocess(dc, slot); + } if (slot >= 0) { tcg_gen_goto_tb(slot); tcg_gen_exit_tb(dc->base.tb, slot); @@ -855,6 +861,19 @@ static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0) return xtensa_isa_length_from_chars(dc->config->isa, &op0); } +static int gen_postprocess(DisasContext *dc, int slot) +{ + uint32_t op_flags = dc->op_flags; + + if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) { + gen_check_interrupts(dc); + } + if (op_flags & XTENSA_OP_EXIT_TB_M1) { + slot = -1; + } + return slot; +} + struct slot_prop { XtensaOpcodeOps *ops; uint32_t arg[MAX_OPCODE_ARGS]; @@ -1195,6 +1214,8 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) } } + dc->op_flags = op_flags; + for (slot = 0; slot < slots; ++slot) { struct slot_prop *pslot = ordered[slot]; XtensaOpcodeOps *ops = pslot->ops; @@ -1204,21 +1225,17 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) } if (dc->base.is_jmp == DISAS_NEXT) { - if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) { - gen_check_interrupts(dc); - } - + gen_postprocess(dc, 0); + dc->op_flags = 0; if (op_flags & XTENSA_OP_EXIT_TB_M1) { /* Change in mmu index, memory mapping or tb->flags; exit tb */ gen_jumpi_check_loop_end(dc, -1); } else if (op_flags & XTENSA_OP_EXIT_TB_0) { gen_jumpi_check_loop_end(dc, 0); + } else { + gen_check_loop_end(dc, 0); } } - - if (dc->base.is_jmp == DISAS_NEXT) { - gen_check_loop_end(dc, 0); - } dc->pc = dc->base.pc_next; } From patchwork Wed Jan 30 23:54:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 10789421 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4307391E for ; Wed, 30 Jan 2019 23:56:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 568002DD1E for ; Wed, 30 Jan 2019 23:56:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 49CBA2DFB1; Wed, 30 Jan 2019 23:56:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9FACB2DD1E for ; Wed, 30 Jan 2019 23:56:39 +0000 (UTC) Received: from localhost ([127.0.0.1]:45949 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gozig-0003IV-Sm for patchwork-qemu-devel@patchwork.kernel.org; Wed, 30 Jan 2019 18:56:38 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56209) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gozhW-0002Ih-3Y for qemu-devel@nongnu.org; Wed, 30 Jan 2019 18:55:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gozhU-0006xE-4K for qemu-devel@nongnu.org; Wed, 30 Jan 2019 18:55:25 -0500 Received: from mail-lj1-x244.google.com ([2a00:1450:4864:20::244]:40819) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gozhS-0006wK-7n for qemu-devel@nongnu.org; Wed, 30 Jan 2019 18:55:22 -0500 Received: by mail-lj1-x244.google.com with SMTP id n18-v6so1076740lji.7 for ; Wed, 30 Jan 2019 15:55:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=u/VSCq/Gxp2LXtZxW4cRiYihtnAQZHQTFRGEpRDTooY=; b=kelI6LN/hyRuzEvA28XHvRPlpUtHMIgixeWO8cDKabGcqlmuT7X3Zy3uYC2GiyhxBO HOhuQhCoooyVgvO9UlAqSqHKOC8vBHjYIUi9qJJie2WfrEtup1i6R2J6nVQbPOGIvTsT 3/L63Wgz/zsHDLY0IZp4pWil0no7UVcsP/7MD5+lwR/QZgNodwxB/r3/yop1/6X6IQWT zUYXSrNDfF2szPqHVU4LGlXlTnZ/qYtzMm9Aoo80yY8A4GHzu32Fot3zQruQPRmRBlL3 i8sWyrenzhuBiMGprTYQCpW6aF/gLD85OuA1Y/qOsg5Ws1Ubyk9FuOVNoswGE9QyXrkR UH1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=u/VSCq/Gxp2LXtZxW4cRiYihtnAQZHQTFRGEpRDTooY=; b=iEUiF1EQae7y2hEARjk/FKXZgiAYWFikvFnoDl/HZ+dFlAJMpiNJINxA+Yyz7vhl13 8yTmym46EjjR49WAdaBO0APL2MSSR8n5oW2/eS6Hlj7WG4vRvL4hSzwD0uvHEJWbNZZd gZyH9DEnVMVV2pS6lYkAjA9UAHIqz0bEA7uNV35CvMThL7Apl5zAtvnv1Th7QlCeOXdr ZfdyjOEO2r/61ELZ/FCTGHls9eUDKJwkOgyhjU4CcCZN5crtb6iFPgTGw3SjiDU5YlRe 6J+125OnlJ5ou3e0uiu+p1dBzTYZHulbiVN7cQ5lsIjBGtIT02hc2huFGp6v9+QnnqGo bRvA== X-Gm-Message-State: AJcUukdE3FXc9Kk1R255SYpN4jw+5eYkRi/V3Wmhk8cZ4mGcxDCXXZim hQejva1f+i8J6fiNT/w31C8TGvxTY30= X-Google-Smtp-Source: AHgI3IaMC1vkKantcz79Ow8CPvimQTmkknTZhS/xo0JW6s2zYrETNik6zx8duA45So2uzclznepWgQ== X-Received: by 2002:a2e:1f01:: with SMTP id f1-v6mr20828925ljf.129.1548892518205; Wed, 30 Jan 2019 15:55:18 -0800 (PST) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id w9sm527752lfc.66.2019.01.30.15.55.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Jan 2019 15:55:17 -0800 (PST) From: Max Filippov To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2019 15:54:42 -0800 Message-Id: <20190130235442.2876-4-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190130235442.2876-1-jcmvbkbc@gmail.com> References: <20190130235442.2876-1-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::244 Subject: [Qemu-devel] [PATCH 3/3] target/xtensa: move WINDOW_BASE SR update to postprocessing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov , Richard Henderson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Opcodes that modify WINDOW_BASE SR don't have dependency on opcodes that use windowed registers. If such opcodes are combined in a single instruction they may not be correctly ordered. Instead of adding said dependency use temporary register to store changed WINDOW_BASE value and do actual register window rotation as a postprocessing step. Not all opcodes that change WINDOW_BASE need this: retw, rfwo and rfwu are also jump opcodes, so they are guaranteed to be translated last and thus will not affect other opcodes in the same instruction. Signed-off-by: Max Filippov --- target/xtensa/cpu.h | 1 + target/xtensa/helper.h | 3 +-- target/xtensa/translate.c | 30 ++++++++++++++++++++++-------- target/xtensa/win_helper.c | 14 ++++---------- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index e1002c626954..c2b492e175bd 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -478,6 +478,7 @@ typedef struct CPUXtensaState { float64 f64; } fregs[16]; float_status fp_status; + uint32_t windowbase_next; #ifndef CONFIG_USER_ONLY xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE]; diff --git a/target/xtensa/helper.h b/target/xtensa/helper.h index 2a7db35874fe..b6529a8925f3 100644 --- a/target/xtensa/helper.h +++ b/target/xtensa/helper.h @@ -3,12 +3,11 @@ DEF_HELPER_3(exception_cause, noreturn, env, i32, i32) DEF_HELPER_4(exception_cause_vaddr, noreturn, env, i32, i32, i32) DEF_HELPER_3(debug_exception, noreturn, env, i32, i32) -DEF_HELPER_2(wsr_windowbase, void, env, i32) +DEF_HELPER_1(sync_windowbase, void, env) DEF_HELPER_4(entry, void, env, i32, i32, i32) DEF_HELPER_2(test_ill_retw, void, env, i32) DEF_HELPER_2(test_underflow_retw, void, env, i32) DEF_HELPER_2(retw, i32, env, i32) -DEF_HELPER_2(rotw, void, env, i32) DEF_HELPER_3(window_check, noreturn, env, i32, i32) DEF_HELPER_1(restore_owb, void, env) DEF_HELPER_2(movsp, void, env, i32) diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index f5f5bcfb179a..a61598030dee 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -82,6 +82,7 @@ static TCGv_i32 cpu_R[16]; static TCGv_i32 cpu_FR[16]; static TCGv_i32 cpu_SR[256]; static TCGv_i32 cpu_UR[256]; +static TCGv_i32 cpu_windowbase_next; #include "exec/gen-icount.h" @@ -253,6 +254,11 @@ void xtensa_translate_init(void) uregnames[i].name); } } + + cpu_windowbase_next = + tcg_global_mem_new_i32(cpu_env, + offsetof(CPUXtensaState, windowbase_next), + "windowbase_next"); } static inline bool option_enabled(DisasContext *dc, int opt) @@ -566,7 +572,7 @@ static void gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s) #ifndef CONFIG_USER_ONLY static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v) { - gen_helper_wsr_windowbase(cpu_env, v); + tcg_gen_mov_i32(cpu_windowbase_next, v); } static void gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v) @@ -868,6 +874,9 @@ static int gen_postprocess(DisasContext *dc, int slot) if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) { gen_check_interrupts(dc); } + if (op_flags & XTENSA_OP_SYNC_REGISTER_WINDOW) { + gen_helper_sync_windowbase(cpu_env); + } if (op_flags & XTENSA_OP_EXIT_TB_M1) { slot = -1; } @@ -2270,9 +2279,7 @@ static void translate_rfw(DisasContext *dc, const uint32_t arg[], static void translate_rotw(DisasContext *dc, const uint32_t arg[], const uint32_t par[]) { - TCGv_i32 tmp = tcg_const_i32(arg[0]); - gen_helper_rotw(cpu_env, tmp); - tcg_temp_free(tmp); + tcg_gen_addi_i32(cpu_windowbase_next, cpu_SR[WINDOW_BASE], arg[0]); } static void translate_rsil(DisasContext *dc, const uint32_t arg[], @@ -3092,7 +3099,8 @@ static const XtensaOpcodeOps core_ops[] = { .translate = translate_entry, .test_ill = test_ill_entry, .test_overflow = test_overflow_entry, - .op_flags = XTENSA_OP_EXIT_TB_M1, + .op_flags = XTENSA_OP_EXIT_TB_M1 | + XTENSA_OP_SYNC_REGISTER_WINDOW, }, { .name = "esync", .translate = translate_nop, @@ -3781,7 +3789,9 @@ static const XtensaOpcodeOps core_ops[] = { }, { .name = "rotw", .translate = translate_rotw, - .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, + .op_flags = XTENSA_OP_PRIVILEGED | + XTENSA_OP_EXIT_TB_M1 | + XTENSA_OP_SYNC_REGISTER_WINDOW, }, { .name = "rsil", .translate = translate_rsil, @@ -5044,7 +5054,9 @@ static const XtensaOpcodeOps core_ops[] = { .translate = translate_wsr, .test_ill = test_ill_wsr, .par = (const uint32_t[]){WINDOW_BASE}, - .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, + .op_flags = XTENSA_OP_PRIVILEGED | + XTENSA_OP_EXIT_TB_M1 | + XTENSA_OP_SYNC_REGISTER_WINDOW, .windowed_register_op = 0x1, }, { .name = "wsr.windowstart", @@ -5611,7 +5623,9 @@ static const XtensaOpcodeOps core_ops[] = { .translate = translate_xsr, .test_ill = test_ill_xsr, .par = (const uint32_t[]){WINDOW_BASE}, - .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, + .op_flags = XTENSA_OP_PRIVILEGED | + XTENSA_OP_EXIT_TB_M1 | + XTENSA_OP_SYNC_REGISTER_WINDOW, .windowed_register_op = 0x1, }, { .name = "xsr.windowstart", diff --git a/target/xtensa/win_helper.c b/target/xtensa/win_helper.c index 7d793d4f9cff..d7a4e2782186 100644 --- a/target/xtensa/win_helper.c +++ b/target/xtensa/win_helper.c @@ -96,9 +96,9 @@ void xtensa_rotate_window(CPUXtensaState *env, uint32_t delta) xtensa_rotate_window_abs(env, env->sregs[WINDOW_BASE] + delta); } -void HELPER(wsr_windowbase)(CPUXtensaState *env, uint32_t v) +void HELPER(sync_windowbase)(CPUXtensaState *env) { - xtensa_rotate_window_abs(env, v); + xtensa_rotate_window_abs(env, env->windowbase_next); } void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm) @@ -106,9 +106,8 @@ void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm) int callinc = (env->sregs[PS] & PS_CALLINC) >> PS_CALLINC_SHIFT; env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - imm; - xtensa_rotate_window(env, callinc); - env->sregs[WINDOW_START] |= - windowstart_bit(env->sregs[WINDOW_BASE], env); + env->windowbase_next = env->sregs[WINDOW_BASE] + callinc; + env->sregs[WINDOW_START] |= windowstart_bit(env->windowbase_next, env); } void HELPER(window_check)(CPUXtensaState *env, uint32_t pc, uint32_t w) @@ -196,11 +195,6 @@ uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc) return ret_pc; } -void HELPER(rotw)(CPUXtensaState *env, uint32_t imm4) -{ - xtensa_rotate_window(env, imm4); -} - void xtensa_restore_owb(CPUXtensaState *env) { xtensa_rotate_window_abs(env, (env->sregs[PS] & PS_OWB) >> PS_OWB_SHIFT);