From patchwork Tue Dec 25 20:55:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 154484 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp5214774ljp; Tue, 25 Dec 2018 13:06:24 -0800 (PST) X-Google-Smtp-Source: AFSGD/WfZzBQPu3D8GFCGJXSZSXknT5TV2Qlm6AVUb34VPLrU6MjBYYjHWWSaai0T/ig8Jf7XH3v X-Received: by 2002:ac8:53c6:: with SMTP id c6mr16795366qtq.278.1545771984015; Tue, 25 Dec 2018 13:06:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545771984; cv=none; d=google.com; s=arc-20160816; b=aSmh5gKOqt73S86iLikVIFJWNq6ecePjM6SrOL+PZLoM9cXb5gBviQAxVPq4Yt5+/G 9t99frUWhA3UoTpZAA2ZMUwBjukzgrbhq4SWuq1GaktL+BTbujoGqatHZk8nJ5IKRSAA rTs1pGA+QSFx3fFblmt2IqvjD0tNd7AL8cNEK8nQ/OpIL4tCJ+FMVxItm+8J1OnbJg44 3jrxZkpvfA2POSWbhtkIG76WNiQ6WTgUrIGnFam5A42GftTyb9Dsa8uckTBNPgeO/bDg NX5MKT320tLZchI4DX9WMUvXSzzV9YAbKSzkOywhQRdFURYTmHHHxyMDnBAaUl3d1FH6 WVXw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=myzqUFGUW1JpW5L6sQKOHT3LOmEvIwCqy8Ny+fPHBb8=; b=pW5HzdrV8gsLr4yf608OUbcWam/czTsk0sLStbj6KFn0R5DVNfvCj4MtUUuU28bPQR hHuQebYGpjaqJwq5Qn8gcNVx12wwV/60wj8LWYON7D9gpL3P49FbEWfPulhy3bT/qRho SJaeNiAqVDlunJ8nybQ5kw550EZLC1o5x57L4e5SsXEYKA5vYJr8knBONRh8E4aeUXdj 6fYD7v9/OOyTXyE3Chrr5D7X5amNFqD/SsXhXv1D67SiqjyqQu1zd8rj9c0W/ViDOXXt JsoNwvVhLfT6iis6uzjh19wo8x58YwoCQh1wLFvu+r/qBWZZ+n6yb92i+jGq/W1tyj38 Kasg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=f8bPc5kr; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [208.118.235.17]) by mx.google.com with ESMTPS id i13si7058566qtm.380.2018.12.25.13.06.23 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 25 Dec 2018 13:06:24 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=f8bPc5kr; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1]:43103 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbtuB-0007b1-Ce for patch@linaro.org; Tue, 25 Dec 2018 16:06:23 -0500 Received: from eggs.gnu.org ([208.118.235.92]:50023) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbtli-0005Qs-4x for qemu-devel@nongnu.org; Tue, 25 Dec 2018 15:57:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbtlf-00085P-0K for qemu-devel@nongnu.org; Tue, 25 Dec 2018 15:57:38 -0500 Received: from mail-pl1-x630.google.com ([2607:f8b0:4864:20::630]:40552) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbtle-00084n-Qe for qemu-devel@nongnu.org; Tue, 25 Dec 2018 15:57:34 -0500 Received: by mail-pl1-x630.google.com with SMTP id u18so6802425plq.7 for ; Tue, 25 Dec 2018 12:57:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=myzqUFGUW1JpW5L6sQKOHT3LOmEvIwCqy8Ny+fPHBb8=; b=f8bPc5krs9W0bB8+Fn8yfYQ1aBhQ9JlsghaJqW++GydmxIxxrzAa2kHXprqbpVAls9 1AdbhlvoRE9atTCqr9nG67iMcmTxVNEp5qNs6n0o9FRWuVgtcPdEeRIDxQrsE7Mkm5Mw gpGe/+7OlrzYsjGrIxCDbI2VzPZymNxu5abig= 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=myzqUFGUW1JpW5L6sQKOHT3LOmEvIwCqy8Ny+fPHBb8=; b=NIetbTaN5w43iCfvyUYV7xyS8b6ACMX8vSVdBOuLjO47Zb/W6FQiBdfKmf2hOJS1r+ GKD5SKTQ+s4Ve0Nac3REg7piW5YNCK3JFRPjziMQoerfP21t+1BhvesexwujBHqKWy69 WGgdr2ohcjE6abZD1M+Eg/8AiiWC4y9yfCc5BcK17b0O832AZemnTWbJ7gs/3LdPW8xm AQVOwYG6lOPWJmjdyk8wtnFSy0jTOxMKs30QpJfNF75qJ8XXnlqx6EjGnsqf0kpitqAi dOB1FQNNKgHOPaBXv7DGlY4pYIaMpF0Wfu0bmbsz3ZeLriq007ZmA0JQFOgOOFYskqDN LhcQ== X-Gm-Message-State: AJcUukc8JFeDrRuQdyblN41kKkyv52ZYo5Bo11n1ozpecXAkvOVpV+3I vjeBMvygFGOy0F8lbuW33c0s6ZVBUJY= X-Received: by 2002:a17:902:3f81:: with SMTP id a1mr17264754pld.258.1545771453558; Tue, 25 Dec 2018 12:57:33 -0800 (PST) Received: from cloudburst.home (c211-28-135-144.sunsh3.vic.optusnet.com.au. [211.28.135.144]) by smtp.gmail.com with ESMTPSA id t21sm48501628pgg.24.2018.12.25.12.57.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Dec 2018 12:57:32 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Wed, 26 Dec 2018 07:55:02 +1100 Message-Id: <20181225205529.10874-16-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181225205529.10874-1-richard.henderson@linaro.org> References: <20181225205529.10874-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::630 Subject: [Qemu-devel] [PULL 15/42] tcg/riscv: Add branch and jump instructions 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: peter.maydell@linaro.org, Michael Clark , Alistair Francis Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alistair Francis Signed-off-by: Alistair Francis Signed-off-by: Michael Clark Reviewed-by: Richard Henderson Message-Id: Signed-off-by: Richard Henderson --- tcg/riscv/tcg-target.inc.c | 145 +++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) -- 2.17.2 diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c index 5da850b957..ecc76c9ef8 100644 --- a/tcg/riscv/tcg-target.inc.c +++ b/tcg/riscv/tcg-target.inc.c @@ -750,3 +750,148 @@ static void tcg_out_addsub2(TCGContext *s, tcg_out_opc_reg(s, opc_add, rh, th, TCG_REG_TMP0); } } + +static const struct { + RISCVInsn op; + bool swap; +} tcg_brcond_to_riscv[] = { + [TCG_COND_EQ] = { OPC_BEQ, false }, + [TCG_COND_NE] = { OPC_BNE, false }, + [TCG_COND_LT] = { OPC_BLT, false }, + [TCG_COND_GE] = { OPC_BGE, false }, + [TCG_COND_LE] = { OPC_BGE, true }, + [TCG_COND_GT] = { OPC_BLT, true }, + [TCG_COND_LTU] = { OPC_BLTU, false }, + [TCG_COND_GEU] = { OPC_BGEU, false }, + [TCG_COND_LEU] = { OPC_BGEU, true }, + [TCG_COND_GTU] = { OPC_BLTU, true } +}; + +static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1, + TCGReg arg2, TCGLabel *l) +{ + RISCVInsn op = tcg_brcond_to_riscv[cond].op; + + tcg_debug_assert(op != 0); + + if (tcg_brcond_to_riscv[cond].swap) { + TCGReg t = arg1; + arg1 = arg2; + arg2 = t; + } + + if (l->has_value) { + intptr_t diff = tcg_pcrel_diff(s, l->u.value_ptr); + if (diff == sextreg(diff, 0, 12)) { + tcg_out_opc_branch(s, op, arg1, arg2, diff); + } else { + /* Invert the conditional branch. */ + tcg_out_opc_branch(s, op ^ (1 << 12), arg1, arg2, 8); + tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, diff - 4); + } + } else { + tcg_out_reloc(s, s->code_ptr, R_RISCV_BRANCH, l, 0); + tcg_out_opc_branch(s, op, arg1, arg2, 0); + /* NOP to allow patching later */ + tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0); + } +} + +static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, + TCGReg arg1, TCGReg arg2) +{ + switch (cond) { + case TCG_COND_EQ: + tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2); + tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1); + break; + case TCG_COND_NE: + tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2); + tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret); + break; + case TCG_COND_LT: + tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2); + break; + case TCG_COND_GE: + tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2); + tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1); + break; + case TCG_COND_LE: + tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1); + tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1); + break; + case TCG_COND_GT: + tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1); + break; + case TCG_COND_LTU: + tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2); + break; + case TCG_COND_GEU: + tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2); + tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1); + break; + case TCG_COND_LEU: + tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1); + tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1); + break; + case TCG_COND_GTU: + tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1); + break; + default: + g_assert_not_reached(); + break; + } +} + +static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah, + TCGReg bl, TCGReg bh, TCGLabel *l) +{ + /* todo */ + g_assert_not_reached(); +} + +static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret, + TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh) +{ + /* todo */ + g_assert_not_reached(); +} + +static inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target) +{ + ptrdiff_t offset = tcg_pcrel_diff(s, target); + tcg_debug_assert(offset == sextreg(offset, 1, 20) << 1); + tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, offset); +} + +static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail) +{ + TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA; + ptrdiff_t offset = tcg_pcrel_diff(s, arg); + int ret; + + if (offset == sextreg(offset, 1, 20) << 1) { + /* short jump: -2097150 to 2097152 */ + tcg_out_opc_jump(s, OPC_JAL, link, offset); + } else if (TCG_TARGET_REG_BITS == 32 || + offset == sextreg(offset, 1, 31) << 1) { + /* long jump: -2147483646 to 2147483648 */ + tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP0, 0); + tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, 0); + ret = reloc_call(s->code_ptr - 2, arg);\ + tcg_debug_assert(ret == true); + } else if (TCG_TARGET_REG_BITS == 64) { + /* far jump: 64-bit */ + tcg_target_long imm = sextreg((tcg_target_long)arg, 0, 12); + tcg_target_long base = (tcg_target_long)arg - imm; + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, base); + tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, imm); + } else { + g_assert_not_reached(); + } +} + +static void tcg_out_call(TCGContext *s, tcg_insn_unit *arg) +{ + tcg_out_call_int(s, arg, false); +}