From patchwork Wed Feb 17 23:39:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383928 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3217581jao; Wed, 17 Feb 2021 15:40:47 -0800 (PST) X-Google-Smtp-Source: ABdhPJxtO6jUOWG5YZlhpffdGytFOFkKNETYVAB4g82x1BMaMByVoxkgOUkQdjp8+rUHdoYP0tKh X-Received: by 2002:a25:b09e:: with SMTP id f30mr2857421ybj.199.1613605247636; Wed, 17 Feb 2021 15:40:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605247; cv=none; d=google.com; s=arc-20160816; b=KA+5MSmok/7JEryAKW27dQNUxXbXA+KCnwIGAlZv6C9X4JHuiig/q0q+JKNe0M7+LG sXkVEdAsUa3/jy3+6TXlsHgKf8y0OSuc2CneMFxmwurBG6vEG9iJt+rJxPhuah4wfw1Y UOtO1Cd3RyWKHgzlbZuK4HMBvxAwjOOnu4SYPLd5L/e0Ud7hlLlL5qBfvuAtngXFuXfM W0+jNc2RDWgDuo1HaslYLpteC6ssyJbMH2OvxURvvv104wmiRRfBSMWltQ6Qd2mDT4Xx H26ptE6OPjYd9QxyJuo9+Ejt94Oe+/4DtUlF4ZMzNWAXkmZtRrzqBycKCdu5PZN4SN0x 9M8Q== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=AcGphVvC0/caTtvh4+lg1JnnXtDLzy6lys2FZhvbGvY=; b=dWn3jhNoDhgu5+aZZGHwkf1a0O7SXKb/anY4n8wQI7KwVv441WwqHynMaV25E3gux7 KLi2zchrgh6USuRlK7uM08mk54AHUxrXKEqmbjqnq+lXxqQFhMYDT6iOuESG8gjtZxdl JzcOKZ3eSjqk7Lg23VaSZVRUV5J1XtgJMQVpCWQ7MAvTMb3XnqccapidABKiETBuGaVu /V6g/xyh+5rtJuCmIilsDDiQHH026LGGywbUyDCUeBwe2ylULjlLjkR2OWx9U6jBzBMW /5UwcjwXlTn1NVtw6Q/G0qcFZGFNzGlFNGsHPBdmbhp0y3O38ovPk/tPMulKuhjJyLN/ TywA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=uQcXATsi; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.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. [209.51.188.17]) by mx.google.com with ESMTPS id d203si3959832ybh.272.2021.02.17.15.40.47 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:40:47 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=uQcXATsi; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.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 ([::1]:33658 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWR5-0007e4-2C for patch@linaro.org; Wed, 17 Feb 2021 18:40:47 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50502) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWQs-0007cQ-SJ for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:34 -0500 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]:42333) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWQr-0004Xi-5O for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:34 -0500 Received: by mail-pl1-x635.google.com with SMTP id s16so195923plr.9 for ; Wed, 17 Feb 2021 15:40:32 -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 :mime-version:content-transfer-encoding; bh=AcGphVvC0/caTtvh4+lg1JnnXtDLzy6lys2FZhvbGvY=; b=uQcXATsih62P0UK9bhURf3ze2dRvXMsnNR0lFCgJiZe4WcacGxVUOz81XmOFqBgRBd 2szhDlI6Uk/Y5Pl7ISxCx86/pmbyDR4jbcI7KIqt0LZSgu9XGX9xv4o5TI1/JXD5nbL0 +hFOUuyJo7QxC1mulXQk4lCYZx0aV8wEoRBy/Ues9yCFhE0mtnpZ67i+5M+1dDgQg/Vm x5sqEhcV/qVpWfmBC2JAITYMGrQlZdhJbeCStSY6aFdfRLhrgOuX6StOO9lpH69bTkFM dfsxUsbF2bmXA+foUVXSjimQnYzIBL4gT0/1PDxSUlOXv7bdFlFuTlJ95naQ34WWJ7VP 3Xwg== 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:mime-version:content-transfer-encoding; bh=AcGphVvC0/caTtvh4+lg1JnnXtDLzy6lys2FZhvbGvY=; b=P83nTTbFbTW9iXbwHQbYKNJ7RWTjfecBrCuzR8HncYx3tOV3gAf6jkSWM+HfFjjD8x BEalm7N96hd6dy6DMSJ3auVmh4bcnOXOX3cAJZ3J5SKdEgLhUCCi71jihzjERqu/Zf1o A8GD6FO3YcWIVEue94sK/6Hswvlx5THlbG+1VaeuMPW7XRhdQq7KIhkRbOyOsumwR+pp YkOcL3wEHwZFPapZzYtyZTX7UPGatPpvMnbIWyPurbLC0MGnD/ZtEnRKmmrhjqtFcE2E Vx+HbsreB5YV2raRpKEostVd98xK7rYTTZbPy6nDI0YpBsiNuuQJKSyzMhEEcbBAauUQ Wemw== X-Gm-Message-State: AOAM5305Ged8dEHcNa0vBMErpMZpU7MRE321+s2Hdxl8JKy3deFJh5h+ 8Fhh0eicK2jv/teY0hXs3nMsjdFCkdqxoA== X-Received: by 2002:a17:90b:1495:: with SMTP id js21mr1191621pjb.127.1613605229982; Wed, 17 Feb 2021 15:40:29 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:29 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 01/35] qemu/int128: Add int128_or Date: Wed, 17 Feb 2021 15:39:49 -0800 Message-Id: <20210217234023.1742406-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::635; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x635.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, =?utf-8?q?Alex_Benn=C3=A9e?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson Tested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Message-Id: <20201021045149.1582203-2-richard.henderson@linaro.org> --- include/qemu/int128.h | 10 ++++++++++ 1 file changed, 10 insertions(+) -- 2.25.1 diff --git a/include/qemu/int128.h b/include/qemu/int128.h index 76ea405922..52fc238421 100644 --- a/include/qemu/int128.h +++ b/include/qemu/int128.h @@ -58,6 +58,11 @@ static inline Int128 int128_and(Int128 a, Int128 b) return a & b; } +static inline Int128 int128_or(Int128 a, Int128 b) +{ + return a | b; +} + static inline Int128 int128_rshift(Int128 a, int n) { return a >> n; @@ -208,6 +213,11 @@ static inline Int128 int128_and(Int128 a, Int128 b) return (Int128) { a.lo & b.lo, a.hi & b.hi }; } +static inline Int128 int128_or(Int128 a, Int128 b) +{ + return (Int128) { a.lo | b.lo, a.hi | b.hi }; +} + static inline Int128 int128_rshift(Int128 a, int n) { int64_t h; From patchwork Wed Feb 17 23:39:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383929 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3217594jao; Wed, 17 Feb 2021 15:40:48 -0800 (PST) X-Google-Smtp-Source: ABdhPJy2hlUxRKAziJwEmAnbVMQ1Q+ah+ObXze7g0IqSApZyU71cg9XIto+JxzjPukPERropGpGE X-Received: by 2002:a25:2b88:: with SMTP id r130mr2637964ybr.460.1613605248717; Wed, 17 Feb 2021 15:40:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605248; cv=none; d=google.com; s=arc-20160816; b=NlnD1q8ASYQOgMeRsE6v/6/XvxbRuYjoImhZh4yx2V42wbFsQqLTG1afUp8pZ6cdQo r85qh6UB5bBVW8RzYJtcZfo+TA1OUCH7AlKAzn84zkRsWUsdxCGpjNifjUjdJJVOuVy7 hrQraxb9WF8ZCQSxmUqLIGcBDnHC4K0qTb+DspPgllS8UfHTodx1DBIL5TYPwi8V6WPf yfXOYqKxY+4psX0CpSWc3yqcB6JJ7XrCrQQa1hdzWTjRFuugeELzDhzGppCpYGaOVlVx vyoDM7Xxosxy3OpTuBRHm+Dii6uVq2Ivswc3rIG7aG3g4vgnMjglkVT3+LXhDx4sJknh JoLQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=GdkpxzgcEFcZSIACGMXXs19rNBJ+Fas4AM99kJ+waPE=; b=vhXNmP47CzW0l57m/BDhhoQf0PUgBioTMqj98JoUnQ4jX0wZvOolmZjqBnYSqkbX0T 5tY4TgTImiJUJDlm46U1LiqhabcTkzE7Xk9hDPE5/jEXnSiDrL2PavBAN+9VZRmzzOA5 eFiTHkEkq57i/wGlrTJBrhMRjk5XHJ4EwK7rGLqQ9zkvNRl0eTOKTxTcYkmyYUyXE5PR 19le98Aum+j4lCuGN5l+6Ct/f/ZXc3PqfsT6vFsG14v26IOLdmo0FQtqaddaOLS3FlbJ 0uQNlJ4Gbv+dGH1PPQ+GbNtmlEepiiqqYdNLPp0Qmw56nl7u7vTJLdzK3Z+uYHcfp51x ip6g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wJXFuZ4X; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id k3si3504504ybh.301.2021.02.17.15.40.48 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:40:48 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wJXFuZ4X; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:33680 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWR6-0007ee-5S for patch@linaro.org; Wed, 17 Feb 2021 18:40:48 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50516) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWQu-0007dc-Br for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:36 -0500 Received: from mail-pf1-x42a.google.com ([2607:f8b0:4864:20::42a]:38929) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWQs-0004ZT-Kx for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:36 -0500 Received: by mail-pf1-x42a.google.com with SMTP id 189so32019pfy.6 for ; Wed, 17 Feb 2021 15:40: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 :mime-version:content-transfer-encoding; bh=GdkpxzgcEFcZSIACGMXXs19rNBJ+Fas4AM99kJ+waPE=; b=wJXFuZ4XMrEkUyyI5wsGPK4g50YqkYKrswA2Ki3gX+dHm8Anln+LzVRV/FXBI9t8X1 5SgR9Cs9tXEfj907aEYxkLttQUg4c/+EDk7GPz+KneGg+6k+Ji4O8vm6oWGn3TgbRTi8 sRc2ZvfpXllCSIdm2X1dy/MI/5yVAzkEngKpeXKjC4u8LZ1PCrYrs7lVN61d844TKJn0 QyJKC7zd+6whaTXTuU9OZsvevwi1MNWZpz3a5e87uH2ejWLTEGgPeuJP90+RTYxMYON0 DXOLCr+XyQU9yVlbDDLQwS+Hh3/XdfsLjMVDTKxTOiKjM9YUm+MShAnq8uM1e1LxGFf2 Uuow== 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:mime-version:content-transfer-encoding; bh=GdkpxzgcEFcZSIACGMXXs19rNBJ+Fas4AM99kJ+waPE=; b=YUQfQTWHiYiDWr3Wcyq/D60TD8QGMOPhfjX05sZMx838ltqS6DUCtZUNsQ6e9tVfUk 3043dYnM8G1Smg+eryHay/TNwFXHXAi6WqX99wcHQPQ9Wa5WMeeB5W8tkXSpvYoYP7fA ZalinNWunVhZER0U5KIijQFElk31B2qBuEBkJs7b49rSGIon63VhnwsBsUU6K6liOc83 4+nWWMgKYJUxFxXGg1wzoOcygFahjayHGC0nds6Xq0FKHm4uvT+WKVSxtr9S2lcA7MpY KZxOEM9uUnqGAuVwyvhWHnxfsCEjJxkKLV6e261Jf9tQ7lG1SetWtLLDuBCRV1AQbceH mXOg== X-Gm-Message-State: AOAM532/cjYa3QLc/tg3aYcxvEaG7t9ZX1MhObD9tl4XYvfZ/UyhbyfZ vMuSQSt4OXNeyVAsvx9+A6cY6H61sqGywg== X-Received: by 2002:a63:4507:: with SMTP id s7mr1546722pga.390.1613605233069; Wed, 17 Feb 2021 15:40:33 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:32 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 02/35] Hexagon Update MAINTAINERS file Date: Wed, 17 Feb 2021 15:39:50 -0800 Message-Id: <20210217234023.1742406-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42a; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Add Taylor Simpson as the Hexagon target maintainer Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-2-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) -- 2.25.1 diff --git a/MAINTAINERS b/MAINTAINERS index 68ee271792..c277a7788c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -188,6 +188,15 @@ F: include/hw/cris/ F: tests/tcg/cris/ F: disas/cris.c +Hexagon TCG CPUs +M: Taylor Simpson +S: Supported +F: target/hexagon/ +F: linux-user/hexagon/ +F: tests/tcg/hexagon/ +F: disas/hexagon.c +F: default-configs/targets/hexagon-linux-user.mak + HPPA (PA-RISC) TCG CPUs M: Richard Henderson S: Maintained From patchwork Wed Feb 17 23:39:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383930 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3217654jao; Wed, 17 Feb 2021 15:40:53 -0800 (PST) X-Google-Smtp-Source: ABdhPJwKgtEUIRxo9xnEbdYzPsd4Q6VQ6Rb2DcHxE4L5ejFcsglP8+HkgfKEip1ZgKggcCR/gmSK X-Received: by 2002:a05:6902:6b2:: with SMTP id j18mr2573561ybt.383.1613605253611; Wed, 17 Feb 2021 15:40:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605253; cv=none; d=google.com; s=arc-20160816; b=orkYdx7xFpIJ5cpFe5/iByoLqYN5Lak1rwEj+v9H8gDEzH8dw7YNRZ6oJLKXUVQK05 2HtojRKh2sGdOt57hCW7yhHnefAKivD6IXFRvgrjy7bciCdf2Bnj9zcqBBV64PkB2/JS EqRU0O8e5uRNY/5FK/xiSArEkzO8y/KOPUeakP6odA5x0NFnrVUWsMBSHcHAO0Jrihx1 jOEbbtP6G50lDdbnzKv8ULq6wzgnc0L0o4EwS+4X9v0+vaHtgwfKIsTAJj95LBeL16ud F1/qrpSWLMiqsnfMNO4NJLgEhSMgD0Fy6nfZF6RMrVRq0XOXP9j31agY/wCHaGlqajbM tK7A== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=ChSDu9KMIIDbw7eUjDHT7R30zKxq07lKROnYqWY1Oxw=; b=QfsyyjYdJ7KNdsclP57UV9YSRJNZxomVn0h5RkA0aiKGGv0dV7nAIRDqFZwRLiZLhK F9gzSu3wf9IwSavcJkj8GBmUWuDR4FuQqHOiPYZ38AmfibyGVKeuYRnSM7BbctTvW7F4 pPZJy78a0fXXXxHF+Qo+MGgmMqcu8CAPRkBQY1tYZf0yQpu31aZb44YkDPg7icH1+F7+ PUZwZpA8xO84vxeG0ROAgA8+l0CMksbGL3YgCqZry/8wnXg8zVRkmP1e5bHsOzR5S2Nu W3KLFqC7G88w46WZ6Qaz9SgpZbABFpyMhG/8T5eYweyS4O/WgXRZQzyiyhtZIaf4IYFn 3l7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mNRceI3G; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id s5si3272538ybm.453.2021.02.17.15.40.53 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:40:53 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mNRceI3G; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:33918 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWRB-0007kg-1E for patch@linaro.org; Wed, 17 Feb 2021 18:40:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50530) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWQx-0007gk-5Q for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:39 -0500 Received: from mail-pf1-x42c.google.com ([2607:f8b0:4864:20::42c]:38931) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWQu-0004Zg-N1 for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:38 -0500 Received: by mail-pf1-x42c.google.com with SMTP id 189so32072pfy.6 for ; Wed, 17 Feb 2021 15:40:36 -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 :mime-version:content-transfer-encoding; bh=ChSDu9KMIIDbw7eUjDHT7R30zKxq07lKROnYqWY1Oxw=; b=mNRceI3GHZqsv8R1B/eXQAS6a7UfUWH4D89LCfYwnaCexNF9EEyDCWs0tNno3Z0x82 uMUYxHoiSf6FifwGQESzcolcbLtOHRxvpIz5PeEvgxLeiCHyPDvowcIKPWH4AjCqWItq ayNOAwprH+DD6cQpbcXxRpzTtUlbRW6eDfEZSCX8FtyAypwv4SyXV5qN5KqKUp43WRWG 12sLP7tpezx26Gq+ouLwTsO5pqBeP8uEMmabfF3ukYya74I6IAwVdvaxNPib6LXXVsc/ pkOQbfbR05F9fRg3ghmBIF/ze+NYvXxKusrT/ocyfFy8tNEYav++bQTvwtlJJD45ya8Y KPHA== 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:mime-version:content-transfer-encoding; bh=ChSDu9KMIIDbw7eUjDHT7R30zKxq07lKROnYqWY1Oxw=; b=eVMfBVO4lzuvsnXjQbMWB6ZkuJJoxX1qMnrAes4rYEXIOLmPdE8Ih7o4DD73iumLUQ cIKzVXpphZeTaLIWDO1iFKCvaJEy91mNpXhLmUSPPT8ELsp1QR7pzikWJ0q+NKwIThuP LXz28wmtz28dXqU7ONpeqSOzoPq32IZ1phADXnYA0K2QrH/gfGx5YfJ+8aD85Uy/3keJ oy2b+gKi7DOh+pN9rUXTHFCaDd9mTGc1XvQsPerMxkn+dnvMoKyPdl6sVKFPh6HNseHZ QlLz8wS3BSmFld2qpq5bC4W/uKPLoDCY16kqtXA2BC5aWzmCi7TnYCgk4sgacEFbCY2a X/2w== X-Gm-Message-State: AOAM533NdRS6chJFjZBdIDEYC4dIHb3tKBce2cYnLQPtuulRcY8jzXdw l0a7y9//eWKGtpwWXenYzjCv+vBu67c0NA== X-Received: by 2002:a63:d355:: with SMTP id u21mr1577968pgi.133.1613605234869; Wed, 17 Feb 2021 15:40:34 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:34 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 03/35] Hexagon (target/hexagon) README Date: Wed, 17 Feb 2021 15:39:51 -0800 Message-Id: <20210217234023.1742406-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42c; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Gives an introduction and overview to the Hexagon target Signed-off-by: Taylor Simpson Message-Id: <1612763186-18161-3-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/README | 235 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 target/hexagon/README -- 2.25.1 diff --git a/target/hexagon/README b/target/hexagon/README new file mode 100644 index 0000000000..b0b2435070 --- /dev/null +++ b/target/hexagon/README @@ -0,0 +1,235 @@ +Hexagon is Qualcomm's very long instruction word (VLIW) digital signal +processor(DSP). + +The following versions of the Hexagon core are supported + Scalar core: v67 + https://developer.qualcomm.com/downloads/qualcomm-hexagon-v67-programmer-s-reference-manual + +We presented an overview of the project at the 2019 KVM Forum. + https://kvmforum2019.sched.com/event/Tmwc/qemu-hexagon-automatic-translation-of-the-isa-manual-pseudcode-to-tiny-code-instructions-of-a-vliw-architecture-niccolo-izzo-revng-taylor-simpson-qualcomm-innovation-center + +*** Tour of the code *** + +The qemu-hexagon implementation is a combination of qemu and the Hexagon +architecture library (aka archlib). The three primary directories with +Hexagon-specific code are + + qemu/target/hexagon + This has all the instruction and packet semantics + qemu/target/hexagon/imported + These files are imported with very little modification from archlib + *.idef Instruction semantics definition + macros.def Mapping of macros to instruction attributes + encode*.def Encoding patterns for each instruction + iclass.def Instruction class definitions used to determine + legal VLIW slots for each instruction + qemu/linux-user/hexagon + Helpers for loading the ELF file and making Linux system calls, + signals, etc + +We start with scripts that generate a bunch of include files. This +is a two step process. The first step is to use the C preprocessor to expand +macros inside the architecture definition files. This is done in +target/hexagon/gen_semantics.c. This step produces + /target/hexagon/semantics_generated.pyinc. +That file is consumed by the following python scripts to produce the indicated +header files in /target/hexagon + gen_opcodes_def.py -> opcodes_def_generated.h.inc + gen_op_regs.py -> op_regs_generated.h.inc + gen_printinsn.py -> printinsn_generated.h.inc + gen_op_attribs.py -> op_attribs_generated.h.inc + gen_helper_protos.py -> helper_protos_generated.h.inc + gen_shortcode.py -> shortcode_generated.h.inc + gen_tcg_funcs.py -> tcg_funcs_generated.c.inc + gen_tcg_func_table.py -> tcg_func_table_generated.c.inc + gen_helper_funcs.py -> helper_funcs_generated.c.inc + +Qemu helper functions have 3 parts + DEF_HELPER declaration indicates the signature of the helper + gen_helper_ will generate a TCG call to the helper function + The helper implementation + +Here's an example of the A2_add instruction. + Instruction tag A2_add + Assembly syntax "Rd32=add(Rs32,Rt32)" + Instruction semantics "{ RdV=RsV+RtV;}" + +By convention, the operands are identified by letter + RdV is the destination register + RsV, RtV are source registers + +The generator uses the operand naming conventions (see large comment in +hex_common.py) to determine the signature of the helper function. Here are the +results for A2_add + +helper_protos_generated.h.inc + DEF_HELPER_3(A2_add, s32, env, s32, s32) + +tcg_funcs_generated.c.inc + static void generate_A2_add( + CPUHexagonState *env, + DisasContext *ctx, + Insn *insn, + Packet *pkt) + { + TCGv RdV = tcg_temp_local_new(); + const int RdN = insn->regno[0]; + TCGv RsV = hex_gpr[insn->regno[1]]; + TCGv RtV = hex_gpr[insn->regno[2]]; + gen_helper_A2_add(RdV, cpu_env, RsV, RtV); + gen_log_reg_write(RdN, RdV); + ctx_log_reg_write(ctx, RdN); + tcg_temp_free(RdV); + } + +helper_funcs_generated.c.inc + int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV) + { + uint32_t slot __attribute__((unused)) = 4; + int32_t RdV = 0; + { RdV=RsV+RtV;} + return RdV; + } + +Note that generate_A2_add updates the disassembly context to be processed +when the packet commits (see "Packet Semantics" below). + +The generator checks for fGEN_TCG_ macro. This allows us to generate +TCG code instead of a call to the helper. If defined, the macro takes 1 +argument. + C semantics (aka short code) + +This allows the code generator to override the auto-generated code. In some +cases this is necessary for correct execution. We can also override for +faster emulation. For example, calling a helper for add is more expensive +than generating a TCG add operation. + +The gen_tcg.h file has any overrides. For example, we could write + #define fGEN_TCG_A2_add(GENHLPR, SHORTCODE) \ + tcg_gen_add_tl(RdV, RsV, RtV) + +The instruction semantics C code relies heavily on macros. In cases where the +C semantics are specified only with macros, we can override the default with +the short semantics option and #define the macros to generate TCG code. One +example is L2_loadw_locked: + Instruction tag L2_loadw_locked + Assembly syntax "Rd32=memw_locked(Rs32)" + Instruction semantics "{ fEA_REG(RsV); fLOAD_LOCKED(1,4,u,EA,RdV) }" + +In gen_tcg.h, we use the shortcode +#define fGEN_TCG_L2_loadw_locked(SHORTCODE) \ + SHORTCODE + +There are also cases where we brute force the TCG code generation. +Instructions with multiple definitions are examples. These require special +handling because qemu helpers can only return a single value. + +In addition to instruction semantics, we use a generator to create the decode +tree. This generation is also a two step process. The first step is to run +target/hexagon/gen_dectree_import.c to produce + /target/hexagon/iset.py +This file is imported by target/hexagon/dectree.py to produce + /target/hexagon/dectree_generated.h.inc + +*** Key Files *** + +cpu.h + +This file contains the definition of the CPUHexagonState struct. It is the +runtime information for each thread and contains stuff like the GPR and +predicate registers. + +macros.h + +The Hexagon arch lib relies heavily on macros for the instruction semantics. +This is a great advantage for qemu because we can override them for different +purposes. You will also notice there are sometimes two definitions of a macro. +The QEMU_GENERATE variable determines whether we want the macro to generate TCG +code. If QEMU_GENERATE is not defined, we want the macro to generate vanilla +C code that will work in the helper implementation. + +translate.c + +The functions in this file generate TCG code for a translation block. Some +important functions in this file are + + gen_start_packet - initialize the data structures for packet semantics + gen_commit_packet - commit the register writes, stores, etc for a packet + decode_and_translate_packet - disassemble a packet and generate code + +genptr.c +gen_tcg.h + +These files create a function for each instruction. It is mostly composed of +fGEN_TCG_ definitions followed by including tcg_funcs_generated.c.inc. + +op_helper.c + +This file contains the implementations of all the helpers. There are a few +general purpose helpers, but most of them are generated by including +helper_funcs_generated.c.inc. There are also several helpers used for debugging. + + +*** Packet Semantics *** + +VLIW packet semantics differ from serial semantics in that all input operands +are read, then the operations are performed, then all the results are written. +For exmaple, this packet performs a swap of registers r0 and r1 + { r0 = r1; r1 = r0 } +Note that the result is different if the instructions are executed serially. + +Packet semantics dictate that we defer any changes of state until the entire +packet is committed. We record the results of each instruction in a side data +structure, and update the visible processor state when we commit the packet. + +The data structures are divided between the runtime state and the translation +context. + +During the TCG generation (see translate.[ch]), we use the DisasContext to +track what needs to be done during packet commit. Here are the relevant +fields + + reg_log list of registers written + reg_log_idx index into ctx_reg_log + pred_log list of predicates written + pred_log_idx index into ctx_pred_log + store_width width of stores (indexed by slot) + +During runtime, the following fields in CPUHexagonState (see cpu.h) are used + + new_value new value of a given register + reg_written boolean indicating if register was written + new_pred_value new value of a predicate register + pred_written boolean indicating if predicate was written + mem_log_stores record of the stores (indexed by slot) + +*** Debugging *** + +You can turn on a lot of debugging by changing the HEX_DEBUG macro to 1 in +internal.h. This will stream a lot of information as it generates TCG and +executes the code. + +To track down nasty issues with Hexagon->TCG generation, we compare the +execution results with actual hardware running on a Hexagon Linux target. +Run qemu with the "-d cpu" option. Then, we can diff the results and figure +out where qemu and hardware behave differently. + +The stacks are located at different locations. We handle this by changing +env->stack_adjust in translate.c. First, set this to zero and run qemu. +Then, change env->stack_adjust to the difference between the two stack +locations. Then rebuild qemu and run again. That will produce a very +clean diff. + +Here are some handy places to set breakpoints + + At the call to gen_start_packet for a given PC (note that the line number + might change in the future) + br translate.c:602 if ctx->base.pc_next == 0xdeadbeef + The helper function for each instruction is named helper_, so here's + an example that will set a breakpoint at the start + br helper_A2_add + If you have the HEX_DEBUG macro set, the following will be useful + At the start of execution of a packet for a given PC + br helper_debug_start_packet if env->gpr[41] == 0xdeadbeef + At the end of execution of a packet for a given PC + br helper_debug_commit_end if env->this_PC == 0xdeadbeef From patchwork Wed Feb 17 23:39:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383931 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3217680jao; Wed, 17 Feb 2021 15:40:56 -0800 (PST) X-Google-Smtp-Source: ABdhPJxrRwSq/LfY6aoVl7sJ3SZZSDfIiaWOo5niwxiX//Kwm2aVYrqi/ZBNQxhOXZCrCalN0G/n X-Received: by 2002:a25:d012:: with SMTP id h18mr2705466ybg.329.1613605256001; Wed, 17 Feb 2021 15:40:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605255; cv=none; d=google.com; s=arc-20160816; b=Jy/64hrAFd6DwUh6SA9b0YPNGw++cSQJfYIltCYdesp9+X+S2qRRG/pyxgXqWkhnbo TloY4t0e0Ldg9/n2XgLNmUwMD1S/Eqa3g1cBrDdjoC9Tbzofg8tR4C9uoJH9SsRqcsz5 NiaSOUlQ56eEV5zq0RID3yv5FmqcvRlWzgRoCa+7SPyQjZSkIPpDq7FPcbWyZHlJ3+Tw lnlnXJu8EZlieE1PREzRTEz64UvXdYIMHk8BjfdvxGB88x/cTyL/joavrhIQUBLwf4fx IASnZHgTJvmbiuaPBmOB+ubnjhq09k1Vf1x4F+/JBCPh9P4Hv25vWqSjoidFE6tT18yx zn4A== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=8XLEYfrw+e5ZQ107eIkxpz9hmRgx7WUPnLtGSCd3eE8=; b=1Gb//ScwioVCWkT0Xzrkkl9LH3mpcxXT1Vkyny5gR4l6d0qlDMbbFUMn6GTC9cIbEv A/PhwjjrVROZya88IQHpdNX0uftyVvqATaMun6LvJpLQaL6B5UH1MPJfGXpIyQsxsV/6 Sg4aTiZO39S2rBmWEycgp6wb81fiShCsRHDc+oChe/cLCxjV2gxJsKWKs0DdfwhnP4dv XLkj5JfBAZmvM3xqkw15S1PPM92Cx/aAFhUL7jpH2Gi0pllNNLK8D2DweutZLqP0X69U i2ZpyoXQZVsLGLrMKtZr9wEw+2j1l45lAjQbX7cGqTJIRRCMkX5K/mIIl+PwIVVjd5pk dcIg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WUwtrjqV; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 76si3679321ybn.492.2021.02.17.15.40.55 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:40:55 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WUwtrjqV; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:34104 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWRD-0007r0-Gt for patch@linaro.org; Wed, 17 Feb 2021 18:40:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50548) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWQy-0007k7-Td for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:40 -0500 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]:40739) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWQx-0004aN-Df for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:40 -0500 Received: by mail-pf1-x429.google.com with SMTP id u143so29138pfc.7 for ; Wed, 17 Feb 2021 15:40:39 -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 :mime-version:content-transfer-encoding; bh=8XLEYfrw+e5ZQ107eIkxpz9hmRgx7WUPnLtGSCd3eE8=; b=WUwtrjqV4AVoUfw7POgGDP1UdCWp438bcwzRoEF+1o102AW6ckTMpDu/v+2ddU/vgq 370ZVwyr42zHpimfm4oHXLj9P5pHb+eVTNLp8zuHIZHb3FOVdXB7Joz5kdZLBpF8JB14 q+F4iVlgho8lgsAoNsXM5AFusYyq3BxLKjgThTTZC+/LPmyGFLbd+HaRTmc34PCOcyDj 4IB8BuxpIwJ/CBQPd0xsbAvNhk9RjroWh2ipGxb9MOgBpS2JRc2yEog8bEDfDojBlWoJ 22YEs0krVBVZ7zEdXmgCPQOV7E9cETk0CMzLlGgyc15zyKmruh0Zy1IjZe8ZnMrGUE2N jSwg== 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:mime-version:content-transfer-encoding; bh=8XLEYfrw+e5ZQ107eIkxpz9hmRgx7WUPnLtGSCd3eE8=; b=sH7ogV/Ppu5+UUC5XrxlH5o3wb/X281XGIX8ETxMGOFtBJ+e7obtABljjHjJBCP/Ht 99HPllgsiYHwtTKgybqF3RRerstovCFCP+mxo24TbR7mzSN7Xgc84X6HEWc8ivYsixT2 eZNFqWyZ8mNGJvJHW6xQDYWAZCm020GZPgz67G+IGzt94KMMDKKZc218PIiIh1lHOx24 vnekt+rI1b8A6MaV1cWP90vzuM/rB44FIWgT41dUk1Vc9wstiA02i7FCNcOXRc2dw+WF sen1GouAzZPOSs/nmE3BAsNUgCXlEaRvUoA2Aejf82FMK52Gp/C5WGG2WjVKe0xC7Wl+ jm9A== X-Gm-Message-State: AOAM533tg4NbSVAlJ7Rv1BCZZtSwZYzkQpDrILSVEzT53EEW/56kd3Tq 8z4qgtPEdXSvtBJRsveGShiolrU1HsEobA== X-Received: by 2002:a62:8453:0:b029:1e4:3a6a:d5ba with SMTP id k80-20020a6284530000b02901e43a6ad5bamr1563184pfd.54.1613605236665; Wed, 17 Feb 2021 15:40:36 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:35 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 04/35] Hexagon (include/elf.h) ELF machine definition Date: Wed, 17 Feb 2021 15:39:52 -0800 Message-Id: <20210217234023.1742406-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::429; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x429.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Define EM_HEXAGON 164 Signed-off-by: Taylor Simpson Tested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-4-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- include/elf.h | 1 + 1 file changed, 1 insertion(+) -- 2.25.1 diff --git a/include/elf.h b/include/elf.h index 7a418ee559..f4fa3c1cd4 100644 --- a/include/elf.h +++ b/include/elf.h @@ -176,6 +176,7 @@ typedef struct mips_elf_abiflags_v0 { #define EM_UNICORE32 110 /* UniCore32 */ +#define EM_HEXAGON 164 /* Qualcomm Hexagon */ #define EM_RX 173 /* Renesas RX family */ #define EM_RISCV 243 /* RISC-V */ From patchwork Wed Feb 17 23:39:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383932 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3218509jao; Wed, 17 Feb 2021 15:42:49 -0800 (PST) X-Google-Smtp-Source: ABdhPJyNNfuy1OSCh4rDx+7DTtbwHIHstYJNq7CX28baOA9QIwrsH9U0aw9uqwwgKdN+fc1W90AI X-Received: by 2002:a25:d091:: with SMTP id h139mr2601350ybg.437.1613605369026; Wed, 17 Feb 2021 15:42:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605369; cv=none; d=google.com; s=arc-20160816; b=IjKN+gX6l59ZV5LTOXHGP1LTLCezEEwljPgx5kfJ4MA6sbkaWbTemAP3bo1rTtvRCm ZSBJLqNdcxbRHw9en2yxuQLvuJBc7c4LvJpoyUThQhU217XaA6YnUPOhY6qPnHckGh9O b5rQ2G59m63wmWT1pxAf68jZx+82FdT0MZUIsh86cSkc8cgjr770gSNZkrgRUyz+EVRw v0QMnghuZe7lUSBd0OzPW7pEqWc1Rn+SKqfqkUQ1EAf4KdcDpetCbVRAAWTb5hfh+zRh xVwiRzq33upZM7WkeInhYpB42JSWevirQYsj5keOZ2uzMMF6jzi+fnKpnWEdBMZU7Vn/ S+dw== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=YFj2KkWo9Er/KLQUoi97QKZIncodD09gY47kBHWa6Ko=; b=zQbQUYOvepuRub+AeXiVBU90VjB4L7aFnEJnRY96SGKXmCA8j+VILXhnbWobdd8lTz vcKFXLSgmbATO8piV057vXGv2Hg4BW269wpJmVK3AB0N/j9gbjs18ahViVL33tggsIyX Da3nWhSlyWj1P2HJyUCoTKf9blSh5TOPmw+xOjdJHVt3I15kleHeF/s2tzpxF5xfDpZ+ 60ZrN47LbvlU3rKs3kjMo01eXpsHVMFsEcYm88WnNXlsjhv2i0DCWmzw6fP0IhqbSsUM nnZrtwbs73DWDdhPJQUl4HAe7JwFRLT57Gu1vx6eKv3jCL5DaP0j1wCbJCRg/Y3q6eCt B0sA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="EIrJW/ay"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id a3si3491684ybe.436.2021.02.17.15.42.48 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:42:49 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="EIrJW/ay"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:41936 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWT2-0002iw-Cs for patch@linaro.org; Wed, 17 Feb 2021 18:42:48 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50558) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWR1-0007pi-3G for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:43 -0500 Received: from mail-pf1-x42c.google.com ([2607:f8b0:4864:20::42c]:41357) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWQx-0004aT-Vw for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:42 -0500 Received: by mail-pf1-x42c.google.com with SMTP id q20so25822pfu.8 for ; Wed, 17 Feb 2021 15:40:39 -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 :mime-version:content-transfer-encoding; bh=YFj2KkWo9Er/KLQUoi97QKZIncodD09gY47kBHWa6Ko=; b=EIrJW/ayJCj5iW9SLQS1c4vKgO0KdSgOMVH3oaYPxTsxD2VfPGwyiw6bLT9FBnziHq 1ullETinsSPYo+7aEFXjfYso4BPGw2r6AKuxo01NI+SCIWEEyVmtFHTfDXILQ/snPti4 UT9QLf39wJw4vtF7Y+ZaSA4U2Su8Kfzq1cE9I/MLwMV1BjQ88uhH/6PbZfHhsKzqP4Vm 1RyDIWBqb5zmuJQi+sLpJa/6reJTygtVMj9XS5pMZc2vYpyREYmUg1VYtaPONqY9WUpS hCnDvD+dz89Hl0SE3SSjfXTNJZV0nrRLbigHfUN+k9pKbBu/sc4QVqtSC+15rChwTCfw 4nlQ== 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:mime-version:content-transfer-encoding; bh=YFj2KkWo9Er/KLQUoi97QKZIncodD09gY47kBHWa6Ko=; b=k8byRBn0X/syymIwpq1hUlg++wohE/4Jp8bDKjsQtdmukhvBmZN7OAtRAVTRWxQzMo S1eaQoQ2+9VbjBUUzi/aNolJq6h3AgzVS8uPtbsorWt3q59txQD2ABXJRTIw7NDxZDkP Tf/2QMbHt41nn860z1t6fcgQoHeaE9VnGdr2SnIGp6vHW+kmvnQNhg6HDtTVFo5kTwhd zXzS/b6UYuQvruVEi5mnGVrPoYpM7qJLPmq3ZJYjC56/uN35t9mRVvzSEbA0J0HomS9G 7UV26y1Tg/laI3J9yxo3CDcTllSe55PqfzngOiJADL6+TYVpt6AI8jhwXnwcpbJUyJ4O elEw== X-Gm-Message-State: AOAM532Mf45rMoP0uJnQMYbdDWOtt5CtQsdEcJZRnC3+FsZvPmfLi2vX g2oXhPZVG6VzpoSOF9cMR439JONwuWUnsw== X-Received: by 2002:aa7:991c:0:b029:1e8:b29:cd69 with SMTP id z28-20020aa7991c0000b02901e80b29cd69mr1616617pff.50.1613605238484; Wed, 17 Feb 2021 15:40:38 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:37 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 05/35] Hexagon (target/hexagon) scalar core definition Date: Wed, 17 Feb 2021 15:39:53 -0800 Message-Id: <20210217234023.1742406-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42c; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Add target state header, target definitions and initialization routines Signed-off-by: Taylor Simpson Message-Id: <1612763186-18161-5-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/cpu-param.h | 29 ++++ target/hexagon/cpu.h | 159 +++++++++++++++++++ target/hexagon/cpu_bits.h | 58 +++++++ target/hexagon/internal.h | 35 ++++ target/hexagon/cpu.c | 318 +++++++++++++++++++++++++++++++++++++ 5 files changed, 599 insertions(+) create mode 100644 target/hexagon/cpu-param.h create mode 100644 target/hexagon/cpu.h create mode 100644 target/hexagon/cpu_bits.h create mode 100644 target/hexagon/internal.h create mode 100644 target/hexagon/cpu.c -- 2.25.1 diff --git a/target/hexagon/cpu-param.h b/target/hexagon/cpu-param.h new file mode 100644 index 0000000000..e8ed5468d9 --- /dev/null +++ b/target/hexagon/cpu-param.h @@ -0,0 +1,29 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_CPU_PARAM_H +#define HEXAGON_CPU_PARAM_H + +#define TARGET_PAGE_BITS 16 /* 64K pages */ +#define TARGET_LONG_BITS 32 + +#define TARGET_PHYS_ADDR_SPACE_BITS 36 +#define TARGET_VIRT_ADDR_SPACE_BITS 32 + +#define NB_MMU_MODES 1 + +#endif diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h new file mode 100644 index 0000000000..e04eac591c --- /dev/null +++ b/target/hexagon/cpu.h @@ -0,0 +1,159 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_CPU_H +#define HEXAGON_CPU_H + +/* Forward declaration needed by some of the header files */ +typedef struct CPUHexagonState CPUHexagonState; + +#include "fpu/softfloat-types.h" + +#include "qemu-common.h" +#include "exec/cpu-defs.h" +#include "hex_regs.h" + +#define NUM_PREGS 4 +#define TOTAL_PER_THREAD_REGS 64 + +#define SLOTS_MAX 4 +#define STORES_MAX 2 +#define REG_WRITES_MAX 32 +#define PRED_WRITES_MAX 5 /* 4 insns + endloop */ + +#define TYPE_HEXAGON_CPU "hexagon-cpu" + +#define HEXAGON_CPU_TYPE_SUFFIX "-" TYPE_HEXAGON_CPU +#define HEXAGON_CPU_TYPE_NAME(name) (name HEXAGON_CPU_TYPE_SUFFIX) +#define CPU_RESOLVING_TYPE TYPE_HEXAGON_CPU + +#define TYPE_HEXAGON_CPU_V67 HEXAGON_CPU_TYPE_NAME("v67") + +#define MMU_USER_IDX 0 + +typedef struct { + target_ulong va; + uint8_t width; + uint32_t data32; + uint64_t data64; +} MemLog; + +#define EXEC_STATUS_OK 0x0000 +#define EXEC_STATUS_STOP 0x0002 +#define EXEC_STATUS_REPLAY 0x0010 +#define EXEC_STATUS_LOCKED 0x0020 +#define EXEC_STATUS_EXCEPTION 0x0100 + + +#define EXCEPTION_DETECTED (env->status & EXEC_STATUS_EXCEPTION) +#define REPLAY_DETECTED (env->status & EXEC_STATUS_REPLAY) +#define CLEAR_EXCEPTION (env->status &= (~EXEC_STATUS_EXCEPTION)) +#define SET_EXCEPTION (env->status |= EXEC_STATUS_EXCEPTION) + +struct CPUHexagonState { + target_ulong gpr[TOTAL_PER_THREAD_REGS]; + target_ulong pred[NUM_PREGS]; + target_ulong branch_taken; + target_ulong next_PC; + + /* For comparing with LLDB on target - see adjust_stack_ptrs function */ + target_ulong last_pc_dumped; + target_ulong stack_start; + + uint8_t slot_cancelled; + target_ulong new_value[TOTAL_PER_THREAD_REGS]; + + /* + * Only used when HEX_DEBUG is on, but unconditionally included + * to reduce recompile time when turning HEX_DEBUG on/off. + */ + target_ulong this_PC; + target_ulong reg_written[TOTAL_PER_THREAD_REGS]; + + target_ulong new_pred_value[NUM_PREGS]; + target_ulong pred_written; + + MemLog mem_log_stores[STORES_MAX]; + target_ulong pkt_has_store_s1; + target_ulong dczero_addr; + + float_status fp_status; + + target_ulong llsc_addr; + target_ulong llsc_val; + uint64_t llsc_val_i64; + + target_ulong is_gather_store_insn; + target_ulong gather_issued; +}; + +#define HEXAGON_CPU_CLASS(klass) \ + OBJECT_CLASS_CHECK(HexagonCPUClass, (klass), TYPE_HEXAGON_CPU) +#define HEXAGON_CPU(obj) \ + OBJECT_CHECK(HexagonCPU, (obj), TYPE_HEXAGON_CPU) +#define HEXAGON_CPU_GET_CLASS(obj) \ + OBJECT_GET_CLASS(HexagonCPUClass, (obj), TYPE_HEXAGON_CPU) + +typedef struct HexagonCPUClass { + /*< private >*/ + CPUClass parent_class; + /*< public >*/ + DeviceRealize parent_realize; + DeviceReset parent_reset; +} HexagonCPUClass; + +typedef struct HexagonCPU { + /*< private >*/ + CPUState parent_obj; + /*< public >*/ + CPUNegativeOffsetState neg; + CPUHexagonState env; + + bool lldb_compat; + target_ulong lldb_stack_adjust; +} HexagonCPU; + +static inline HexagonCPU *hexagon_env_get_cpu(CPUHexagonState *env) +{ + return container_of(env, HexagonCPU, env); +} + +#include "cpu_bits.h" + +#define cpu_signal_handler cpu_hexagon_signal_handler +int cpu_hexagon_signal_handler(int host_signum, void *pinfo, void *puc); + +static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, target_ulong *pc, + target_ulong *cs_base, uint32_t *flags) +{ + *pc = env->gpr[HEX_REG_PC]; + *cs_base = 0; +#ifdef CONFIG_USER_ONLY + *flags = 0; +#else +#error System mode not supported on Hexagon yet +#endif +} + +typedef struct CPUHexagonState CPUArchState; +typedef HexagonCPU ArchCPU; + +void hexagon_translate_init(void); + +#include "exec/cpu-all.h" + +#endif /* HEXAGON_CPU_H */ diff --git a/target/hexagon/cpu_bits.h b/target/hexagon/cpu_bits.h new file mode 100644 index 0000000000..96af834d0e --- /dev/null +++ b/target/hexagon/cpu_bits.h @@ -0,0 +1,58 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_CPU_BITS_H +#define HEXAGON_CPU_BITS_H + +#include "qemu/bitops.h" + +#define HEX_EXCP_FETCH_NO_UPAGE 0x012 +#define HEX_EXCP_INVALID_PACKET 0x015 +#define HEX_EXCP_INVALID_OPCODE 0x015 +#define HEX_EXCP_PRIV_NO_UREAD 0x024 +#define HEX_EXCP_PRIV_NO_UWRITE 0x025 + +#define HEX_EXCP_TRAP0 0x172 + +#define PACKET_WORDS_MAX 4 + +static inline uint32_t parse_bits(uint32_t encoding) +{ + /* The parse bits are [15:14] */ + return extract32(encoding, 14, 2); +} + +static inline uint32_t iclass_bits(uint32_t encoding) +{ + /* The instruction class is encoded in bits [31:28] */ + uint32_t iclass = extract32(encoding, 28, 4); + /* If parse bits are zero, this is a duplex */ + if (parse_bits(encoding) == 0) { + iclass += 16; + } + return iclass; +} + +static inline int is_packet_end(uint32_t endocing) +{ + uint32_t bits = parse_bits(endocing); + return ((bits == 0x3) || (bits == 0x0)); +} + +int disassemble_hexagon(uint32_t *words, int nwords, bfd_vma pc, GString *buf); + +#endif diff --git a/target/hexagon/internal.h b/target/hexagon/internal.h new file mode 100644 index 0000000000..c839796cd1 --- /dev/null +++ b/target/hexagon/internal.h @@ -0,0 +1,35 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_INTERNAL_H +#define HEXAGON_INTERNAL_H + +/* + * Change HEX_DEBUG to 1 to turn on debugging output + */ +#define HEX_DEBUG 0 +#if HEX_DEBUG +#define HEX_DEBUG_LOG(...) qemu_log(__VA_ARGS__) +#else +#define HEX_DEBUG_LOG(...) do { } while (0) +#endif + +void hexagon_debug(CPUHexagonState *env); + +extern const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS]; + +#endif diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c new file mode 100644 index 0000000000..b0b3040dd1 --- /dev/null +++ b/target/hexagon/cpu.c @@ -0,0 +1,318 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qemu/qemu-print.h" +#include "cpu.h" +#include "internal.h" +#include "exec/exec-all.h" +#include "qapi/error.h" +#include "hw/qdev-properties.h" + +static void hexagon_v67_cpu_init(Object *obj) +{ +} + +static ObjectClass *hexagon_cpu_class_by_name(const char *cpu_model) +{ + ObjectClass *oc; + char *typename; + char **cpuname; + + cpuname = g_strsplit(cpu_model, ",", 1); + typename = g_strdup_printf(HEXAGON_CPU_TYPE_NAME("%s"), cpuname[0]); + oc = object_class_by_name(typename); + g_strfreev(cpuname); + g_free(typename); + if (!oc || !object_class_dynamic_cast(oc, TYPE_HEXAGON_CPU) || + object_class_is_abstract(oc)) { + return NULL; + } + return oc; +} + +static Property hexagon_lldb_compat_property = + DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false); +static Property hexagon_lldb_stack_adjust_property = + DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU, lldb_stack_adjust, + 0, qdev_prop_uint32, target_ulong); + +const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + "sa0", "lc0", "sa1", "lc1", "p3_0", "c5", "m0", "m1", + "usr", "pc", "ugp", "gp", "cs0", "cs1", "c14", "c15", + "c16", "c17", "c18", "c19", "pkt_cnt", "insn_cnt", "c22", "c23", + "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31", +}; + +/* + * One of the main debugging techniques is to use "-d cpu" and compare against + * LLDB output when single stepping. However, the target and qemu put the + * stacks at different locations. This is used to compensate so the diff is + * cleaner. + */ +static inline target_ulong adjust_stack_ptrs(CPUHexagonState *env, + target_ulong addr) +{ + HexagonCPU *cpu = container_of(env, HexagonCPU, env); + target_ulong stack_adjust = cpu->lldb_stack_adjust; + target_ulong stack_start = env->stack_start; + target_ulong stack_size = 0x10000; + + if (stack_adjust == 0) { + return addr; + } + + if (stack_start + 0x1000 >= addr && addr >= (stack_start - stack_size)) { + return addr - stack_adjust; + } + return addr; +} + +/* HEX_REG_P3_0 (aka C4) is an alias for the predicate registers */ +static inline target_ulong read_p3_0(CPUHexagonState *env) +{ + int32_t control_reg = 0; + int i; + for (i = NUM_PREGS - 1; i >= 0; i--) { + control_reg <<= 8; + control_reg |= env->pred[i] & 0xff; + } + return control_reg; +} + +static void print_reg(FILE *f, CPUHexagonState *env, int regnum) +{ + target_ulong value; + + if (regnum == HEX_REG_P3_0) { + value = read_p3_0(env); + } else { + value = regnum < 32 ? adjust_stack_ptrs(env, env->gpr[regnum]) + : env->gpr[regnum]; + } + + qemu_fprintf(f, " %s = 0x" TARGET_FMT_lx "\n", + hexagon_regnames[regnum], value); +} + +static void hexagon_dump(CPUHexagonState *env, FILE *f) +{ + HexagonCPU *cpu = container_of(env, HexagonCPU, env); + + if (cpu->lldb_compat) { + /* + * When comparing with LLDB, it doesn't step through single-cycle + * hardware loops the same way. So, we just skip them here + */ + if (env->gpr[HEX_REG_PC] == env->last_pc_dumped) { + return; + } + env->last_pc_dumped = env->gpr[HEX_REG_PC]; + } + + qemu_fprintf(f, "General Purpose Registers = {\n"); + for (int i = 0; i < 32; i++) { + print_reg(f, env, i); + } + print_reg(f, env, HEX_REG_SA0); + print_reg(f, env, HEX_REG_LC0); + print_reg(f, env, HEX_REG_SA1); + print_reg(f, env, HEX_REG_LC1); + print_reg(f, env, HEX_REG_M0); + print_reg(f, env, HEX_REG_M1); + print_reg(f, env, HEX_REG_USR); + print_reg(f, env, HEX_REG_P3_0); + print_reg(f, env, HEX_REG_GP); + print_reg(f, env, HEX_REG_UGP); + print_reg(f, env, HEX_REG_PC); +#ifdef CONFIG_USER_ONLY + /* + * Not modelled in user mode, print junk to minimize the diff's + * with LLDB output + */ + qemu_fprintf(f, " cause = 0x000000db\n"); + qemu_fprintf(f, " badva = 0x00000000\n"); + qemu_fprintf(f, " cs0 = 0x00000000\n"); + qemu_fprintf(f, " cs1 = 0x00000000\n"); +#else + print_reg(f, env, HEX_REG_CAUSE); + print_reg(f, env, HEX_REG_BADVA); + print_reg(f, env, HEX_REG_CS0); + print_reg(f, env, HEX_REG_CS1); +#endif + qemu_fprintf(f, "}\n"); +} + +static void hexagon_dump_state(CPUState *cs, FILE *f, int flags) +{ + HexagonCPU *cpu = HEXAGON_CPU(cs); + CPUHexagonState *env = &cpu->env; + + hexagon_dump(env, f); +} + +void hexagon_debug(CPUHexagonState *env) +{ + hexagon_dump(env, stdout); +} + +static void hexagon_cpu_set_pc(CPUState *cs, vaddr value) +{ + HexagonCPU *cpu = HEXAGON_CPU(cs); + CPUHexagonState *env = &cpu->env; + env->gpr[HEX_REG_PC] = value; +} + +static void hexagon_cpu_synchronize_from_tb(CPUState *cs, + const TranslationBlock *tb) +{ + HexagonCPU *cpu = HEXAGON_CPU(cs); + CPUHexagonState *env = &cpu->env; + env->gpr[HEX_REG_PC] = tb->pc; +} + +static bool hexagon_cpu_has_work(CPUState *cs) +{ + return true; +} + +void restore_state_to_opc(CPUHexagonState *env, TranslationBlock *tb, + target_ulong *data) +{ + env->gpr[HEX_REG_PC] = data[0]; +} + +static void hexagon_cpu_reset(DeviceState *dev) +{ + CPUState *cs = CPU(dev); + HexagonCPU *cpu = HEXAGON_CPU(cs); + HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(cpu); + + mcc->parent_reset(dev); +} + +static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info) +{ + info->print_insn = print_insn_hexagon; +} + +static void hexagon_cpu_realize(DeviceState *dev, Error **errp) +{ + CPUState *cs = CPU(dev); + HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(dev); + Error *local_err = NULL; + + cpu_exec_realizefn(cs, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); + return; + } + + qemu_init_vcpu(cs); + cpu_reset(cs); + + mcc->parent_realize(dev, errp); +} + +static void hexagon_cpu_init(Object *obj) +{ + HexagonCPU *cpu = HEXAGON_CPU(obj); + + cpu_set_cpustate_pointers(cpu); + qdev_property_add_static(DEVICE(obj), &hexagon_lldb_compat_property); + qdev_property_add_static(DEVICE(obj), &hexagon_lldb_stack_adjust_property); +} + +static bool hexagon_tlb_fill(CPUState *cs, vaddr address, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr) +{ +#ifdef CONFIG_USER_ONLY + switch (access_type) { + case MMU_INST_FETCH: + cs->exception_index = HEX_EXCP_FETCH_NO_UPAGE; + break; + case MMU_DATA_LOAD: + cs->exception_index = HEX_EXCP_PRIV_NO_UREAD; + break; + case MMU_DATA_STORE: + cs->exception_index = HEX_EXCP_PRIV_NO_UWRITE; + break; + } + cpu_loop_exit_restore(cs, retaddr); +#else +#error System mode not implemented for Hexagon +#endif +} + +#include "hw/core/tcg-cpu-ops.h" + +static struct TCGCPUOps hexagon_tcg_ops = { + .initialize = hexagon_translate_init, + .synchronize_from_tb = hexagon_cpu_synchronize_from_tb, + .tlb_fill = hexagon_tlb_fill, +}; + +static void hexagon_cpu_class_init(ObjectClass *c, void *data) +{ + HexagonCPUClass *mcc = HEXAGON_CPU_CLASS(c); + CPUClass *cc = CPU_CLASS(c); + DeviceClass *dc = DEVICE_CLASS(c); + + device_class_set_parent_realize(dc, hexagon_cpu_realize, + &mcc->parent_realize); + + device_class_set_parent_reset(dc, hexagon_cpu_reset, &mcc->parent_reset); + + cc->class_by_name = hexagon_cpu_class_by_name; + cc->has_work = hexagon_cpu_has_work; + cc->dump_state = hexagon_dump_state; + cc->set_pc = hexagon_cpu_set_pc; + cc->gdb_read_register = hexagon_gdb_read_register; + cc->gdb_write_register = hexagon_gdb_write_register; + cc->gdb_num_core_regs = TOTAL_PER_THREAD_REGS; + cc->gdb_stop_before_watchpoint = true; + cc->disas_set_info = hexagon_cpu_disas_set_info; + cc->tcg_ops = &hexagon_tcg_ops; +} + +#define DEFINE_CPU(type_name, initfn) \ + { \ + .name = type_name, \ + .parent = TYPE_HEXAGON_CPU, \ + .instance_init = initfn \ + } + +static const TypeInfo hexagon_cpu_type_infos[] = { + { + .name = TYPE_HEXAGON_CPU, + .parent = TYPE_CPU, + .instance_size = sizeof(HexagonCPU), + .instance_init = hexagon_cpu_init, + .abstract = true, + .class_size = sizeof(HexagonCPUClass), + .class_init = hexagon_cpu_class_init, + }, + DEFINE_CPU(TYPE_HEXAGON_CPU_V67, hexagon_v67_cpu_init), +}; + +DEFINE_TYPES(hexagon_cpu_type_infos) From patchwork Wed Feb 17 23:39:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383934 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3218588jao; Wed, 17 Feb 2021 15:42:59 -0800 (PST) X-Google-Smtp-Source: ABdhPJw2Vr7zyvbXMs/MWmaQotNNraoaieiTdO/PKvURbMf23dKxverammK0+pYh1jhMiPdGz/eK X-Received: by 2002:a25:7d84:: with SMTP id y126mr2718849ybc.179.1613605379742; Wed, 17 Feb 2021 15:42:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605379; cv=none; d=google.com; s=arc-20160816; b=1IQHi1b3BhH9oXYWcl8gr2kqlWhG5ATmDVGeMuPPtEMmysUssY0l+mprQF9RtVb4Ic YyZoAeTxQmoLm56BCC1g46HViAFQvqsw8cnqoLZwO1Xoi7O7wRcuuQfkc+VssYHlUsaY i7yXLdKUMG+0huBqTDBTjOXBNRbmkEOkEQTgypYeG1uh8hscErSs8+cSSv1xKfhwdVwC 0mW+fYQhs3rlxGQ6sYLyofnstI5C2nTQLJWVT32nA9NgZ0wX5EYxxIVcmAwocSSVE9lr 0yHP0Y6mWC1Wpo+sn5FUFLQJrcOKvNsXpAeSekOQ70JSouK8bwHKhZH4g1LarDTmr6LY 9iTA== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=efU7ifq9UHagxlnOIXBK9C1qiS3Jd4xMBPPTZVTIbDY=; b=G7/T+8tmONWiEYMltJC0p1TuwrdD45s1kB7TYxwh72hFhF73ssuOIz/o949G2An7v+ +Tu7KChNXXwDwPrVUmhO+nSndTTG2yAB4YUSEdSEKxcvo5cQLhWJIkl5loyOe2B49ldB cZN0AVycFxPWW5CP7JeJy4FoRFJ1WcDW8QB+V8GH9gwCZMcrXRx/hu5evZoQULqA0eRP Nh4uLbSWCisBmGf6seEpeQRjd3B4EWyXc6RLUWZQw3xDja52Kg3+ARuRSwG2Y609ThrT m7J08Yb7w+ylCkXnS05C1CNR8GxtJlQcglskQXfVe+kEHbAI3JqJ7kLM9SvEoCndZpm+ il0w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gC3TM2ta; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id e3si3488218ybi.121.2021.02.17.15.42.59 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:42:59 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gC3TM2ta; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:42646 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWTD-00031N-5c for patch@linaro.org; Wed, 17 Feb 2021 18:42:59 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50574) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWR4-0007zS-JA for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:46 -0500 Received: from mail-pf1-x430.google.com ([2607:f8b0:4864:20::430]:42141) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWR2-0004bZ-Hq for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:46 -0500 Received: by mail-pf1-x430.google.com with SMTP id w18so23441pfu.9 for ; Wed, 17 Feb 2021 15:40:44 -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 :mime-version:content-transfer-encoding; bh=efU7ifq9UHagxlnOIXBK9C1qiS3Jd4xMBPPTZVTIbDY=; b=gC3TM2taN0e8jDaoxIN53fP4wOhxMGx7BstzVcAv82Ckc+cHsM9trud6XtuDwyCOy8 4u0RrjMGBpR0oPV2pkw7llQBPmD5S2rdTY+l77gxB5wqeB0DyfSBk6ChJ9bKBbqfJKdi Sa7J8Zll5V8nuwmg4iuRt9OWwjR6XufW4gzgTbDLQGTGhybbmuIa4kGynWI4khMxPGel w+VHt0YVsg3VgtXwqyKOLUFQKzhiMz0KLht/H708NJ9Wt15euYZhbGQd3Fi0XBXgqu08 aQ4dqDNIbs7zSjTYOy+U96G+rSfQbwfwWvsf/rkrZN8bdqLbwm3xeKht0p7nxRUzmWEd Aiug== 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:mime-version:content-transfer-encoding; bh=efU7ifq9UHagxlnOIXBK9C1qiS3Jd4xMBPPTZVTIbDY=; b=JC0QA318fvoJngvq22KeVsijosM5ntOpZBbIMq5ubfGNgE28LVsJI0nVlYmu7N7nh4 i/ihLDoRRfsnv3+l4B5mceRrO1k5Eb3GqFvqYkzjkgwuBhKxKzYG42+A91pHcZnBX+kn k1Z928DxjE9n11gprtefgasCcBW2b/zGih2JOS+OqTTzW8vFiGmmUpG40oMfTbGsA6FR fZgTeuOnsjvPe6tJGf2mdPS1W/aETM6hn+qX7EReyRnmIRpPTxS1HznX7ZFhs3Cy2pxx j8Ih92H+FFHPMurx5ZTu8EWQkTCOTg6nys/gvrLwUNOz0YlvE5W1QV9uTVkhX5OXAPwj 2D9g== X-Gm-Message-State: AOAM533/hD8qsqiWG6vk0q/J+Ul0m/JKH0kNJNlHnPx3z+05RmWlK++6 Fo1iKAKS9BsGdf0uW9Fdg0cY56UpptGOFg== X-Received: by 2002:a62:dd48:0:b029:1d5:e29c:621c with SMTP id w69-20020a62dd480000b02901d5e29c621cmr1534670pff.31.1613605240182; Wed, 17 Feb 2021 15:40:40 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:39 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 06/35] Hexagon (disas) disassembler Date: Wed, 17 Feb 2021 15:39:54 -0800 Message-Id: <20210217234023.1742406-7-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::430; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Add hexagon to disas/meson.build Add disas/hexagon.c Add hexagon to include/disas/dis-asm.h Signed-off-by: Taylor Simpson Tested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1612763186-18161-6-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- include/disas/dis-asm.h | 1 + disas/hexagon.c | 65 +++++++++++++++++++++++++++++++++++++++++ disas/meson.build | 1 + 3 files changed, 67 insertions(+) create mode 100644 disas/hexagon.c -- 2.25.1 diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h index d1133a4e04..13fa1edd41 100644 --- a/include/disas/dis-asm.h +++ b/include/disas/dis-asm.h @@ -459,6 +459,7 @@ int print_insn_xtensa (bfd_vma, disassemble_info*); int print_insn_riscv32 (bfd_vma, disassemble_info*); int print_insn_riscv64 (bfd_vma, disassemble_info*); int print_insn_rx(bfd_vma, disassemble_info *); +int print_insn_hexagon(bfd_vma, disassemble_info *); #ifdef CONFIG_CAPSTONE bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size); diff --git a/disas/hexagon.c b/disas/hexagon.c new file mode 100644 index 0000000000..3c24e2a94a --- /dev/null +++ b/disas/hexagon.c @@ -0,0 +1,65 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * QEMU Hexagon Disassembler + */ + +#include "qemu/osdep.h" +#include "disas/dis-asm.h" +#include "target/hexagon/cpu_bits.h" + +/* + * We will disassemble a packet with up to 4 instructions, so we need + * a hefty size buffer. + */ +#define PACKET_BUFFER_LEN 1028 + +int print_insn_hexagon(bfd_vma memaddr, struct disassemble_info *info) +{ + uint32_t words[PACKET_WORDS_MAX]; + bool found_end = false; + GString *buf = g_string_sized_new(PACKET_BUFFER_LEN); + int i, len; + + for (i = 0; i < PACKET_WORDS_MAX && !found_end; i++) { + int status = (*info->read_memory_func)(memaddr + i * sizeof(uint32_t), + (bfd_byte *)&words[i], + sizeof(uint32_t), info); + if (status) { + if (i > 0) { + break; + } + (*info->memory_error_func)(status, memaddr, info); + return status; + } + if (is_packet_end(words[i])) { + found_end = true; + } + } + + if (!found_end) { + (*info->fprintf_func)(info->stream, ""); + return PACKET_WORDS_MAX * sizeof(uint32_t); + } + + len = disassemble_hexagon(words, i, memaddr, buf); + (*info->fprintf_func)(info->stream, "%s", buf->str); + g_string_free(buf, true); + + return len; +} diff --git a/disas/meson.build b/disas/meson.build index da341a511e..4c8da01877 100644 --- a/disas/meson.build +++ b/disas/meson.build @@ -6,6 +6,7 @@ common_ss.add(when: 'CONFIG_ARM_A64_DIS', if_true: files('arm-a64.cc')) common_ss.add_all(when: 'CONFIG_ARM_A64_DIS', if_true: libvixl_ss) common_ss.add(when: 'CONFIG_ARM_DIS', if_true: files('arm.c')) common_ss.add(when: 'CONFIG_CRIS_DIS', if_true: files('cris.c')) +common_ss.add(when: 'CONFIG_HEXAGON_DIS', if_true: files('hexagon.c')) common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c')) common_ss.add(when: 'CONFIG_I386_DIS', if_true: files('i386.c')) common_ss.add(when: 'CONFIG_LM32_DIS', if_true: files('lm32.c')) From patchwork Wed Feb 17 23:39:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383936 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3220158jao; Wed, 17 Feb 2021 15:46:17 -0800 (PST) X-Google-Smtp-Source: ABdhPJze+Ab4+cXjkqYw3eKBikhAHGs01OgkHbWTtP7kxHR5ps/gxbIsyoiLA8agWWBNudn9ZxK1 X-Received: by 2002:a25:b223:: with SMTP id i35mr2820288ybj.372.1613605577653; Wed, 17 Feb 2021 15:46:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605577; cv=none; d=google.com; s=arc-20160816; b=XywuBXLxekSfr7TmMytuVP3kbZG8GBMUKrXEcOaJkYU5Ku7dnS0rQx5uUTShKoPAYw m9mPFgglS4fRj09pqH8J6pmcSxd5VnVfpOezMyQ1ixEzhzlpGDKXB6qJs5y8pnLM/AqD JFI4X3q/Jy6oRwLZsanZ/KBugRYWUtxd2JkDpefUaP+8dgP/5NIT+Q9DUtgdnJIUVCu4 1mH6UenSvrlQubKLdWEfWMKypTsmzKpvKysMoZ+N477r/FaiaSMb5+D0OzDTTRimgSaR uTI/Ctc2R+1a9WmAkpYADCi7sYimpRD5XxXR8xtkUsuFmWs74GCYQHNPHFfVyz/yzuXX 1gNQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=EINIkezDIaTxIfm6JRFuokpw0tpVlajjKW14u+Tuwr4=; b=i5UlRuXa1HNedNtP4Zs7v9+dJUWxKfKpC3Pvhqfu8yXHYPPkmCQUzlJcZxyOSU79n0 Ykt3M0NSBdgjjIvmCJa3uCt4iD/CP543uM7WwGx4WtxjgRCBn0zG+XS6zpqdaw/Th2PW RKrtQH6Z6fiW/zEPVPO2VfoVB6Xg+KDYC8lVBKGsv6kdhmr3xrlDUG/6kK2yLQd/R/YO rnWVcXB8R6IjZ0V7kPfAfPNrs7eqKdkKn1HFrenfXJYMjfOAhmgGI/ZljgdKYYIAgC7x LmlX0BBe5HxFbKlI5pjfA7e6AtkOqlNH6sA5pGTyF3PE2VG2c1sgCeF5GquG10adimZ0 i47Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UL22G+ua; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 138si3578267ybn.62.2021.02.17.15.46.17 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:46:17 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UL22G+ua; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:50762 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWWP-0006XK-1H for patch@linaro.org; Wed, 17 Feb 2021 18:46:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50606) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWR8-0008AF-Sn for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:50 -0500 Received: from mail-pg1-x536.google.com ([2607:f8b0:4864:20::536]:43521) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWR7-0004cb-1x for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:50 -0500 Received: by mail-pg1-x536.google.com with SMTP id n10so9499995pgl.10 for ; Wed, 17 Feb 2021 15:40:48 -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 :mime-version:content-transfer-encoding; bh=EINIkezDIaTxIfm6JRFuokpw0tpVlajjKW14u+Tuwr4=; b=UL22G+uacbAQZiYrod/7HHWTsT22Ws2mjoKpLd07TptLmWHFkmU4gy7utxmVBLAUnG 7J20Ut/bIYQzVL8GWsAPqqF+haFz9RMewl2N4ehaqmJtKNyr1jgmASit8BFTBCDIwQQC FAoiNv1nAjFLzvOhR1wOmJdqY6fjN/SxKXMuL6rGWz4o8FPF1qh140zFn2pN0TVyZOjj zmxHl6WHV45pUVjjYYBkFwQM4SWpkOvavFQQMXgJobj25wnJlklM158oeMWzGkDaz7Ex /zZJlwFIYI+RCgiuvN7k0IjvQOsKfqO9AoGjC+o8vDXshL/dWE/ucUjZV4pYxTYz6+3X crhQ== 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:mime-version:content-transfer-encoding; bh=EINIkezDIaTxIfm6JRFuokpw0tpVlajjKW14u+Tuwr4=; b=JygTV9ciJa8WyQWFtFUO02XX89kwTwt+FMYY74zLORaDUjHdREY7GgQ2N1R+B9c8g+ kmDNPfGzQgl9qaWzyMr18SovtDzNNcmn2i+o1QWQASPtE9GUcIAjdDg0afG169ZYiE3J Tn5B4siVoEKSiZ9YrP5cAISqZe8zitgjSUF8ASKek/YDF428PKeJf0WLx5JIkoZ4rFbj TZnw8Zk8qLC9Gh6tuXyuNUpORAgwC8GmWcB83ARf3bxlR/+y84oj9vZqynfie9hHAuGQ +oIZsFR0TCjPVJO9i2QJuG6WV6JXykeAtetSZf/gdqEgsTowlVUCgqrLDnn743Pjp0/N 2+zQ== X-Gm-Message-State: AOAM533nrdl7PgEzACNyCp/P9Q/k50W909B0oIZsgKv/JkVdeUpQ1rkY rFVkEvPthMbEqpzkSm50tRyE2Sw4j2VH7g== X-Received: by 2002:a05:6a00:15cc:b029:1ba:5282:3ab8 with SMTP id o12-20020a056a0015ccb02901ba52823ab8mr1515610pfu.77.1613605241572; Wed, 17 Feb 2021 15:40:41 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:41 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 07/35] Hexagon (target/hexagon) register names Date: Wed, 17 Feb 2021 15:39:55 -0800 Message-Id: <20210217234023.1742406-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::536; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x536.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1612763186-18161-7-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/hex_regs.h | 83 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 target/hexagon/hex_regs.h -- 2.25.1 diff --git a/target/hexagon/hex_regs.h b/target/hexagon/hex_regs.h new file mode 100644 index 0000000000..f291911eef --- /dev/null +++ b/target/hexagon/hex_regs.h @@ -0,0 +1,83 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_REGS_H +#define HEXAGON_REGS_H + +enum { + HEX_REG_R00 = 0, + HEX_REG_R01 = 1, + HEX_REG_R02 = 2, + HEX_REG_R03 = 3, + HEX_REG_R04 = 4, + HEX_REG_R05 = 5, + HEX_REG_R06 = 6, + HEX_REG_R07 = 7, + HEX_REG_R08 = 8, + HEX_REG_R09 = 9, + HEX_REG_R10 = 10, + HEX_REG_R11 = 11, + HEX_REG_R12 = 12, + HEX_REG_R13 = 13, + HEX_REG_R14 = 14, + HEX_REG_R15 = 15, + HEX_REG_R16 = 16, + HEX_REG_R17 = 17, + HEX_REG_R18 = 18, + HEX_REG_R19 = 19, + HEX_REG_R20 = 20, + HEX_REG_R21 = 21, + HEX_REG_R22 = 22, + HEX_REG_R23 = 23, + HEX_REG_R24 = 24, + HEX_REG_R25 = 25, + HEX_REG_R26 = 26, + HEX_REG_R27 = 27, + HEX_REG_R28 = 28, + HEX_REG_R29 = 29, + HEX_REG_SP = 29, + HEX_REG_FP = 30, + HEX_REG_R30 = 30, + HEX_REG_LR = 31, + HEX_REG_R31 = 31, + HEX_REG_SA0 = 32, + HEX_REG_LC0 = 33, + HEX_REG_SA1 = 34, + HEX_REG_LC1 = 35, + HEX_REG_P3_0 = 36, + HEX_REG_M0 = 38, + HEX_REG_M1 = 39, + HEX_REG_USR = 40, + HEX_REG_PC = 41, + HEX_REG_UGP = 42, + HEX_REG_GP = 43, + HEX_REG_CS0 = 44, + HEX_REG_CS1 = 45, + HEX_REG_UPCYCLELO = 46, + HEX_REG_UPCYCLEHI = 47, + HEX_REG_FRAMELIMIT = 48, + HEX_REG_FRAMEKEY = 49, + HEX_REG_PKTCNTLO = 50, + HEX_REG_PKTCNTHI = 51, + /* Use reserved control registers for qemu execution counts */ + HEX_REG_QEMU_PKT_CNT = 52, + HEX_REG_QEMU_INSN_CNT = 53, + HEX_REG_UTIMERLO = 62, + HEX_REG_UTIMERHI = 63, +}; + +#endif From patchwork Wed Feb 17 23:39:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383933 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3218512jao; Wed, 17 Feb 2021 15:42:49 -0800 (PST) X-Google-Smtp-Source: ABdhPJxna3X3O8DB5COXqW+p3J8MfVqmItRrCWfCKV2xBPOMy86W4CS6yDWJE7JulfHcwX40Pd1H X-Received: by 2002:a25:da4c:: with SMTP id n73mr2501618ybf.463.1613605369723; Wed, 17 Feb 2021 15:42:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605369; cv=none; d=google.com; s=arc-20160816; b=tZEaVc/1dLPekST7WjBzjj/CUln1HaPWUuqDbXdLuj+MP1f9CJR2cPYDXEk62YeYF5 gbLDnbcnk0OscxuQs3bSgbXbBh+G7YBVyGS7+UAeq+rbm34BUGuBnV3tP6Y0jgO8Vq0+ VXg6YS9Ln9UShwk6o2VoDgOmkuj6YLIwUmYQ/EhysCyu3fF2BOOsgU74eEP9oPb40HH6 GJpY2fTH0PmYqPf5x53b7PnXP7XzX38NJGAZCMp4hrOjQD8rmP/8X1mFBMmHOIkMOmYG fRc2eP4ugBISTJYv9cVn/pvQqjnFI88qSKB9M1Z6Fz12m0wXbcqrX4owvceTke8jUp95 rJrg== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=AJk3e4AfvfpdW4OO2fcNK1rD5VxDoURrTXi+1stUu50=; b=PNmdMgwAl0KYWpxsFHMAwozTk4e/R2t05f2ycak3nP6LTod4/ccMIxywvpzdVwOTdL hCOacv9AnbCOGx6dlQuBE+tY/KaUY9kNruFL1IP7U20jzM0ce9G8fwyZKlTQmohP1vJb Md1I/8S8SRhZV1z61oWmL/c+QqhiJxE27IJpLmlxbUiZv7Fs1T89LJBTm9wBYoy42SC3 PXeTOqP/ihv5hcN5or/MtpL19bhFyrDsowmqszc+eT+Hm79uOK2NppQyX6+EJrClePVE fYX+FZraJKA1EqRoODxlohQbgII9xXogRwR59w7boyvR+qVKzm0SdRFzzjWy3EVXBUP5 ZF1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Uq5UPr2z; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id k16si3590418ybp.314.2021.02.17.15.42.49 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:42:49 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Uq5UPr2z; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:42000 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWT3-0002kY-1k for patch@linaro.org; Wed, 17 Feb 2021 18:42:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50656) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRC-0008JE-VU for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:55 -0500 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]:38296) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWR8-0004cj-9J for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:54 -0500 Received: by mail-pj1-x102b.google.com with SMTP id l18so264684pji.3 for ; Wed, 17 Feb 2021 15:40:49 -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 :mime-version:content-transfer-encoding; bh=AJk3e4AfvfpdW4OO2fcNK1rD5VxDoURrTXi+1stUu50=; b=Uq5UPr2z8yA+goemdmcLDrJD5T0u4TaN4r4pIwIbVPOwHZ5eUO1ogRMhOGVM2OVBYU du8JCC2ENbhk1K5xmzzZ07zgA4GjbBlEzwBuKT22Sz5Enr93wH1E1RdoTOgHhIjrx7tM vpDY/jaMAJCTE6HVbWZe8nBn66Zp5Xsd3I5F+Oc0qOHaxpt/GXgSHTM328CZlviDv4wa HWEjrbKpgPh0AuXpASqopUbLYkxrigpv5DI6BjCGlHalyhW4DJgm/4a/3T1tqUIEGDCb uSH8mwna4oNKnjkfmVmPTX1y0jwWwy06qEhS9cTkZEzpDs2XVxa38twd+mXtjlb/ohRQ a4VQ== 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:mime-version:content-transfer-encoding; bh=AJk3e4AfvfpdW4OO2fcNK1rD5VxDoURrTXi+1stUu50=; b=jaPjCot0vnDV60gnIbZ2IA7TrZdzRVf/QR1ote1JxjIBZ2mZK1P46b+aF7/A4GV1iJ oGRTyHJH7V/s4ORq0PfCof/g7T5RIpAFTV9Fb29ZWzfDBGZCx74KTs142/FR3qUBrS04 QhS55f4oM4WWmJSYtJeIzYfryLo1wdP+n6cCETkGtR0BQzconzFbSO4UJpSMvbwxrZBD p5EQNsk/O77TRJ9EgU7R+yam8LHi/Kz8QODG6LRHTA5Z75rSWlcAUrtr1K29FyTSQDLF wyYHSPlOkpWM5TJnyzlXDrEpMroun5VkKBT5Cyx9Ln4wBuzmWJvXbLEQ+bXxLygCmFYl sLyg== X-Gm-Message-State: AOAM530KeeSguVuFXFJlFrA1ibeoJi4paRoxQaOPVoUi1vma2LFK0dn+ OpHQfcZou06Ru2nbFXCF5QYALAU++tUefQ== X-Received: by 2002:a17:90b:3907:: with SMTP id ob7mr1232957pjb.18.1613605244947; Wed, 17 Feb 2021 15:40:44 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:44 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 08/35] Hexagon (target/hexagon) scalar core helpers Date: Wed, 17 Feb 2021 15:39:56 -0800 Message-Id: <20210217234023.1742406-9-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102b; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson The majority of helpers are generated. Define the helper functions needed then include the generated file Signed-off-by: Taylor Simpson Message-Id: <1612763186-18161-8-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/helper.h | 88 +++ target/hexagon/op_helper.c | 1064 ++++++++++++++++++++++++++++++++++++ 2 files changed, 1152 insertions(+) create mode 100644 target/hexagon/helper.h create mode 100644 target/hexagon/op_helper.c -- 2.25.1 diff --git a/target/hexagon/helper.h b/target/hexagon/helper.h new file mode 100644 index 0000000000..a5f340ce67 --- /dev/null +++ b/target/hexagon/helper.h @@ -0,0 +1,88 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "internal.h" +#include "helper_protos_generated.h.inc" + +DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_RETURN, noreturn, env, i32) +#if HEX_DEBUG +DEF_HELPER_1(debug_start_packet, void, env) +DEF_HELPER_FLAGS_3(debug_check_store_width, TCG_CALL_NO_WG, void, env, int, int) +DEF_HELPER_FLAGS_3(debug_commit_end, TCG_CALL_NO_WG, void, env, int, int) +#endif +DEF_HELPER_2(commit_store, void, env, int) +DEF_HELPER_FLAGS_4(fcircadd, TCG_CALL_NO_RWG_SE, s32, s32, s32, s32, s32) + +/* Floating point */ +DEF_HELPER_2(conv_sf2df, f64, env, f32) +DEF_HELPER_2(conv_df2sf, f32, env, f64) +DEF_HELPER_2(conv_uw2sf, f32, env, s32) +DEF_HELPER_2(conv_uw2df, f64, env, s32) +DEF_HELPER_2(conv_w2sf, f32, env, s32) +DEF_HELPER_2(conv_w2df, f64, env, s32) +DEF_HELPER_2(conv_ud2sf, f32, env, s64) +DEF_HELPER_2(conv_ud2df, f64, env, s64) +DEF_HELPER_2(conv_d2sf, f32, env, s64) +DEF_HELPER_2(conv_d2df, f64, env, s64) +DEF_HELPER_2(conv_sf2uw, s32, env, f32) +DEF_HELPER_2(conv_sf2w, s32, env, f32) +DEF_HELPER_2(conv_sf2ud, s64, env, f32) +DEF_HELPER_2(conv_sf2d, s64, env, f32) +DEF_HELPER_2(conv_df2uw, s32, env, f64) +DEF_HELPER_2(conv_df2w, s32, env, f64) +DEF_HELPER_2(conv_df2ud, s64, env, f64) +DEF_HELPER_2(conv_df2d, s64, env, f64) +DEF_HELPER_2(conv_sf2uw_chop, s32, env, f32) +DEF_HELPER_2(conv_sf2w_chop, s32, env, f32) +DEF_HELPER_2(conv_sf2ud_chop, s64, env, f32) +DEF_HELPER_2(conv_sf2d_chop, s64, env, f32) +DEF_HELPER_2(conv_df2uw_chop, s32, env, f64) +DEF_HELPER_2(conv_df2w_chop, s32, env, f64) +DEF_HELPER_2(conv_df2ud_chop, s64, env, f64) +DEF_HELPER_2(conv_df2d_chop, s64, env, f64) +DEF_HELPER_3(sfadd, f32, env, f32, f32) +DEF_HELPER_3(sfsub, f32, env, f32, f32) +DEF_HELPER_3(sfcmpeq, s32, env, f32, f32) +DEF_HELPER_3(sfcmpgt, s32, env, f32, f32) +DEF_HELPER_3(sfcmpge, s32, env, f32, f32) +DEF_HELPER_3(sfcmpuo, s32, env, f32, f32) +DEF_HELPER_3(sfmax, f32, env, f32, f32) +DEF_HELPER_3(sfmin, f32, env, f32, f32) +DEF_HELPER_3(sfclass, s32, env, f32, s32) +DEF_HELPER_3(sffixupn, f32, env, f32, f32) +DEF_HELPER_3(sffixupd, f32, env, f32, f32) +DEF_HELPER_2(sffixupr, f32, env, f32) + +DEF_HELPER_3(dfadd, f64, env, f64, f64) +DEF_HELPER_3(dfsub, f64, env, f64, f64) +DEF_HELPER_3(dfmax, f64, env, f64, f64) +DEF_HELPER_3(dfmin, f64, env, f64, f64) +DEF_HELPER_3(dfcmpeq, s32, env, f64, f64) +DEF_HELPER_3(dfcmpgt, s32, env, f64, f64) +DEF_HELPER_3(dfcmpge, s32, env, f64, f64) +DEF_HELPER_3(dfcmpuo, s32, env, f64, f64) +DEF_HELPER_3(dfclass, s32, env, f64, s32) + +DEF_HELPER_3(sfmpy, f32, env, f32, f32) +DEF_HELPER_4(sffma, f32, env, f32, f32, f32) +DEF_HELPER_5(sffma_sc, f32, env, f32, f32, f32, f32) +DEF_HELPER_4(sffms, f32, env, f32, f32, f32) +DEF_HELPER_4(sffma_lib, f32, env, f32, f32, f32) +DEF_HELPER_4(sffms_lib, f32, env, f32, f32, f32) + +DEF_HELPER_3(dfmpyfix, f64, env, f64, f64) +DEF_HELPER_4(dfmpyhh, f64, env, f64, f64, f64) diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c new file mode 100644 index 0000000000..2c6d718579 --- /dev/null +++ b/target/hexagon/op_helper.c @@ -0,0 +1,1064 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu.h" +#include "exec/helper-proto.h" +#include "fpu/softfloat.h" +#include "cpu.h" +#include "internal.h" +#include "macros.h" +#include "arch.h" +#include "hex_arch_types.h" +#include "fma_emu.h" +#include "conv_emu.h" + +#define SF_BIAS 127 +#define SF_MANTBITS 23 + +/* Exceptions processing helpers */ +static void QEMU_NORETURN do_raise_exception_err(CPUHexagonState *env, + uint32_t exception, + uintptr_t pc) +{ + CPUState *cs = CPU(hexagon_env_get_cpu(env)); + qemu_log_mask(CPU_LOG_INT, "%s: %d\n", __func__, exception); + cs->exception_index = exception; + cpu_loop_exit_restore(cs, pc); +} + +void QEMU_NORETURN HELPER(raise_exception)(CPUHexagonState *env, uint32_t excp) +{ + do_raise_exception_err(env, excp, 0); +} + +static inline void log_reg_write(CPUHexagonState *env, int rnum, + target_ulong val, uint32_t slot) +{ + HEX_DEBUG_LOG("log_reg_write[%d] = " TARGET_FMT_ld " (0x" TARGET_FMT_lx ")", + rnum, val, val); + if (val == env->gpr[rnum]) { + HEX_DEBUG_LOG(" NO CHANGE"); + } + HEX_DEBUG_LOG("\n"); + + env->new_value[rnum] = val; +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + env->reg_written[rnum] = 1; +#endif +} + +static inline void log_pred_write(CPUHexagonState *env, int pnum, + target_ulong val) +{ + HEX_DEBUG_LOG("log_pred_write[%d] = " TARGET_FMT_ld + " (0x" TARGET_FMT_lx ")\n", + pnum, val, val); + + /* Multiple writes to the same preg are and'ed together */ + if (env->pred_written & (1 << pnum)) { + env->new_pred_value[pnum] &= val & 0xff; + } else { + env->new_pred_value[pnum] = val & 0xff; + env->pred_written |= 1 << pnum; + } +} + +static inline void log_store32(CPUHexagonState *env, target_ulong addr, + target_ulong val, int width, int slot) +{ + HEX_DEBUG_LOG("log_store%d(0x" TARGET_FMT_lx + ", %" PRId32 " [0x08%" PRIx32 "])\n", + width, addr, val, val); + env->mem_log_stores[slot].va = addr; + env->mem_log_stores[slot].width = width; + env->mem_log_stores[slot].data32 = val; +} + +static inline void log_store64(CPUHexagonState *env, target_ulong addr, + int64_t val, int width, int slot) +{ + HEX_DEBUG_LOG("log_store%d(0x" TARGET_FMT_lx + ", %" PRId64 " [0x016%" PRIx64 "])\n", + width, addr, val, val); + env->mem_log_stores[slot].va = addr; + env->mem_log_stores[slot].width = width; + env->mem_log_stores[slot].data64 = val; +} + +static inline void write_new_pc(CPUHexagonState *env, target_ulong addr) +{ + HEX_DEBUG_LOG("write_new_pc(0x" TARGET_FMT_lx ")\n", addr); + + /* + * If more than one branch is taken in a packet, only the first one + * is actually done. + */ + if (env->branch_taken) { + HEX_DEBUG_LOG("INFO: multiple branches taken in same packet, " + "ignoring the second one\n"); + } else { + fCHECK_PCALIGN(addr); + env->branch_taken = 1; + env->next_PC = addr; + } +} + +#if HEX_DEBUG +/* Handy place to set a breakpoint */ +void HELPER(debug_start_packet)(CPUHexagonState *env) +{ + HEX_DEBUG_LOG("Start packet: pc = 0x" TARGET_FMT_lx "\n", + env->gpr[HEX_REG_PC]); + + for (int i = 0; i < TOTAL_PER_THREAD_REGS; i++) { + env->reg_written[i] = 0; + } +} +#endif + +static inline int32_t new_pred_value(CPUHexagonState *env, int pnum) +{ + return env->new_pred_value[pnum]; +} + +#if HEX_DEBUG +/* Checks for bookkeeping errors between disassembly context and runtime */ +void HELPER(debug_check_store_width)(CPUHexagonState *env, int slot, int check) +{ + if (env->mem_log_stores[slot].width != check) { + HEX_DEBUG_LOG("ERROR: %d != %d\n", + env->mem_log_stores[slot].width, check); + g_assert_not_reached(); + } +} +#endif + +void HELPER(commit_store)(CPUHexagonState *env, int slot_num) +{ + switch (env->mem_log_stores[slot_num].width) { + case 1: + put_user_u8(env->mem_log_stores[slot_num].data32, + env->mem_log_stores[slot_num].va); + break; + case 2: + put_user_u16(env->mem_log_stores[slot_num].data32, + env->mem_log_stores[slot_num].va); + break; + case 4: + put_user_u32(env->mem_log_stores[slot_num].data32, + env->mem_log_stores[slot_num].va); + break; + case 8: + put_user_u64(env->mem_log_stores[slot_num].data64, + env->mem_log_stores[slot_num].va); + break; + default: + g_assert_not_reached(); + } +} + +#if HEX_DEBUG +static void print_store(CPUHexagonState *env, int slot) +{ + if (!(env->slot_cancelled & (1 << slot))) { + uint8_t width = env->mem_log_stores[slot].width; + if (width == 1) { + uint32_t data = env->mem_log_stores[slot].data32 & 0xff; + HEX_DEBUG_LOG("\tmemb[0x" TARGET_FMT_lx "] = %" PRId32 + " (0x%02" PRIx32 ")\n", + env->mem_log_stores[slot].va, data, data); + } else if (width == 2) { + uint32_t data = env->mem_log_stores[slot].data32 & 0xffff; + HEX_DEBUG_LOG("\tmemh[0x" TARGET_FMT_lx "] = %" PRId32 + " (0x%04" PRIx32 ")\n", + env->mem_log_stores[slot].va, data, data); + } else if (width == 4) { + uint32_t data = env->mem_log_stores[slot].data32; + HEX_DEBUG_LOG("\tmemw[0x" TARGET_FMT_lx "] = %" PRId32 + " (0x%08" PRIx32 ")\n", + env->mem_log_stores[slot].va, data, data); + } else if (width == 8) { + HEX_DEBUG_LOG("\tmemd[0x" TARGET_FMT_lx "] = %" PRId64 + " (0x%016" PRIx64 ")\n", + env->mem_log_stores[slot].va, + env->mem_log_stores[slot].data64, + env->mem_log_stores[slot].data64); + } else { + HEX_DEBUG_LOG("\tBad store width %d\n", width); + g_assert_not_reached(); + } + } +} + +/* This function is a handy place to set a breakpoint */ +void HELPER(debug_commit_end)(CPUHexagonState *env, int has_st0, int has_st1) +{ + bool reg_printed = false; + bool pred_printed = false; + int i; + + HEX_DEBUG_LOG("Packet committed: pc = 0x" TARGET_FMT_lx "\n", + env->this_PC); + HEX_DEBUG_LOG("slot_cancelled = %d\n", env->slot_cancelled); + + for (i = 0; i < TOTAL_PER_THREAD_REGS; i++) { + if (env->reg_written[i]) { + if (!reg_printed) { + HEX_DEBUG_LOG("Regs written\n"); + reg_printed = true; + } + HEX_DEBUG_LOG("\tr%d = " TARGET_FMT_ld " (0x" TARGET_FMT_lx ")\n", + i, env->new_value[i], env->new_value[i]); + } + } + + for (i = 0; i < NUM_PREGS; i++) { + if (env->pred_written & (1 << i)) { + if (!pred_printed) { + HEX_DEBUG_LOG("Predicates written\n"); + pred_printed = true; + } + HEX_DEBUG_LOG("\tp%d = 0x" TARGET_FMT_lx "\n", + i, env->new_pred_value[i]); + } + } + + if (has_st0 || has_st1) { + HEX_DEBUG_LOG("Stores\n"); + if (has_st0) { + print_store(env, 0); + } + if (has_st1) { + print_store(env, 1); + } + } + + HEX_DEBUG_LOG("Next PC = " TARGET_FMT_lx "\n", env->next_PC); + HEX_DEBUG_LOG("Exec counters: pkt = " TARGET_FMT_lx + ", insn = " TARGET_FMT_lx + "\n", + env->gpr[HEX_REG_QEMU_PKT_CNT], + env->gpr[HEX_REG_QEMU_INSN_CNT]); + +} +#endif + +static int32_t fcircadd_v4(int32_t RxV, int32_t offset, int32_t M, int32_t CS) +{ + int32_t length = M & 0x0001ffff; + uint32_t new_ptr = RxV + offset; + uint32_t start_addr = CS; + uint32_t end_addr = start_addr + length; + + if (new_ptr >= end_addr) { + new_ptr -= length; + } else if (new_ptr < start_addr) { + new_ptr += length; + } + + return new_ptr; +} + +int32_t HELPER(fcircadd)(int32_t RxV, int32_t offset, int32_t M, int32_t CS) +{ + int32_t K_const = (M >> 24) & 0xf; + int32_t length = M & 0x1ffff; + int32_t mask = (1 << (K_const + 2)) - 1; + uint32_t new_ptr = RxV + offset; + uint32_t start_addr = RxV & (~mask); + uint32_t end_addr = start_addr | length; + + if (K_const == 0 && length >= 4) { + return fcircadd_v4(RxV, offset, M, CS); + } + + if (new_ptr >= end_addr) { + new_ptr -= length; + } else if (new_ptr < start_addr) { + new_ptr += length; + } + + return new_ptr; +} + +/* + * Hexagon FP operations return ~0 insteat of NaN + * The hex_check_sfnan/hex_check_dfnan functions perform this check + */ +static float32 hex_check_sfnan(float32 x) +{ + if (float32_is_any_nan(x)) { + return make_float32(0xFFFFFFFFU); + } + return x; +} + +static float64 hex_check_dfnan(float64 x) +{ + if (float64_is_any_nan(x)) { + return make_float64(0xFFFFFFFFFFFFFFFFULL); + } + return x; +} + +/* + * mem_noshuf + * Section 5.5 of the Hexagon V67 Programmer's Reference Manual + * + * If the load is in slot 0 and there is a store in slot1 (that + * wasn't cancelled), we have to do the store first. + */ +static void check_noshuf(CPUHexagonState *env, uint32_t slot) +{ + if (slot == 0 && env->pkt_has_store_s1 && + ((env->slot_cancelled & (1 << 1)) == 0)) { + HELPER(commit_store)(env, 1); + } +} + +static inline uint8_t mem_load1(CPUHexagonState *env, uint32_t slot, + target_ulong vaddr) +{ + uint8_t retval; + check_noshuf(env, slot); + get_user_u8(retval, vaddr); + return retval; +} + +static inline uint16_t mem_load2(CPUHexagonState *env, uint32_t slot, + target_ulong vaddr) +{ + uint16_t retval; + check_noshuf(env, slot); + get_user_u16(retval, vaddr); + return retval; +} + +static inline uint32_t mem_load4(CPUHexagonState *env, uint32_t slot, + target_ulong vaddr) +{ + uint32_t retval; + check_noshuf(env, slot); + get_user_u32(retval, vaddr); + return retval; +} + +static inline uint64_t mem_load8(CPUHexagonState *env, uint32_t slot, + target_ulong vaddr) +{ + uint64_t retval; + check_noshuf(env, slot); + get_user_u64(retval, vaddr); + return retval; +} + +/* Floating point */ +float64 HELPER(conv_sf2df)(CPUHexagonState *env, float32 RsV) +{ + float64 out_f64; + arch_fpop_start(env); + out_f64 = float32_to_float64(RsV, &env->fp_status); + out_f64 = hex_check_dfnan(out_f64); + arch_fpop_end(env); + return out_f64; +} + +float32 HELPER(conv_df2sf)(CPUHexagonState *env, float64 RssV) +{ + float32 out_f32; + arch_fpop_start(env); + out_f32 = float64_to_float32(RssV, &env->fp_status); + out_f32 = hex_check_sfnan(out_f32); + arch_fpop_end(env); + return out_f32; +} + +float32 HELPER(conv_uw2sf)(CPUHexagonState *env, int32_t RsV) +{ + float32 RdV; + arch_fpop_start(env); + RdV = uint32_to_float32(RsV, &env->fp_status); + RdV = hex_check_sfnan(RdV); + arch_fpop_end(env); + return RdV; +} + +float64 HELPER(conv_uw2df)(CPUHexagonState *env, int32_t RsV) +{ + float64 RddV; + arch_fpop_start(env); + RddV = uint32_to_float64(RsV, &env->fp_status); + RddV = hex_check_dfnan(RddV); + arch_fpop_end(env); + return RddV; +} + +float32 HELPER(conv_w2sf)(CPUHexagonState *env, int32_t RsV) +{ + float32 RdV; + arch_fpop_start(env); + RdV = int32_to_float32(RsV, &env->fp_status); + RdV = hex_check_sfnan(RdV); + arch_fpop_end(env); + return RdV; +} + +float64 HELPER(conv_w2df)(CPUHexagonState *env, int32_t RsV) +{ + float64 RddV; + arch_fpop_start(env); + RddV = int32_to_float64(RsV, &env->fp_status); + RddV = hex_check_dfnan(RddV); + arch_fpop_end(env); + return RddV; +} + +float32 HELPER(conv_ud2sf)(CPUHexagonState *env, int64_t RssV) +{ + float32 RdV; + arch_fpop_start(env); + RdV = uint64_to_float32(RssV, &env->fp_status); + RdV = hex_check_sfnan(RdV); + arch_fpop_end(env); + return RdV; +} + +float64 HELPER(conv_ud2df)(CPUHexagonState *env, int64_t RssV) +{ + float64 RddV; + arch_fpop_start(env); + RddV = uint64_to_float64(RssV, &env->fp_status); + RddV = hex_check_dfnan(RddV); + arch_fpop_end(env); + return RddV; +} + +float32 HELPER(conv_d2sf)(CPUHexagonState *env, int64_t RssV) +{ + float32 RdV; + arch_fpop_start(env); + RdV = int64_to_float32(RssV, &env->fp_status); + RdV = hex_check_sfnan(RdV); + arch_fpop_end(env); + return RdV; +} + +float64 HELPER(conv_d2df)(CPUHexagonState *env, int64_t RssV) +{ + float64 RddV; + arch_fpop_start(env); + RddV = int64_to_float64(RssV, &env->fp_status); + RddV = hex_check_dfnan(RddV); + arch_fpop_end(env); + return RddV; +} + +int32_t HELPER(conv_sf2uw)(CPUHexagonState *env, float32 RsV) +{ + int32_t RdV; + arch_fpop_start(env); + RdV = conv_sf_to_4u(RsV, &env->fp_status); + arch_fpop_end(env); + return RdV; +} + +int32_t HELPER(conv_sf2w)(CPUHexagonState *env, float32 RsV) +{ + int32_t RdV; + arch_fpop_start(env); + RdV = conv_sf_to_4s(RsV, &env->fp_status); + arch_fpop_end(env); + return RdV; +} + +int64_t HELPER(conv_sf2ud)(CPUHexagonState *env, float32 RsV) +{ + int64_t RddV; + arch_fpop_start(env); + RddV = conv_sf_to_8u(RsV, &env->fp_status); + arch_fpop_end(env); + return RddV; +} + +int64_t HELPER(conv_sf2d)(CPUHexagonState *env, float32 RsV) +{ + int64_t RddV; + arch_fpop_start(env); + RddV = conv_sf_to_8s(RsV, &env->fp_status); + arch_fpop_end(env); + return RddV; +} + +int32_t HELPER(conv_df2uw)(CPUHexagonState *env, float64 RssV) +{ + int32_t RdV; + arch_fpop_start(env); + RdV = conv_df_to_4u(RssV, &env->fp_status); + arch_fpop_end(env); + return RdV; +} + +int32_t HELPER(conv_df2w)(CPUHexagonState *env, float64 RssV) +{ + int32_t RdV; + arch_fpop_start(env); + RdV = conv_df_to_4s(RssV, &env->fp_status); + arch_fpop_end(env); + return RdV; +} + +int64_t HELPER(conv_df2ud)(CPUHexagonState *env, float64 RssV) +{ + int64_t RddV; + arch_fpop_start(env); + RddV = conv_df_to_8u(RssV, &env->fp_status); + arch_fpop_end(env); + return RddV; +} + +int64_t HELPER(conv_df2d)(CPUHexagonState *env, float64 RssV) +{ + int64_t RddV; + arch_fpop_start(env); + RddV = conv_df_to_8s(RssV, &env->fp_status); + arch_fpop_end(env); + return RddV; +} + +int32_t HELPER(conv_sf2uw_chop)(CPUHexagonState *env, float32 RsV) +{ + int32_t RdV; + arch_fpop_start(env); + set_float_rounding_mode(float_round_to_zero, &env->fp_status); + RdV = conv_sf_to_4u(RsV, &env->fp_status); + arch_fpop_end(env); + return RdV; +} + +int32_t HELPER(conv_sf2w_chop)(CPUHexagonState *env, float32 RsV) +{ + int32_t RdV; + arch_fpop_start(env); + set_float_rounding_mode(float_round_to_zero, &env->fp_status); + RdV = conv_sf_to_4s(RsV, &env->fp_status); + arch_fpop_end(env); + return RdV; +} + +int64_t HELPER(conv_sf2ud_chop)(CPUHexagonState *env, float32 RsV) +{ + int64_t RddV; + arch_fpop_start(env); + set_float_rounding_mode(float_round_to_zero, &env->fp_status); + RddV = conv_sf_to_8u(RsV, &env->fp_status); + arch_fpop_end(env); + return RddV; +} + +int64_t HELPER(conv_sf2d_chop)(CPUHexagonState *env, float32 RsV) +{ + int64_t RddV; + arch_fpop_start(env); + set_float_rounding_mode(float_round_to_zero, &env->fp_status); + RddV = conv_sf_to_8s(RsV, &env->fp_status); + arch_fpop_end(env); + return RddV; +} + +int32_t HELPER(conv_df2uw_chop)(CPUHexagonState *env, float64 RssV) +{ + int32_t RdV; + arch_fpop_start(env); + set_float_rounding_mode(float_round_to_zero, &env->fp_status); + RdV = conv_df_to_4u(RssV, &env->fp_status); + arch_fpop_end(env); + return RdV; +} + +int32_t HELPER(conv_df2w_chop)(CPUHexagonState *env, float64 RssV) +{ + int32_t RdV; + arch_fpop_start(env); + set_float_rounding_mode(float_round_to_zero, &env->fp_status); + RdV = conv_df_to_4s(RssV, &env->fp_status); + arch_fpop_end(env); + return RdV; +} + +int64_t HELPER(conv_df2ud_chop)(CPUHexagonState *env, float64 RssV) +{ + int64_t RddV; + arch_fpop_start(env); + set_float_rounding_mode(float_round_to_zero, &env->fp_status); + RddV = conv_df_to_8u(RssV, &env->fp_status); + arch_fpop_end(env); + return RddV; +} + +int64_t HELPER(conv_df2d_chop)(CPUHexagonState *env, float64 RssV) +{ + int64_t RddV; + arch_fpop_start(env); + set_float_rounding_mode(float_round_to_zero, &env->fp_status); + RddV = conv_df_to_8s(RssV, &env->fp_status); + arch_fpop_end(env); + return RddV; +} + +float32 HELPER(sfadd)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + float32 RdV; + arch_fpop_start(env); + RdV = float32_add(RsV, RtV, &env->fp_status); + RdV = hex_check_sfnan(RdV); + arch_fpop_end(env); + return RdV; +} + +float32 HELPER(sfsub)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + float32 RdV; + arch_fpop_start(env); + RdV = float32_sub(RsV, RtV, &env->fp_status); + RdV = hex_check_sfnan(RdV); + arch_fpop_end(env); + return RdV; +} + +int32_t HELPER(sfcmpeq)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + int32_t PdV; + arch_fpop_start(env); + PdV = f8BITSOF(float32_eq_quiet(RsV, RtV, &env->fp_status)); + arch_fpop_end(env); + return PdV; +} + +int32_t HELPER(sfcmpgt)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + int cmp; + int32_t PdV; + arch_fpop_start(env); + cmp = float32_compare_quiet(RsV, RtV, &env->fp_status); + PdV = f8BITSOF(cmp == float_relation_greater); + arch_fpop_end(env); + return PdV; +} + +int32_t HELPER(sfcmpge)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + int cmp; + int32_t PdV; + arch_fpop_start(env); + cmp = float32_compare_quiet(RsV, RtV, &env->fp_status); + PdV = f8BITSOF(cmp == float_relation_greater || + cmp == float_relation_equal); + arch_fpop_end(env); + return PdV; +} + +int32_t HELPER(sfcmpuo)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + int32_t PdV; + arch_fpop_start(env); + PdV = f8BITSOF(float32_is_any_nan(RsV) || + float32_is_any_nan(RtV)); + arch_fpop_end(env); + return PdV; +} + +float32 HELPER(sfmax)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + float32 RdV; + arch_fpop_start(env); + RdV = float32_maxnum(RsV, RtV, &env->fp_status); + RdV = hex_check_sfnan(RdV); + arch_fpop_end(env); + return RdV; +} + +float32 HELPER(sfmin)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + float32 RdV; + arch_fpop_start(env); + RdV = float32_minnum(RsV, RtV, &env->fp_status); + RdV = hex_check_sfnan(RdV); + arch_fpop_end(env); + return RdV; +} + +int32_t HELPER(sfclass)(CPUHexagonState *env, float32 RsV, int32_t uiV) +{ + int32_t PdV = 0; + arch_fpop_start(env); + if (fGETBIT(0, uiV) && float32_is_zero(RsV)) { + PdV = 0xff; + } + if (fGETBIT(1, uiV) && float32_is_normal(RsV)) { + PdV = 0xff; + } + if (fGETBIT(2, uiV) && float32_is_denormal(RsV)) { + PdV = 0xff; + } + if (fGETBIT(3, uiV) && float32_is_infinity(RsV)) { + PdV = 0xff; + } + if (fGETBIT(4, uiV) && float32_is_any_nan(RsV)) { + PdV = 0xff; + } + set_float_exception_flags(0, &env->fp_status); + arch_fpop_end(env); + return PdV; +} + +float32 HELPER(sffixupn)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + float32 RdV = 0; + int adjust; + arch_fpop_start(env); + arch_sf_recip_common(&RsV, &RtV, &RdV, &adjust, &env->fp_status); + RdV = RsV; + arch_fpop_end(env); + return RdV; +} + +float32 HELPER(sffixupd)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + float32 RdV = 0; + int adjust; + arch_fpop_start(env); + arch_sf_recip_common(&RsV, &RtV, &RdV, &adjust, &env->fp_status); + RdV = RtV; + arch_fpop_end(env); + return RdV; +} + +float32 HELPER(sffixupr)(CPUHexagonState *env, float32 RsV) +{ + float32 RdV = 0; + int adjust; + arch_fpop_start(env); + arch_sf_invsqrt_common(&RsV, &RdV, &adjust, &env->fp_status); + RdV = RsV; + arch_fpop_end(env); + return RdV; +} + +float64 HELPER(dfadd)(CPUHexagonState *env, float64 RssV, float64 RttV) +{ + float64 RddV; + arch_fpop_start(env); + RddV = float64_add(RssV, RttV, &env->fp_status); + RddV = hex_check_dfnan(RddV); + arch_fpop_end(env); + return RddV; +} + +float64 HELPER(dfsub)(CPUHexagonState *env, float64 RssV, float64 RttV) +{ + float64 RddV; + arch_fpop_start(env); + RddV = float64_sub(RssV, RttV, &env->fp_status); + RddV = hex_check_dfnan(RddV); + arch_fpop_end(env); + return RddV; +} + +float64 HELPER(dfmax)(CPUHexagonState *env, float64 RssV, float64 RttV) +{ + float64 RddV; + arch_fpop_start(env); + RddV = float64_maxnum(RssV, RttV, &env->fp_status); + if (float64_is_any_nan(RssV) || float64_is_any_nan(RttV)) { + float_raise(float_flag_invalid, &env->fp_status); + } + RddV = hex_check_dfnan(RddV); + arch_fpop_end(env); + return RddV; +} + +float64 HELPER(dfmin)(CPUHexagonState *env, float64 RssV, float64 RttV) +{ + float64 RddV; + arch_fpop_start(env); + RddV = float64_minnum(RssV, RttV, &env->fp_status); + if (float64_is_any_nan(RssV) || float64_is_any_nan(RttV)) { + float_raise(float_flag_invalid, &env->fp_status); + } + RddV = hex_check_dfnan(RddV); + arch_fpop_end(env); + return RddV; +} + +int32_t HELPER(dfcmpeq)(CPUHexagonState *env, float64 RssV, float64 RttV) +{ + int32_t PdV; + arch_fpop_start(env); + PdV = f8BITSOF(float64_eq_quiet(RssV, RttV, &env->fp_status)); + arch_fpop_end(env); + return PdV; +} + +int32_t HELPER(dfcmpgt)(CPUHexagonState *env, float64 RssV, float64 RttV) +{ + int cmp; + int32_t PdV; + arch_fpop_start(env); + cmp = float64_compare_quiet(RssV, RttV, &env->fp_status); + PdV = f8BITSOF(cmp == float_relation_greater); + arch_fpop_end(env); + return PdV; +} + +int32_t HELPER(dfcmpge)(CPUHexagonState *env, float64 RssV, float64 RttV) +{ + int cmp; + int32_t PdV; + arch_fpop_start(env); + cmp = float64_compare_quiet(RssV, RttV, &env->fp_status); + PdV = f8BITSOF(cmp == float_relation_greater || + cmp == float_relation_equal); + arch_fpop_end(env); + return PdV; +} + +int32_t HELPER(dfcmpuo)(CPUHexagonState *env, float64 RssV, float64 RttV) +{ + int32_t PdV; + arch_fpop_start(env); + PdV = f8BITSOF(float64_is_any_nan(RssV) || + float64_is_any_nan(RttV)); + arch_fpop_end(env); + return PdV; +} + +int32_t HELPER(dfclass)(CPUHexagonState *env, float64 RssV, int32_t uiV) +{ + int32_t PdV = 0; + arch_fpop_start(env); + if (fGETBIT(0, uiV) && float64_is_zero(RssV)) { + PdV = 0xff; + } + if (fGETBIT(1, uiV) && float64_is_normal(RssV)) { + PdV = 0xff; + } + if (fGETBIT(2, uiV) && float64_is_denormal(RssV)) { + PdV = 0xff; + } + if (fGETBIT(3, uiV) && float64_is_infinity(RssV)) { + PdV = 0xff; + } + if (fGETBIT(4, uiV) && float64_is_any_nan(RssV)) { + PdV = 0xff; + } + set_float_exception_flags(0, &env->fp_status); + arch_fpop_end(env); + return PdV; +} + +float32 HELPER(sfmpy)(CPUHexagonState *env, float32 RsV, float32 RtV) +{ + float32 RdV; + arch_fpop_start(env); + RdV = internal_mpyf(RsV, RtV, &env->fp_status); + RdV = hex_check_sfnan(RdV); + arch_fpop_end(env); + return RdV; +} + +float32 HELPER(sffma)(CPUHexagonState *env, float32 RxV, + float32 RsV, float32 RtV) +{ + arch_fpop_start(env); + RxV = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status); + RxV = hex_check_sfnan(RxV); + arch_fpop_end(env); + return RxV; +} + +static bool is_zero_prod(float32 a, float32 b) +{ + return ((float32_is_zero(a) && is_finite(b)) || + (float32_is_zero(b) && is_finite(a))); +} + +static float32 check_nan(float32 dst, float32 x, float_status *fp_status) +{ + float32 ret = dst; + if (float32_is_any_nan(x)) { + if (extract32(x, 22, 1) == 0) { + float_raise(float_flag_invalid, fp_status); + } + ret = make_float32(0xffffffff); /* nan */ + } + return ret; +} + +float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV, + float32 RsV, float32 RtV, float32 PuV) +{ + size4s_t tmp; + arch_fpop_start(env); + RxV = check_nan(RxV, RxV, &env->fp_status); + RxV = check_nan(RxV, RsV, &env->fp_status); + RxV = check_nan(RxV, RtV, &env->fp_status); + tmp = internal_fmafx(RsV, RtV, RxV, fSXTN(8, 64, PuV), &env->fp_status); + tmp = hex_check_sfnan(tmp); + if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) { + RxV = tmp; + } + arch_fpop_end(env); + return RxV; +} + +float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV, + float32 RsV, float32 RtV) +{ + float32 neg_RsV; + arch_fpop_start(env); + neg_RsV = float32_sub(float32_zero, RsV, &env->fp_status); + RxV = internal_fmafx(neg_RsV, RtV, RxV, 0, &env->fp_status); + RxV = hex_check_sfnan(RxV); + arch_fpop_end(env); + return RxV; +} + +static inline bool is_inf_prod(int32_t a, int32_t b) +{ + return (float32_is_infinity(a) && float32_is_infinity(b)) || + (float32_is_infinity(a) && is_finite(b) && !float32_is_zero(b)) || + (float32_is_infinity(b) && is_finite(a) && !float32_is_zero(a)); +} + +float32 HELPER(sffma_lib)(CPUHexagonState *env, float32 RxV, + float32 RsV, float32 RtV) +{ + int infinp; + int infminusinf; + float32 tmp; + + arch_fpop_start(env); + set_float_rounding_mode(float_round_nearest_even, &env->fp_status); + infminusinf = float32_is_infinity(RxV) && + is_inf_prod(RsV, RtV) && + (fGETBIT(31, RsV ^ RxV ^ RtV) != 0); + infinp = float32_is_infinity(RxV) || + float32_is_infinity(RtV) || + float32_is_infinity(RsV); + RxV = check_nan(RxV, RxV, &env->fp_status); + RxV = check_nan(RxV, RsV, &env->fp_status); + RxV = check_nan(RxV, RtV, &env->fp_status); + tmp = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status); + tmp = hex_check_sfnan(tmp); + if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) { + RxV = tmp; + } + set_float_exception_flags(0, &env->fp_status); + if (float32_is_infinity(RxV) && !infinp) { + RxV = RxV - 1; + } + if (infminusinf) { + RxV = 0; + } + arch_fpop_end(env); + return RxV; +} + +float32 HELPER(sffms_lib)(CPUHexagonState *env, float32 RxV, + float32 RsV, float32 RtV) +{ + int infinp; + int infminusinf; + float32 tmp; + + arch_fpop_start(env); + set_float_rounding_mode(float_round_nearest_even, &env->fp_status); + infminusinf = float32_is_infinity(RxV) && + is_inf_prod(RsV, RtV) && + (fGETBIT(31, RsV ^ RxV ^ RtV) == 0); + infinp = float32_is_infinity(RxV) || + float32_is_infinity(RtV) || + float32_is_infinity(RsV); + RxV = check_nan(RxV, RxV, &env->fp_status); + RxV = check_nan(RxV, RsV, &env->fp_status); + RxV = check_nan(RxV, RtV, &env->fp_status); + float32 minus_RsV = float32_sub(float32_zero, RsV, &env->fp_status); + tmp = internal_fmafx(minus_RsV, RtV, RxV, 0, &env->fp_status); + tmp = hex_check_sfnan(tmp); + if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) { + RxV = tmp; + } + set_float_exception_flags(0, &env->fp_status); + if (float32_is_infinity(RxV) && !infinp) { + RxV = RxV - 1; + } + if (infminusinf) { + RxV = 0; + } + arch_fpop_end(env); + return RxV; +} + +float64 HELPER(dfmpyfix)(CPUHexagonState *env, float64 RssV, float64 RttV) +{ + int64_t RddV; + arch_fpop_start(env); + if (float64_is_denormal(RssV) && + (float64_getexp(RttV) >= 512) && + float64_is_normal(RttV)) { + RddV = float64_mul(RssV, make_float64(0x4330000000000000), + &env->fp_status); + RddV = hex_check_dfnan(RddV); + } else if (float64_is_denormal(RttV) && + (float64_getexp(RssV) >= 512) && + float64_is_normal(RssV)) { + RddV = float64_mul(RssV, make_float64(0x3cb0000000000000), + &env->fp_status); + RddV = hex_check_dfnan(RddV); + } else { + RddV = RssV; + } + arch_fpop_end(env); + return RddV; +} + +float64 HELPER(dfmpyhh)(CPUHexagonState *env, float64 RxxV, + float64 RssV, float64 RttV) +{ + arch_fpop_start(env); + RxxV = internal_mpyhh(RssV, RttV, RxxV, &env->fp_status); + RxxV = hex_check_dfnan(RxxV); + arch_fpop_end(env); + return RxxV; +} + +static void cancel_slot(CPUHexagonState *env, uint32_t slot) +{ + HEX_DEBUG_LOG("Slot %d cancelled\n", slot); + env->slot_cancelled |= (1 << slot); +} + +/* These macros can be referenced in the generated helper functions */ +#define warn(...) /* Nothing */ +#define fatal(...) g_assert_not_reached(); + +#define BOGUS_HELPER(tag) \ + printf("ERROR: bogus helper: " #tag "\n") + +#include "helper_funcs_generated.c.inc" From patchwork Wed Feb 17 23:39:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383940 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3221745jao; Wed, 17 Feb 2021 15:49:31 -0800 (PST) X-Google-Smtp-Source: ABdhPJxuVmK73jND/EXZRoYcU69n5IHX+CneMGdiU+6i6h3x5OKSvyn25yQEUbd8y0nDye683tMr X-Received: by 2002:a25:d70b:: with SMTP id o11mr2714332ybg.471.1613605770952; Wed, 17 Feb 2021 15:49:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605770; cv=none; d=google.com; s=arc-20160816; b=QwHnu4B8pLu7A2jfyks7anFOFd7aM+h2sd0jwxeFMqE8AcG0FyZvB3Pf/fMZPCdmKh G0k03LSM4WlFcTgohBEIMfDyHdmgUJOimbKeMWhTfdsiBkFrlQFVxqlefMMFAPEQ3u84 7bzvtLPfTfiO0TbUe5yDH2EX/lZ7X7t5gaZ/U7YLLx5lPYRiey5AEMwX6ZH23UwhKXrp GprSX6J7g1BF0FzIvAwz26cm3PhQDXO0DOlZZRXcBimFDX6he0sLXGnuAAVlgyvZny5j eqS1rpb0EXcWyGGR0lW6Z6fcOh0PQXLojEMjPE2Z58+d/0yqWvMIL+r7rYPa3JGq5Hgx ypMQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=rT3fdfxLOBUZePBBIZU0/yFNFGueWion3u26dnymBfY=; b=tkGHaUUvjAzwjP0A93B6HoLXyyMs31s85HSbrbCtWoVIN9kttgd+9e2zXva6CcOyrn FlicBk7gYEdNsQrnqG0mYiSaDRTqzOvbXvVvmcZvfmSQlos1ESBdwE9fGD5Bd6snsPBo e+Vlnvvvb3g4FDX5Ido/11HA6nu+NwfRJltX3KgENJnyzkaUUkFborwFh0Y/azapRJh6 NxC/dFtjlwQh0W1IcvrETFSPmGIZiqI5eVawByR3F0tJ44JHvsmH3tS4CYjG5YrY/drM EWJ5HIhIui3RT2ESyui3cLPITJFDU1cSJtx2pCc5Wct99NAVlceByv16riSju12j4+Hb 0VVA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OQYuTL8i; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id u17si3655126ybj.429.2021.02.17.15.49.30 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:49:30 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OQYuTL8i; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:58736 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWZW-0001Sc-EK for patch@linaro.org; Wed, 17 Feb 2021 18:49:30 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50628) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRA-0008Ds-ES for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:52 -0500 Received: from mail-pg1-x531.google.com ([2607:f8b0:4864:20::531]:42627) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWR7-0004ch-Rk for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:52 -0500 Received: by mail-pg1-x531.google.com with SMTP id o38so9502133pgm.9 for ; Wed, 17 Feb 2021 15:40:49 -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 :mime-version:content-transfer-encoding; bh=rT3fdfxLOBUZePBBIZU0/yFNFGueWion3u26dnymBfY=; b=OQYuTL8isULqJrBXjgnJVlNqgNrk0eKil7Vjvhiq1Op/OM3W5pRGihovrKl1p22zVd 61APAvQhsOjnqWkKcjP/ZWPGzG//XaOFlB3NWuJiOQz9yYKffwKRhuxpZB9IwjikxDRv qBdSi5IwssUGT5BQFSQBs4nwu5tn76HH+sRo+dAUnwpw07urlfBvTw788GN/8uB81wzg m8X7qIfmRD/KZXz25QoARpN/7ySpJK3BiOUD6Q5Hq6vtt9Nl/rk4MDch60UFow77GvLY QnewiY42gVHGS9yoUmO1Pdr3J8yjtYwjwfQKoUd+qecWgZtRWjCtrCJGMTYUzTpYOKWu gn3A== 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:mime-version:content-transfer-encoding; bh=rT3fdfxLOBUZePBBIZU0/yFNFGueWion3u26dnymBfY=; b=k7Wj0HtqPx5DGGWaheO6fW/n1MQsuVDXswD/E2q+wUpJqs0hcnuB1CZcyO8b3kWcIP hJuhuqdeJP+sRRsXs66b8As4Kcf5Lp8KEt5isJdnGecINZYleT3tIcH3AEgguy1buHwm dI5+pJk/2l/cgaIMQEFs2H6jgI3upwTx+OI6YebKNnHyde9nzSTrYoM7/vWlVWevG+em d+zglp6+C0zreRawM1TLHOsBecS8g5OHglkaXjkHYVA26Jm7Rvaa6RaDnCvvefzapMOE 7Hc9VTuBNjwd4xU3RVBVv2BC5WENOIZI0Jqjc5WtzpigRY2S9F6u9rFD6A87vateBAeu 2j7A== X-Gm-Message-State: AOAM530/yXGFfHK6EgnuoXY7I3E0Bb9JSSIgiYzI2QCDCPzTkmKlYOZs 2UzQzMlEFG/4qOLG+bwq4V55pINECRKGAg== X-Received: by 2002:a62:2c50:0:b029:1b9:1846:b490 with SMTP id s77-20020a622c500000b02901b91846b490mr1551788pfs.76.1613605248196; Wed, 17 Feb 2021 15:40:48 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:47 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 09/35] Hexagon (target/hexagon) GDB Stub Date: Wed, 17 Feb 2021 15:39:57 -0800 Message-Id: <20210217234023.1742406-10-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::531; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x531.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson GDB register read and write routines Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1612763186-18161-9-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/internal.h | 2 ++ target/hexagon/gdbstub.c | 47 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 target/hexagon/gdbstub.c -- 2.25.1 diff --git a/target/hexagon/internal.h b/target/hexagon/internal.h index c839796cd1..2da85c8606 100644 --- a/target/hexagon/internal.h +++ b/target/hexagon/internal.h @@ -28,6 +28,8 @@ #define HEX_DEBUG_LOG(...) do { } while (0) #endif +int hexagon_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); +int hexagon_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void hexagon_debug(CPUHexagonState *env); extern const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS]; diff --git a/target/hexagon/gdbstub.c b/target/hexagon/gdbstub.c new file mode 100644 index 0000000000..9c8c04c961 --- /dev/null +++ b/target/hexagon/gdbstub.c @@ -0,0 +1,47 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" +#include "cpu.h" +#include "internal.h" + +int hexagon_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) +{ + HexagonCPU *cpu = HEXAGON_CPU(cs); + CPUHexagonState *env = &cpu->env; + + if (n < TOTAL_PER_THREAD_REGS) { + return gdb_get_regl(mem_buf, env->gpr[n]); + } + + g_assert_not_reached(); +} + +int hexagon_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) +{ + HexagonCPU *cpu = HEXAGON_CPU(cs); + CPUHexagonState *env = &cpu->env; + + if (n < TOTAL_PER_THREAD_REGS) { + env->gpr[n] = ldtul_p(mem_buf); + return sizeof(target_ulong); + } + + g_assert_not_reached(); +} From patchwork Wed Feb 17 23:39:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383937 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3220652jao; Wed, 17 Feb 2021 15:47:16 -0800 (PST) X-Google-Smtp-Source: ABdhPJwX+gMhWIt9SPrbFqlSPHyKRF6/3Fdr2+UmmAK1P6KcRXtLjasSQNRy+hYV9vMH03h7NN9F X-Received: by 2002:a25:d64e:: with SMTP id n75mr2722764ybg.171.1613605636881; Wed, 17 Feb 2021 15:47:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605636; cv=none; d=google.com; s=arc-20160816; b=bhpkfb8dMCxCCkjVK3sayiIev9S/0RBt5/LM0CbPwJtoPYmeiA0pbiUnnPN/2/gNCT ZeQVbkz+bz6dcgPsfNX51IuGA1c/2dA6dy9Qz0XNtEq7iuVdlC+6sO3RaEg/QdCUcK+9 5uEJNW8idQjS3Fzhbez+2OOjo9aUMu8cHq5zEwJ8uTL+R3Hb95VldoIpqfCyMbzLS7BU SbCL3AlrumIUXXyNplPibGmwovZMgQDeu9/7gOY4h6klTqpNaV9W1LNZOaz4XMurGMzF E/VeH3283bi77xBkvMxExj1+glYfaaxwv4EDjOej5IZv0K+UDoLhG5N0Iap7zdTfTBwr ZKPg== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=syEff87HhmL4pp5l8qJFx/wNBs45tn+PDuAIuUBTe6o=; b=zGpKK639zKdzkmYFkxMQCzzfn7nnaBST12xEt0o1XywoDn+z7723mAA3SN+HOj3u1r 81uZkVMOk+VJ4yhXNucQ4BE73VNxadjyT9uczdHVGsRkldDfnVVzElaDDypCdenp9O0N m9gH+OBtduGOro2bWSqSvuFwYTxsJUAYeRvjGerG/lWfs1sB6G53zb/3DvvwJ9TVSr0T PbNkemNqZR+tCBlHs+ehVbS5K/L4SwjyVSuJilaUFYq3Z5RANp+K4g7dBuy8vlkFgHad scE/xgoiYwzK+uG/2UYaPtCQBrN4tbx7lojJxrk/SnSxXFvZiaAd2Ymk93lmv8SwaaGy n1Zw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wVf25Jmo; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id k16si3600020ybp.314.2021.02.17.15.47.16 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:47:16 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wVf25Jmo; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:50988 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWXM-0006dO-55 for patch@linaro.org; Wed, 17 Feb 2021 18:47:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50644) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRB-0008HF-MW for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:53 -0500 Received: from mail-pf1-x42a.google.com ([2607:f8b0:4864:20::42a]:42136) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWR9-0004dQ-5c for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:53 -0500 Received: by mail-pf1-x42a.google.com with SMTP id w18so23604pfu.9 for ; Wed, 17 Feb 2021 15:40:50 -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 :mime-version:content-transfer-encoding; bh=syEff87HhmL4pp5l8qJFx/wNBs45tn+PDuAIuUBTe6o=; b=wVf25JmoVmwPwxn2dbzD53J63oqAeHHh1HjMCoM2wOTomO5v9e0npCxFvtGqbet/vg 8FepejFrfpD6rSajKOCDchLI56yQTZlnqIHJkb435N4inXclmlYSm1qqvCqyl0AVW+7M ZfE8drTY93SVQJQwAzgwMltNrxpWSnXKl6pr/3zy59fnUUUUsFnbtUQYUhArtPyGuqeJ V3PUxO59KlQbFboVD7+oy+m0dFi/cabngjdSHvRIW9GxbXKL4uqkHosnPhruFhK8+nfU 0j2Oc1HayuBU22L5VgGvvZjR50coJMwOjsFUmchufSWz6Ycw1QAqBy3K1nNjOVSaYZWF qrgg== 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:mime-version:content-transfer-encoding; bh=syEff87HhmL4pp5l8qJFx/wNBs45tn+PDuAIuUBTe6o=; b=oMzw2j9gUaBOdB/nNMDSdyJ3onS+9jkgoqvMLu2XfftMPjAfGtNPn24x5bDGAdtM+T R1hV8ze+i6u3TigfKDeoiE9hkFCxw3WMoW3D21XQeJtarV22/MON7V4fRiTgqd68lLSj FHzuUwXu83mRmjttNS1hUu7D6yw1OZ1MXi7NxJ8gUl7cUzCPSNSKQWmq8z+g6156dlnO yqeKFEcdleVFNLsi1wwEWlPiRX9+hQjA4PmS98Sgono2hyhRf/+LjlMav4qJSvZVM0gX Yf588prCGu8/lV95d5vzNNdIsd1SbLYqemfHKPTzMd2RQtoR2Ky3EY7cphjAb5rJefm8 RR1w== X-Gm-Message-State: AOAM532cDxG8tLRiIwzF6D3hbgZKLh3pr9bzjITaJdTLamP5bKvy6Pjh x3/vaauxnC75QszOEtqiybHW25jXDSluEQ== X-Received: by 2002:a62:bd05:0:b029:1ab:6d2:5edf with SMTP id a5-20020a62bd050000b02901ab06d25edfmr1467574pff.32.1613605249782; Wed, 17 Feb 2021 15:40:49 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:49 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 10/35] Hexagon (target/hexagon) architecture types Date: Wed, 17 Feb 2021 15:39:58 -0800 Message-Id: <20210217234023.1742406-11-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42a; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Define types used in files imported from the Hexagon architecture library Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1612763186-18161-10-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/hex_arch_types.h | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 target/hexagon/hex_arch_types.h -- 2.25.1 diff --git a/target/hexagon/hex_arch_types.h b/target/hexagon/hex_arch_types.h new file mode 100644 index 0000000000..d721e1f934 --- /dev/null +++ b/target/hexagon/hex_arch_types.h @@ -0,0 +1,38 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_ARCH_TYPES_H +#define HEXAGON_ARCH_TYPES_H + +#include "qemu/osdep.h" +#include "qemu/int128.h" + +/* + * These types are used by the code imported from the Hexagon + * architecture library. + */ +typedef uint8_t size1u_t; +typedef int8_t size1s_t; +typedef uint16_t size2u_t; +typedef int16_t size2s_t; +typedef uint32_t size4u_t; +typedef int32_t size4s_t; +typedef uint64_t size8u_t; +typedef int64_t size8s_t; +typedef Int128 size16s_t; + +#endif From patchwork Wed Feb 17 23:39:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383941 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3221983jao; Wed, 17 Feb 2021 15:49:57 -0800 (PST) X-Google-Smtp-Source: ABdhPJxGVrBwP6cvsn1y42xUeVaBilVI8Puar0Dj1sQ9cx1oM8MOy15zYm/rOPKcuEsDxO9eyCpD X-Received: by 2002:a5b:30c:: with SMTP id j12mr2642141ybp.360.1613605797781; Wed, 17 Feb 2021 15:49:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605797; cv=none; d=google.com; s=arc-20160816; b=O8NXx+bJqvEEl4XmuChv+i0L+D4sgmbxQAGxG9ySEiS89vHcZB3JqbMOa7OjInALF/ LSPOznfHaAEv5udwTh0xTwzO45OG+doRbX56DyjmZbvIFBjVphIOMW3GZrayQ6/lTeEZ Cs8sHVcoEB3V5rf+eQQ+KIhMG7Rm62RB7UdMcpQ56cUYfW81/qk7xNn7k1yDU9tbEQoC 18blK3ntcEH6z4C+tXfPyBh/ppEYHA551x2LIRs4zXsF2da+v8OHe99KW9Ip3d7p7Mfe x/kxf+5qFgXqM/iEy34I3XmU3X+6m85ngvOVCTjumBm9ryqEdxUpGvNquZ7wT81nEwg+ j/Wg== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=+Ct613QdC6dlEWBE/nYo3PltwiwMWPpntLMKNmtZ7L0=; b=vJ/mBVvsIL804TGItBC+MqB6/j9IjfsFPywchcq8MVMeNr5NgYI5ktooUyMCNbgQH6 gq9SK6ETGQ9oC1tWkugdKrySFU+fMZSnIAgtGj9S0onKOQ/E06/97gYgvUWocsj6ntau v+Kx2tPAaiF0nPt6UBSpeGC2Y5Q6qkRU6IFeuBOqL3e99z8cXXFzOk8hl6dQOgt2obeD zK+AAoBVtR1DFSVrJ51GsCNCbB4HphWDz993ZWKcwTNHyDct3vrtuwXGZ+DS4BgTsn4H Y1il6Qx3W0BD5pus0fWBucc3YvrdcPqtsyQnkdMrWs/CAGZwhkHffj6HZegXx2oPXC0L XD/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="I/cqg8Rj"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id o135si3221860ybg.469.2021.02.17.15.49.57 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:49:57 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="I/cqg8Rj"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:58950 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWZx-0001Xc-5S for patch@linaro.org; Wed, 17 Feb 2021 18:49:57 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50658) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRD-0008Kq-HZ for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:55 -0500 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]:53425) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRA-0004dd-T1 for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:55 -0500 Received: by mail-pj1-x102a.google.com with SMTP id c19so240503pjq.3 for ; Wed, 17 Feb 2021 15:40:52 -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 :mime-version:content-transfer-encoding; bh=+Ct613QdC6dlEWBE/nYo3PltwiwMWPpntLMKNmtZ7L0=; b=I/cqg8RjinVjqos4iKyz2HBGWbSW1e7hWaq+Tt3vI2f4ch6l04uHgSF0W3c9GBUBCy CQIiNwPvxHHZZDdKcPWYASM89B3sTEfZxJLrTMwGsliq9MHKatDvc55Xm+IMY0XZ9O6c m1HlTUszkxrOF0dREQ28Q/pjCBQqZbqFDml2A1KEnXLHu8DVj2+xesJwKQn58EyIaKlo tkYcNwze7iSxt73o9y1/o0WQ9WRIOy1G03N4kdWsoarN9Dtb5P1bTPS9wSwuLOomqtYK w+lbCcpGk9dAnFRTf0AlBKHNFwsOhzDJDOHbOPPe4259lsnIzK0cebZaDRHr2QGl+Be3 6kCw== 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:mime-version:content-transfer-encoding; bh=+Ct613QdC6dlEWBE/nYo3PltwiwMWPpntLMKNmtZ7L0=; b=czCdYMA6ysTgdbjV9ipwdnKWPkBhb7xVM3DWr22l06oZKkwMSikCvGjlQjT2Iw6O02 z/b5s+guaZwLg1YswL3p+teQWiz70qwCHI3sBaUAzD+An6s2R9rCY0wCshrOb8tRpeQk 9ciIzwYKoPXnkrIWvdUG+qWvsvLoIz6f9i7wLz/yAo6lElPkJBnxtXxgXtfnN8VZ1r5U upIaXiD/wz9tgoG3YlQUCftYPSKOCov/HcXzMA/P38GwAQgylepAFzxxTaAcT4mGdaUP g2IJm3RukunZuiqES3gh/yHnF9ZspvM0Vo9tmlPTM78E3evOXrHiNLxwHushK05pIkcP Qf9w== X-Gm-Message-State: AOAM530wUH5tRVcfODnVHm3gEgbFOIbUPgBm9vhhCK51Nuwni2Vs6fzL M1cEef0luqI61Dt2OKl5xjsxXEcZheBn6g== X-Received: by 2002:a17:902:8201:b029:e3:95d2:eb0a with SMTP id x1-20020a1709028201b02900e395d2eb0amr1575092pln.43.1613605251352; Wed, 17 Feb 2021 15:40:51 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:50 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 11/35] Hexagon (target/hexagon) instruction and packet types Date: Wed, 17 Feb 2021 15:39:59 -0800 Message-Id: <20210217234023.1742406-12-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson The insn_t and packet_t are the interface between instruction decoding and TCG code generation Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-11-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/insn.h | 74 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 target/hexagon/insn.h -- 2.25.1 diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h new file mode 100644 index 0000000000..5756a1d0ca --- /dev/null +++ b/target/hexagon/insn.h @@ -0,0 +1,74 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_INSN_H +#define HEXAGON_INSN_H + +#include "cpu.h" + +#define INSTRUCTIONS_MAX 7 /* 2 pairs + loopend */ +#define REG_OPERANDS_MAX 5 +#define IMMEDS_MAX 2 + +struct Instruction; +struct Packet; +struct DisasContext; + +typedef void (*SemanticInsn)(CPUHexagonState *env, + struct DisasContext *ctx, + struct Instruction *insn, + struct Packet *pkt); + +struct Instruction { + SemanticInsn generate; /* pointer to genptr routine */ + uint8_t regno[REG_OPERANDS_MAX]; /* reg operands including predicates */ + uint16_t opcode; + + uint32_t iclass:6; + uint32_t slot:3; + uint32_t part1:1; /* + * cmp-jumps are split into two insns. + * set for the compare and clear for the jump + */ + uint32_t extension_valid:1; /* Has a constant extender attached */ + uint32_t which_extended:1; /* If has an extender, which immediate */ + uint32_t is_endloop:1; /* This is an end of loop */ + uint32_t new_value_producer_slot:4; + int32_t immed[IMMEDS_MAX]; /* immediate field */ +}; + +typedef struct Instruction Insn; + +struct Packet { + uint16_t num_insns; + uint16_t encod_pkt_size_in_bytes; + + /* Pre-decodes about COF */ + uint32_t pkt_has_cof:1; /* Has any change-of-flow */ + uint32_t pkt_has_endloop:1; + + uint32_t pkt_has_dczeroa:1; + + uint32_t pkt_has_store_s0:1; + uint32_t pkt_has_store_s1:1; + + Insn insn[INSTRUCTIONS_MAX]; +}; + +typedef struct Packet Packet; + +#endif From patchwork Wed Feb 17 23:40:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383935 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3219033jao; Wed, 17 Feb 2021 15:43:55 -0800 (PST) X-Google-Smtp-Source: ABdhPJyRKJGYnNp23v0Wc9QCrnm/6YVExr2DNUJ2IxvTHhmOlyQP2ytQ5UYd875c0/B/e/3BccP7 X-Received: by 2002:a25:3623:: with SMTP id d35mr2818144yba.180.1613605435315; Wed, 17 Feb 2021 15:43:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605435; cv=none; d=google.com; s=arc-20160816; b=GQabRfAy/KJetX5CH/iqPVg3mbbunZY6jvUm2d0c5r3rfvbUFQWTBIB5L7O/Bdeuhi JEuRXeIYDFdReduhUGi1fBb/cGoBoOQe4Gnzdfz0E0NWS0CRXKkDCd2pu00SKqtTNCKi 2Yv0u9uXpOkOXV8A8Y3R93XhZXvV7wqEY7CdWB+nICKJh+XrQ47xayXMQ/njhrAA8Eug uo2MQnUEUcPkDCHAif/3ufArou1f1UGKXs2i6hp5jsdotic57aKKCxr0xRFAer8amtXj BLV21IeD4nz52gtu36ymdZ3LYGsUivDRVwNCNvTlmfMrnMTnwEV7ESA3XnLDEJYW+4Al oZ6g== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=dDaFLG04fKZppE97at5lCyqt8weiRL0OebuqOGVUCiE=; b=PssjdK/sdyoXTK29+q4AqUYJVqTSO5bYQ0jq8ixFpv+R/x48od+qy4aONszMkJKPKk cEvRVbcPok4ploDrc6B0pTB9VjM3DPHc3dod6ht/pUvgjOfP6CSL2GZFbQZ7AKVf7Tvl N5hXZrIBLuMpEEuETjfgM4l1dowpNJjvo6Kh2lDDJksJaB7e6Xd+JN/vwXIXpXzMqmcN E5iMJESvCSE5iQF/IQoVkXn712KBxblQPOqXX1oJppWTumb29bHwkpOVzx9WzCkZnhTu 2BAY+990bwLQxLOqJkGMaD8/VyJSQCmYebjHL2GV3Xob1Pd9/xuEguJd59qEis4ZkNiE J2iA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OvOchk+J; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id a10si1752243ybg.43.2021.02.17.15.43.55 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:43:55 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OvOchk+J; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:45616 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWU6-0004Dz-Kq for patch@linaro.org; Wed, 17 Feb 2021 18:43:54 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50668) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRE-0008Nx-Pq for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:56 -0500 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]:51012) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRC-0004eT-On for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:56 -0500 Received: by mail-pj1-x1033.google.com with SMTP id cl8so249558pjb.0 for ; Wed, 17 Feb 2021 15:40:54 -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 :mime-version:content-transfer-encoding; bh=dDaFLG04fKZppE97at5lCyqt8weiRL0OebuqOGVUCiE=; b=OvOchk+JWy/S88KPT9Fqh8rmCYvV/QrRulm5sTiKU7R1vZPPniI73/Els63WyPFGtS HYeLVT6LdhaBZrQqQsyjz22dX3FsvVdG0kpNExnR7FaxDoQQIRNEI2GJ7iT8H8ezcshg VuZpZ+1nmwpfrQOg/905osUbb8RPf1O3HKnxmBkDrGbL25wcZzj8qY9cp4fz847EHZ2o hClC3nG1QF3jmcV0UyGSA6n0WdluJ1JRJzNl4afE57rgbSgTbGYt/ikMeVT8BI9bQWmU 4ZQ1FP4rAdH1oKBPL5xpDVV22TfKMC+KwRWL0sSWS9FhPRfCc1GcQWW4o8JZEF5MIi4i xcCQ== 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:mime-version:content-transfer-encoding; bh=dDaFLG04fKZppE97at5lCyqt8weiRL0OebuqOGVUCiE=; b=pSVO04t33jsm0/FF1TFCjYBmlkpV2A1hMZXUXkCpVDURR6aEjS0jyNplriXOV93IRI zu56kilBXcowVYOhkM+72+Bp03+dxkTVZh0IpXhoXj8z8UIb9kKRf5jeOig1FncZ78ph oE69LfpQIxK9LA7Pp6rQogAHZxaZ4zwi1dUfihqiJ5fNiYGIbHJFhkZTksIjXCkaGGpK MsqOqJuoHUNSDM6Ia9QacD0lFZh4Qa56D9EH/+z2Ec3AqyuiuQZykHTEZrNwlPX3LS4B rArQ9DC13K5VsnVVXg3/3aFa93n79L7jZOUBbICveZCT0bIOjzOKlL0mjiEn/EClXEOV uU7g== X-Gm-Message-State: AOAM533qS82Tep7TDvuR1wXmiVudIwqFUpsdCYdT7loLmSm0L2+CpI7O 9gDgQHEzeWAmk8BWAZXIvylxX90qTz73tQ== X-Received: by 2002:a17:90b:e94:: with SMTP id fv20mr1156416pjb.207.1613605253370; Wed, 17 Feb 2021 15:40:53 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:52 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 12/35] Hexagon (target/hexagon) register fields Date: Wed, 17 Feb 2021 15:40:00 -0800 Message-Id: <20210217234023.1742406-13-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1033; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1033.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Declare bitfields within registers such as user status register (USR) Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-12-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/reg_fields.h | 36 +++++++++++++++++++++++++ target/hexagon/reg_fields_def.h.inc | 41 +++++++++++++++++++++++++++++ target/hexagon/reg_fields.c | 27 +++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 target/hexagon/reg_fields.h create mode 100644 target/hexagon/reg_fields_def.h.inc create mode 100644 target/hexagon/reg_fields.c -- 2.25.1 diff --git a/target/hexagon/reg_fields.h b/target/hexagon/reg_fields.h new file mode 100644 index 0000000000..d3c86c942f --- /dev/null +++ b/target/hexagon/reg_fields.h @@ -0,0 +1,36 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_REG_FIELDS_H +#define HEXAGON_REG_FIELDS_H + +typedef struct { + int offset; + int width; +} RegField; + +extern const RegField reg_field_info[]; + +enum { +#define DEF_REG_FIELD(TAG, START, WIDTH) \ + TAG, +#include "reg_fields_def.h.inc" + NUM_REG_FIELDS +#undef DEF_REG_FIELD +}; + +#endif diff --git a/target/hexagon/reg_fields_def.h.inc b/target/hexagon/reg_fields_def.h.inc new file mode 100644 index 0000000000..f2a58d486c --- /dev/null +++ b/target/hexagon/reg_fields_def.h.inc @@ -0,0 +1,41 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * For registers that have individual fields, explain them here + * DEF_REG_FIELD(tag, + * bit start offset, + * width + */ + +/* USR fields */ +DEF_REG_FIELD(USR_OVF, 0, 1) +DEF_REG_FIELD(USR_FPINVF, 1, 1) +DEF_REG_FIELD(USR_FPDBZF, 2, 1) +DEF_REG_FIELD(USR_FPOVFF, 3, 1) +DEF_REG_FIELD(USR_FPUNFF, 4, 1) +DEF_REG_FIELD(USR_FPINPF, 5, 1) + +DEF_REG_FIELD(USR_LPCFG, 8, 2) + +DEF_REG_FIELD(USR_FPRND, 22, 2) + +DEF_REG_FIELD(USR_FPINVE, 25, 1) +DEF_REG_FIELD(USR_FPDBZE, 26, 1) +DEF_REG_FIELD(USR_FPOVFE, 27, 1) +DEF_REG_FIELD(USR_FPUNFE, 28, 1) +DEF_REG_FIELD(USR_FPINPE, 29, 1) diff --git a/target/hexagon/reg_fields.c b/target/hexagon/reg_fields.c new file mode 100644 index 0000000000..bdcab79428 --- /dev/null +++ b/target/hexagon/reg_fields.c @@ -0,0 +1,27 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "reg_fields.h" + +const RegField reg_field_info[] = { +#define DEF_REG_FIELD(TAG, START, WIDTH) \ + { START, WIDTH }, +#include "reg_fields_def.h.inc" + { 0, 0 } +#undef DEF_REG_FIELD +}; From patchwork Wed Feb 17 23:40:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384041 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3223010jao; Wed, 17 Feb 2021 15:51:59 -0800 (PST) X-Google-Smtp-Source: ABdhPJyJKOdr10ZhIwqSjYtauj/TDunDzd2sP985FUL5ykUmomO02k512b4jZBoAA+T0DK3ZYCTm X-Received: by 2002:a25:dd1:: with SMTP id 200mr2829869ybn.262.1613605918919; Wed, 17 Feb 2021 15:51:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605918; cv=none; d=google.com; s=arc-20160816; b=B0civQs+9/S4SE29nWmUSXAm8J+mBzh5KZ2+ANJdCqccp0b/OKPlKen0VU/Z1vjFxZ q6n0pohHezq7mduCKB2VtktV6hLcdzdv6BftGJukql6/Fz+aaoK3WGQH6CP3tlR7L6sw rytPHV2RODNegm5xqULH+pBCUKU2sQHhFtXxun7BJ8iks9AyWDIlU52Nic+0S85bo7fJ t37HWkPYXfAXsG9kuAoXAK3N99BJfSJtRPenkGwN1wcpzH3258SGupquchsy+83yiV1Q 95Cr9rmNeCsl1DfAq8M8BuJtOPX3XYs2P3HWGVkMYa9BV7g+TkegF/DvgeUqad+jNLvl 5ndg== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=oGnaYxKKBgT3k2qwC/vFmzHYIKgNtQ/wsfJ4eKxQ8qk=; b=K9u8O0d5iizSRrIQD8E6LU6PzPBEsvjihz51261ejYMx+c/CDD1gRDicbUhy5FM0x2 GktVNGR2GlEJF3PaMXYWBqi0CjWXWYmyErhpZpbJyVGBPQfBCRWJuxsvwwXCg8xLftPr iGIsXeXU9vdmuetW/BrkQ/kyd6VJglekAhI442xjOxoy4IO+pFy2uSIZ24PASBqa2+AW SwuetFEp2jMZammIkui4VOaEa3fujw2tMA0M7mKh+gtjOzaPaakoOP5uZpI1omt68H57 rabg8HEMc0x1Evl01ke/tlm3Zfu6kIKhH4XHqiWJBOs0nNToHC99pY9Hil4s/S+l3HTr lw1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BD4LmWgk; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id v4si76772ybs.427.2021.02.17.15.51.58 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:51:58 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BD4LmWgk; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:39196 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWbu-00057m-A8 for patch@linaro.org; Wed, 17 Feb 2021 18:51:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50686) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRH-0008U2-2g for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:59 -0500 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]:37849) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRE-0004ek-QV for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:40:58 -0500 Received: by mail-pj1-x102c.google.com with SMTP id t2so269301pjq.2 for ; Wed, 17 Feb 2021 15:40:56 -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 :mime-version:content-transfer-encoding; bh=oGnaYxKKBgT3k2qwC/vFmzHYIKgNtQ/wsfJ4eKxQ8qk=; b=BD4LmWgkWmSTY7UpudGTrM66DwiVhJLaditD9NfIaYrAZK34zawRmleVyjBlrELM3f xGwNtPDfLzTTD6HGsth3BsDGU34xWGNR/GX0Gx8YeCNG+Nem7Up+gZweMp5+GIuAgzR/ vgxdVT2iU4zCkM96HRX44K+IFdpzo2Zfk1kwz217FY5lxzYKid/bIEAml1BtBLo9ShDO i2wSlYx2wWiMfrjGoPsCHQsDCDd8giWgeKoEVj3cLlAi0Mgnor/He+Fvmc3dBWdpd/Lp 5fNvHnL49BRBGCLgmbA6PveDU2RVKqz3ZG7CJv8vUebzIPNKVAC7bDj9yp2k+ZIQ3uLz ayyA== 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:mime-version:content-transfer-encoding; bh=oGnaYxKKBgT3k2qwC/vFmzHYIKgNtQ/wsfJ4eKxQ8qk=; b=eTnYH0VHUh569S4f7KxxbCFpOD5rhf4oMjHxWrOPN3wLv/ma6DW5PpgQy3gsDsOLV7 o93JV79TKwW0aXZwgpXrI+WVtGwb2FAw+DP476ulpSZkTMPNV9u3cOGf3o4g4uLjLGNc PoxpHqik/wKu+N1nVjKMZiP92idm4N7oIdm+fxXJVWZ2gejteU2NBZ7cWkG8MV2M3xd7 YL68Lzk9lpL3ScDawsCZPv8aXALGAiIk8/whPGy93I4/ZLxzvg0g2bwV44uSVcRu2bEd ITtIscl9PFvUD7mM4SWVr015gR+7uNsOgkOZD+MjjL0axrK3X+mmfjlAzqQBWwyee4VP QkdA== X-Gm-Message-State: AOAM530hpNDRz/4k8CIayPS4t0RbOnh5D/YhurBMR+OJhe45FSRbWQps Wacpc94UgzvN3y4a78QwT6G8qOTYurE2xQ== X-Received: by 2002:a17:902:8501:b029:e2:ebb4:6e77 with SMTP id bj1-20020a1709028501b02900e2ebb46e77mr1346757plb.43.1613605255386; Wed, 17 Feb 2021 15:40:55 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:54 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 13/35] Hexagon (target/hexagon) instruction attributes Date: Wed, 17 Feb 2021 15:40:01 -0800 Message-Id: <20210217234023.1742406-14-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Signed-off-by: Taylor Simpson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-13-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/attribs.h | 35 ++++++++++++ target/hexagon/attribs_def.h.inc | 97 ++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 target/hexagon/attribs.h create mode 100644 target/hexagon/attribs_def.h.inc -- 2.25.1 diff --git a/target/hexagon/attribs.h b/target/hexagon/attribs.h new file mode 100644 index 0000000000..54576f4143 --- /dev/null +++ b/target/hexagon/attribs.h @@ -0,0 +1,35 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_ATTRIBS_H +#define HEXAGON_ATTRIBS_H + +#include "qemu/bitmap.h" +#include "opcodes.h" + +enum { +#define DEF_ATTRIB(NAME, ...) A_##NAME, +#include "attribs_def.h.inc" +#undef DEF_ATTRIB +}; + +extern DECLARE_BITMAP(opcode_attribs[XX_LAST_OPCODE], A_ZZ_LASTATTRIB); + +#define GET_ATTRIB(opcode, attrib) \ + test_bit(attrib, opcode_attribs[opcode]) + +#endif /* ATTRIBS_H */ diff --git a/target/hexagon/attribs_def.h.inc b/target/hexagon/attribs_def.h.inc new file mode 100644 index 0000000000..381550909d --- /dev/null +++ b/target/hexagon/attribs_def.h.inc @@ -0,0 +1,97 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* Keep this as the first attribute: */ +DEF_ATTRIB(AA_DUMMY, "Dummy Zeroth Attribute", "", "") + +/* Misc */ +DEF_ATTRIB(EXTENSION, "Extension instruction", "", "") + +DEF_ATTRIB(PRIV, "Not available in user or guest mode", "", "") +DEF_ATTRIB(GUEST, "Not available in user mode", "", "") + +DEF_ATTRIB(FPOP, "Floating Point Operation", "", "") + +DEF_ATTRIB(EXTENDABLE, "Immediate may be extended", "", "") + +DEF_ATTRIB(ARCHV2, "V2 architecture", "", "") +DEF_ATTRIB(ARCHV3, "V3 architecture", "", "") +DEF_ATTRIB(ARCHV4, "V4 architecture", "", "") +DEF_ATTRIB(ARCHV5, "V5 architecture", "", "") + +DEF_ATTRIB(SUBINSN, "sub-instruction", "", "") + +/* Load and Store attributes */ +DEF_ATTRIB(LOAD, "Loads from memory", "", "") +DEF_ATTRIB(STORE, "Stores to memory", "", "") +DEF_ATTRIB(MEMLIKE, "Memory-like instruction", "", "") +DEF_ATTRIB(MEMLIKE_PACKET_RULES, "follows Memory-like packet rules", "", "") + + +/* Change-of-flow attributes */ +DEF_ATTRIB(JUMP, "Jump-type instruction", "", "") +DEF_ATTRIB(INDIRECT, "Absolute register jump", "", "") +DEF_ATTRIB(CALL, "Function call instruction", "", "") +DEF_ATTRIB(COF, "Change-of-flow instruction", "", "") +DEF_ATTRIB(CONDEXEC, "May be cancelled by a predicate", "", "") +DEF_ATTRIB(DOTNEWVALUE, "Uses a register value generated in this pkt", "", "") +DEF_ATTRIB(NEWCMPJUMP, "Compound compare and jump", "", "") + +/* access to implicit registers */ +DEF_ATTRIB(IMPLICIT_WRITES_LR, "Writes the link register", "", "UREG.LR") +DEF_ATTRIB(IMPLICIT_WRITES_SP, "Writes the stack pointer", "", "UREG.SP") +DEF_ATTRIB(IMPLICIT_WRITES_FP, "Writes the frame pointer", "", "UREG.FP") +DEF_ATTRIB(IMPLICIT_WRITES_LC0, "Writes loop count for loop 0", "", "UREG.LC0") +DEF_ATTRIB(IMPLICIT_WRITES_LC1, "Writes loop count for loop 1", "", "UREG.LC1") +DEF_ATTRIB(IMPLICIT_WRITES_SA0, "Writes start addr for loop 0", "", "UREG.SA0") +DEF_ATTRIB(IMPLICIT_WRITES_SA1, "Writes start addr for loop 1", "", "UREG.SA1") +DEF_ATTRIB(IMPLICIT_WRITES_P0, "Writes Predicate 0", "", "UREG.P0") +DEF_ATTRIB(IMPLICIT_WRITES_P1, "Writes Predicate 1", "", "UREG.P1") +DEF_ATTRIB(IMPLICIT_WRITES_P2, "Writes Predicate 1", "", "UREG.P2") +DEF_ATTRIB(IMPLICIT_WRITES_P3, "May write Predicate 3", "", "UREG.P3") +DEF_ATTRIB(IMPLICIT_READS_PC, "Reads the PC register", "", "") +DEF_ATTRIB(WRITES_PRED_REG, "Writes a predicate register", "", "") + +DEF_ATTRIB(CRSLOT23, "Can execute in slot 2 or slot 3 (CR)", "", "") +DEF_ATTRIB(IT_NOP, "nop instruction", "", "") +DEF_ATTRIB(IT_EXTENDER, "constant extender instruction", "", "") + + +/* Restrictions to make note of */ +DEF_ATTRIB(RESTRICT_SLOT0ONLY, "Must execute on slot0", "", "") +DEF_ATTRIB(RESTRICT_SLOT1ONLY, "Must execute on slot1", "", "") +DEF_ATTRIB(RESTRICT_SLOT2ONLY, "Must execute on slot2", "", "") +DEF_ATTRIB(RESTRICT_SLOT3ONLY, "Must execute on slot3", "", "") +DEF_ATTRIB(RESTRICT_NOSLOT1, "No slot 1 instruction in parallel", "", "") +DEF_ATTRIB(RESTRICT_PREFERSLOT0, "Try to encode into slot 0", "", "") + +DEF_ATTRIB(ICOP, "Instruction cache op", "", "") + +DEF_ATTRIB(HWLOOP0_END, "Ends HW loop0", "", "") +DEF_ATTRIB(HWLOOP1_END, "Ends HW loop1", "", "") +DEF_ATTRIB(DCZEROA, "dczeroa type", "", "") +DEF_ATTRIB(ICFLUSHOP, "icflush op type", "", "") +DEF_ATTRIB(DCFLUSHOP, "dcflush op type", "", "") +DEF_ATTRIB(DCFETCH, "dcfetch type", "", "") + +DEF_ATTRIB(L2FETCH, "Instruction is l2fetch type", "", "") + +DEF_ATTRIB(ICINVA, "icinva", "", "") +DEF_ATTRIB(DCCLEANINVA, "dccleaninva", "", "") + +/* Keep this as the last attribute: */ +DEF_ATTRIB(ZZ_LASTATTRIB, "Last attribute in the file", "", "") From patchwork Wed Feb 17 23:40:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384140 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3224424jao; Wed, 17 Feb 2021 15:55:04 -0800 (PST) X-Google-Smtp-Source: ABdhPJziGinKHD7YfOVG4I7QbRTsRXgN2NAarqnYBH5dTVRLlDH1RXiAEQmv460L2i/bIjHt4zEX X-Received: by 2002:a25:46d6:: with SMTP id t205mr2571268yba.47.1613606104105; Wed, 17 Feb 2021 15:55:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606104; cv=none; d=google.com; s=arc-20160816; b=T44KKNq+FxbAapKZ958BsNkCxSXalGouPE0w+jthy4SrbYxi4DsNdAtGzNcHqqXUXk q/m4uNGNmRa1l9vc6tayDNO6JUx7a+hPzG9NpPsDgysJeqjnBsHdF6UCW8atmsjoAgzv FNd2cjvvxADHCvJWRs9hQb35vyeDS9n81GNUeuYjfuuIgisdB8xY731wJ4JvKBltl+YN k0tg3DnuI2YUWyqw6H/GYNdmFmM9mXo6kM9BA1GiZqAz7cQN2F0/GtK9LMp2L50fTRyt 54OvzL7TiZMJCRkmjUnWeL6n9Q1W+wjFT1DL+SdYXDxlnnbYxEPMqki7AvQGJspMb1mD xrnA== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=+4KMQ8x+BMG6c8hJi61P4S06pDXtJwP/HJLAU37OL50=; b=BcMcjPqe4431F9xRpNCRRc9iPunGzp/QKKOS8w6OFZqNICnOKtj8Hmh8D1kab1sVpJ YwW37BBrcFpZYGByQk4CTFs5WarBZRMaIHUZqQ1eSfTty0iWPSNqzYSo4agCcwOzgvOf vZz9kV5aVKtI4x6ged/bY36eoKIpUWd7GuC9f6mll2DGenPRR8UWPiXikKNdxM679Z6E J9ioDRr64dy0814/ty6lyEAQnnq2cyC068vrLR/NHc7pSSvwyl4jrog/uh9l/uRrGuwa DTvn1TEStS7cE1adHFKhlkZe8TRg+5IMYyZAsUFgulCSBjVdnxkp+9GGYG+lpj1pNNtE zW4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CLwQRTiZ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 8si3547080ybo.110.2021.02.17.15.55.03 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:55:04 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CLwQRTiZ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:46848 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWet-0008NG-5U for patch@linaro.org; Wed, 17 Feb 2021 18:55:03 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50714) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRK-0000B1-La for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:02 -0500 Received: from mail-pf1-x432.google.com ([2607:f8b0:4864:20::432]:40749) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRG-0004fT-Sm for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:02 -0500 Received: by mail-pf1-x432.google.com with SMTP id u143so29600pfc.7 for ; Wed, 17 Feb 2021 15:40:58 -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 :mime-version:content-transfer-encoding; bh=+4KMQ8x+BMG6c8hJi61P4S06pDXtJwP/HJLAU37OL50=; b=CLwQRTiZfw7ONcC110YJTEmTVUGbu3X33tocaO/awNxbTFJ8GbZCSxu88rbjJwCluI P+CAbPM17SAqn8rA6IGmi0saoeMgCYWTZUE3lYp8S0IBpxfYp+pIgQULgmHw4r+fBqCx 5zM9/ZvR0hf4tV/vu9GFlI8+hOoSUbpOpQcYB2PD0QLzHr0w2CdI8ladRxJFVicHXyI1 by80DujwZte7/+uxM1wWy2xk07mdiElJTSnbDqv8SiPXdafhMKnFdlX1kMRMhe4WWrVn kKRpY5N/qCXn/68YJCZRCoA+KtUjws9apr+HNkdGb7ST2CUTCThi7UNfzT3YU2rvbgtu XPmA== 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:mime-version:content-transfer-encoding; bh=+4KMQ8x+BMG6c8hJi61P4S06pDXtJwP/HJLAU37OL50=; b=LeLrRnh1xDs3cF2hpeq6ZJ2XGCg5vFZL/tQuxhD9b2Im+Y5btGoo4bpiN5vAF9sA2x 1As/iqXxL95O81BXuLSMRpEyBolO8xU+/diGEVG+YpQ5zj2ZVdU8B7IljGGXJc4kfKuX XnFmQ9goY3du//3ilurERswlUiDBP7P2YICLDlg/4nR/rOuwShI/xKJuozr+WfWUgUFZ crQOf/NPRt0J5MNfmdzBTnuDGc+td+54k5R96uYnV0grQrEYX7AdyoeNkIhUk02XcIh9 /cGlI07gkZ9YuX3NT7GGMi+WwQpqUD8xN3eQIiZSq/xaH/P+j/XRvHhLeEmvvnmGzvaI Bqhw== X-Gm-Message-State: AOAM531FePcLctI3Roj13wh2IqIaZu74gVuOo+Esnb8zSNPiHppQQ3dP Jgsb1C03JiPoQT+BiOmnqSA/rx+O5W4gNA== X-Received: by 2002:a63:d203:: with SMTP id a3mr1487837pgg.333.1613605257285; Wed, 17 Feb 2021 15:40:57 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:56 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 14/35] Hexagon (target/hexagon) instruction/packet decode Date: Wed, 17 Feb 2021 15:40:02 -0800 Message-Id: <20210217234023.1742406-15-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::432; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x432.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Take the words from instruction memory and build a packet_t for TCG code generation The following operations are performed Convert the .new encoded offset to the register number of the producer Reorder the packet so .new producer is before consumer Apply constant extenders Separate subinsn's into two instructions Break compare-jumps into two instructions Create instructions for :endloop Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-14-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/decode.h | 32 ++ target/hexagon/decode.c | 957 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 989 insertions(+) create mode 100644 target/hexagon/decode.h create mode 100644 target/hexagon/decode.c -- 2.25.1 diff --git a/target/hexagon/decode.h b/target/hexagon/decode.h new file mode 100644 index 0000000000..c66f5ea64d --- /dev/null +++ b/target/hexagon/decode.h @@ -0,0 +1,32 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_DECODE_H +#define HEXAGON_DECODE_H + +#include "cpu.h" +#include "opcodes.h" +#include "insn.h" + +void decode_init(void); + +void decode_send_insn_to(Packet *packet, int start, int newloc); + +int decode_packet(int max_words, const uint32_t *words, Packet *pkt, + bool disas_only); + +#endif diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c new file mode 100644 index 0000000000..c9bacaa1ee --- /dev/null +++ b/target/hexagon/decode.c @@ -0,0 +1,957 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "iclass.h" +#include "attribs.h" +#include "genptr.h" +#include "decode.h" +#include "insn.h" +#include "printinsn.h" + +#define fZXTN(N, M, VAL) ((VAL) & ((1LL << (N)) - 1)) + +enum { + EXT_IDX_noext = 0, + EXT_IDX_noext_AFTER = 4, + EXT_IDX_mmvec = 4, + EXT_IDX_mmvec_AFTER = 8, + XX_LAST_EXT_IDX +}; + +/* + * Certain operand types represent a non-contiguous set of values. + * For example, the compound compare-and-jump instruction can only access + * registers R0-R7 and R16-23. + * This table represents the mapping from the encoding to the actual values. + */ + +#define DEF_REGMAP(NAME, ELEMENTS, ...) \ + static const unsigned int DECODE_REGISTER_##NAME[ELEMENTS] = \ + { __VA_ARGS__ }; + /* Name Num Table */ +DEF_REGMAP(R_16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23) +DEF_REGMAP(R__8, 8, 0, 2, 4, 6, 16, 18, 20, 22) + +#define DECODE_MAPPED_REG(REGNO, NAME) \ + insn->regno[REGNO] = DECODE_REGISTER_##NAME[insn->regno[REGNO]]; + +typedef struct { + const struct DectreeTable *table_link; + const struct DectreeTable *table_link_b; + Opcode opcode; + enum { + DECTREE_ENTRY_INVALID, + DECTREE_TABLE_LINK, + DECTREE_SUBINSNS, + DECTREE_EXTSPACE, + DECTREE_TERMINAL + } type; +} DectreeEntry; + +typedef struct DectreeTable { + unsigned int (*lookup_function)(int startbit, int width, uint32_t opcode); + unsigned int size; + unsigned int startbit; + unsigned int width; + const DectreeEntry table[]; +} DectreeTable; + +#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) \ + static const DectreeTable dectree_table_##TAG; +#define TABLE_LINK(TABLE) /* NOTHING */ +#define TERMINAL(TAG, ENC) /* NOTHING */ +#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) /* NOTHING */ +#define EXTSPACE(TAG, ENC) /* NOTHING */ +#define INVALID() /* NOTHING */ +#define DECODE_END_TABLE(...) /* NOTHING */ +#define DECODE_MATCH_INFO(...) /* NOTHING */ +#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ +#define DECODE_OPINFO(...) /* NOTHING */ + +#include "dectree_generated.h.inc" + +#undef DECODE_OPINFO +#undef DECODE_MATCH_INFO +#undef DECODE_LEGACY_MATCH_INFO +#undef DECODE_END_TABLE +#undef INVALID +#undef TERMINAL +#undef SUBINSNS +#undef EXTSPACE +#undef TABLE_LINK +#undef DECODE_NEW_TABLE +#undef DECODE_SEPARATOR_BITS + +#define DECODE_SEPARATOR_BITS(START, WIDTH) NULL, START, WIDTH +#define DECODE_NEW_TABLE_HELPER(TAG, SIZE, FN, START, WIDTH) \ + static const DectreeTable dectree_table_##TAG = { \ + .size = SIZE, \ + .lookup_function = FN, \ + .startbit = START, \ + .width = WIDTH, \ + .table = { +#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) \ + DECODE_NEW_TABLE_HELPER(TAG, SIZE, WHATNOT) + +#define TABLE_LINK(TABLE) \ + { .type = DECTREE_TABLE_LINK, .table_link = &dectree_table_##TABLE }, +#define TERMINAL(TAG, ENC) \ + { .type = DECTREE_TERMINAL, .opcode = TAG }, +#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) \ + { \ + .type = DECTREE_SUBINSNS, \ + .table_link = &dectree_table_DECODE_SUBINSN_##CLASSA, \ + .table_link_b = &dectree_table_DECODE_SUBINSN_##CLASSB \ + }, +#define EXTSPACE(TAG, ENC) { .type = DECTREE_EXTSPACE }, +#define INVALID() { .type = DECTREE_ENTRY_INVALID, .opcode = XX_LAST_OPCODE }, + +#define DECODE_END_TABLE(...) } }; + +#define DECODE_MATCH_INFO(...) /* NOTHING */ +#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ +#define DECODE_OPINFO(...) /* NOTHING */ + +#include "dectree_generated.h.inc" + +#undef DECODE_OPINFO +#undef DECODE_MATCH_INFO +#undef DECODE_LEGACY_MATCH_INFO +#undef DECODE_END_TABLE +#undef INVALID +#undef TERMINAL +#undef SUBINSNS +#undef EXTSPACE +#undef TABLE_LINK +#undef DECODE_NEW_TABLE +#undef DECODE_NEW_TABLE_HELPER +#undef DECODE_SEPARATOR_BITS + +static const DectreeTable dectree_table_DECODE_EXT_EXT_noext = { + .size = 1, .lookup_function = NULL, .startbit = 0, .width = 0, + .table = { + { .type = DECTREE_ENTRY_INVALID, .opcode = XX_LAST_OPCODE }, + } +}; + +static const DectreeTable *ext_trees[XX_LAST_EXT_IDX]; + +static void decode_ext_init(void) +{ + int i; + for (i = EXT_IDX_noext; i < EXT_IDX_noext_AFTER; i++) { + ext_trees[i] = &dectree_table_DECODE_EXT_EXT_noext; + } +} + +typedef struct { + uint32_t mask; + uint32_t match; +} DecodeITableEntry; + +#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) /* NOTHING */ +#define TABLE_LINK(TABLE) /* NOTHING */ +#define TERMINAL(TAG, ENC) /* NOTHING */ +#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) /* NOTHING */ +#define EXTSPACE(TAG, ENC) /* NOTHING */ +#define INVALID() /* NOTHING */ +#define DECODE_END_TABLE(...) /* NOTHING */ +#define DECODE_OPINFO(...) /* NOTHING */ + +#define DECODE_MATCH_INFO_NORMAL(TAG, MASK, MATCH) \ + [TAG] = { \ + .mask = MASK, \ + .match = MATCH, \ + }, + +#define DECODE_MATCH_INFO_NULL(TAG, MASK, MATCH) \ + [TAG] = { .match = ~0 }, + +#define DECODE_MATCH_INFO(...) DECODE_MATCH_INFO_NORMAL(__VA_ARGS__) +#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ + +static const DecodeITableEntry decode_itable[XX_LAST_OPCODE] = { +#include "dectree_generated.h.inc" +}; + +#undef DECODE_MATCH_INFO +#define DECODE_MATCH_INFO(...) DECODE_MATCH_INFO_NULL(__VA_ARGS__) + +#undef DECODE_LEGACY_MATCH_INFO +#define DECODE_LEGACY_MATCH_INFO(...) DECODE_MATCH_INFO_NORMAL(__VA_ARGS__) + +static const DecodeITableEntry decode_legacy_itable[XX_LAST_OPCODE] = { +#include "dectree_generated.h.inc" +}; + +#undef DECODE_OPINFO +#undef DECODE_MATCH_INFO +#undef DECODE_LEGACY_MATCH_INFO +#undef DECODE_END_TABLE +#undef INVALID +#undef TERMINAL +#undef SUBINSNS +#undef EXTSPACE +#undef TABLE_LINK +#undef DECODE_NEW_TABLE +#undef DECODE_SEPARATOR_BITS + +void decode_init(void) +{ + decode_ext_init(); +} + +void decode_send_insn_to(Packet *packet, int start, int newloc) +{ + Insn tmpinsn; + int direction; + int i; + if (start == newloc) { + return; + } + if (start < newloc) { + /* Move towards end */ + direction = 1; + } else { + /* move towards beginning */ + direction = -1; + } + for (i = start; i != newloc; i += direction) { + tmpinsn = packet->insn[i]; + packet->insn[i] = packet->insn[i + direction]; + packet->insn[i + direction] = tmpinsn; + } +} + +/* Fill newvalue registers with the correct regno */ +static void +decode_fill_newvalue_regno(Packet *packet) +{ + int i, use_regidx, offset, def_idx, dst_idx; + uint16_t def_opcode, use_opcode; + char *dststr; + + for (i = 1; i < packet->num_insns; i++) { + if (GET_ATTRIB(packet->insn[i].opcode, A_DOTNEWVALUE) && + !GET_ATTRIB(packet->insn[i].opcode, A_EXTENSION)) { + use_opcode = packet->insn[i].opcode; + + /* It's a store, so we're adjusting the Nt field */ + if (GET_ATTRIB(use_opcode, A_STORE)) { + use_regidx = strchr(opcode_reginfo[use_opcode], 't') - + opcode_reginfo[use_opcode]; + } else { /* It's a Jump, so we're adjusting the Ns field */ + use_regidx = strchr(opcode_reginfo[use_opcode], 's') - + opcode_reginfo[use_opcode]; + } + + /* + * What's encoded at the N-field is the offset to who's producing + * the value. Shift off the LSB which indicates odd/even register, + * then walk backwards and skip over the constant extenders. + */ + offset = packet->insn[i].regno[use_regidx] >> 1; + def_idx = i - offset; + for (int j = 0; j < offset; j++) { + if (GET_ATTRIB(packet->insn[i - j - 1].opcode, A_IT_EXTENDER)) { + def_idx--; + } + } + + /* + * Check for a badly encoded N-field which points to an instruction + * out-of-range + */ + g_assert(!((def_idx < 0) || (def_idx > (packet->num_insns - 1)))); + + /* + * packet->insn[def_idx] is the producer + * Figure out which type of destination it produces + * and the corresponding index in the reginfo + */ + def_opcode = packet->insn[def_idx].opcode; + dststr = strstr(opcode_wregs[def_opcode], "Rd"); + if (dststr) { + dststr = strchr(opcode_reginfo[def_opcode], 'd'); + } else { + dststr = strstr(opcode_wregs[def_opcode], "Rx"); + if (dststr) { + dststr = strchr(opcode_reginfo[def_opcode], 'x'); + } else { + dststr = strstr(opcode_wregs[def_opcode], "Re"); + if (dststr) { + dststr = strchr(opcode_reginfo[def_opcode], 'e'); + } else { + dststr = strstr(opcode_wregs[def_opcode], "Ry"); + if (dststr) { + dststr = strchr(opcode_reginfo[def_opcode], 'y'); + } else { + g_assert_not_reached(); + } + } + } + } + g_assert(dststr != NULL); + + /* Now patch up the consumer with the register number */ + dst_idx = dststr - opcode_reginfo[def_opcode]; + packet->insn[i].regno[use_regidx] = + packet->insn[def_idx].regno[dst_idx]; + /* + * We need to remember who produces this value to later + * check if it was dynamically cancelled + */ + packet->insn[i].new_value_producer_slot = + packet->insn[def_idx].slot; + } + } +} + +/* Split CJ into a compare and a jump */ +static void decode_split_cmpjump(Packet *pkt) +{ + int last, i; + int numinsns = pkt->num_insns; + + /* + * First, split all compare-jumps. + * The compare is sent to the end as a new instruction. + * Do it this way so we don't reorder dual jumps. Those need to stay in + * original order. + */ + for (i = 0; i < numinsns; i++) { + /* It's a cmp-jump */ + if (GET_ATTRIB(pkt->insn[i].opcode, A_NEWCMPJUMP)) { + last = pkt->num_insns; + pkt->insn[last] = pkt->insn[i]; /* copy the instruction */ + pkt->insn[last].part1 = 1; /* last instruction does the CMP */ + pkt->insn[i].part1 = 0; /* existing instruction does the JUMP */ + pkt->num_insns++; + } + } + + /* Now re-shuffle all the compares back to the beginning */ + for (i = 0; i < pkt->num_insns; i++) { + if (pkt->insn[i].part1) { + decode_send_insn_to(pkt, i, 0); + } + } +} + +static inline int decode_opcode_can_jump(int opcode) +{ + if ((GET_ATTRIB(opcode, A_JUMP)) || + (GET_ATTRIB(opcode, A_CALL)) || + (opcode == J2_trap0) || + (opcode == J2_pause)) { + /* Exception to A_JUMP attribute */ + if (opcode == J4_hintjumpr) { + return 0; + } + return 1; + } + + return 0; +} + +static inline int decode_opcode_ends_loop(int opcode) +{ + return GET_ATTRIB(opcode, A_HWLOOP0_END) || + GET_ATTRIB(opcode, A_HWLOOP1_END); +} + +/* Set the is_* fields in each instruction */ +static void decode_set_insn_attr_fields(Packet *pkt) +{ + int i; + int numinsns = pkt->num_insns; + uint16_t opcode; + + pkt->pkt_has_cof = 0; + pkt->pkt_has_endloop = 0; + pkt->pkt_has_dczeroa = 0; + + for (i = 0; i < numinsns; i++) { + opcode = pkt->insn[i].opcode; + if (pkt->insn[i].part1) { + continue; /* Skip compare of cmp-jumps */ + } + + if (GET_ATTRIB(opcode, A_DCZEROA)) { + pkt->pkt_has_dczeroa = 1; + } + + if (GET_ATTRIB(opcode, A_STORE)) { + if (pkt->insn[i].slot == 0) { + pkt->pkt_has_store_s0 = 1; + } else { + pkt->pkt_has_store_s1 = 1; + } + } + + pkt->pkt_has_cof |= decode_opcode_can_jump(opcode); + + pkt->insn[i].is_endloop = decode_opcode_ends_loop(opcode); + + pkt->pkt_has_endloop |= pkt->insn[i].is_endloop; + + pkt->pkt_has_cof |= pkt->pkt_has_endloop; + } +} + +/* + * Shuffle for execution + * Move stores to end (in same order as encoding) + * Move compares to beginning (for use by .new insns) + */ +static void decode_shuffle_for_execution(Packet *packet) +{ + int changed = 0; + int i; + int flag; /* flag means we've seen a non-memory instruction */ + int n_mems; + int last_insn = packet->num_insns - 1; + + /* + * Skip end loops, somehow an end loop is getting in and messing + * up the order + */ + if (decode_opcode_ends_loop(packet->insn[last_insn].opcode)) { + last_insn--; + } + + do { + changed = 0; + /* + * Stores go last, must not reorder. + * Cannot shuffle stores past loads, either. + * Iterate backwards. If we see a non-memory instruction, + * then a store, shuffle the store to the front. Don't shuffle + * stores wrt each other or a load. + */ + for (flag = n_mems = 0, i = last_insn; i >= 0; i--) { + int opcode = packet->insn[i].opcode; + + if (flag && GET_ATTRIB(opcode, A_STORE)) { + decode_send_insn_to(packet, i, last_insn - n_mems); + n_mems++; + changed = 1; + } else if (GET_ATTRIB(opcode, A_STORE)) { + n_mems++; + } else if (GET_ATTRIB(opcode, A_LOAD)) { + /* + * Don't set flag, since we don't want to shuffle a + * store past a load + */ + n_mems++; + } else if (GET_ATTRIB(opcode, A_DOTNEWVALUE)) { + /* + * Don't set flag, since we don't want to shuffle past + * a .new value + */ + } else { + flag = 1; + } + } + + if (changed) { + continue; + } + /* Compares go first, may be reordered wrt each other */ + for (flag = 0, i = 0; i < last_insn + 1; i++) { + int opcode = packet->insn[i].opcode; + + if ((strstr(opcode_wregs[opcode], "Pd4") || + strstr(opcode_wregs[opcode], "Pe4")) && + GET_ATTRIB(opcode, A_STORE) == 0) { + /* This should be a compare (not a store conditional) */ + if (flag) { + decode_send_insn_to(packet, i, 0); + changed = 1; + continue; + } + } else if (GET_ATTRIB(opcode, A_IMPLICIT_WRITES_P3) && + !decode_opcode_ends_loop(packet->insn[i].opcode)) { + /* + * spNloop instruction + * Don't reorder endloops; they are not valid for .new uses, + * and we want to match HW + */ + if (flag) { + decode_send_insn_to(packet, i, 0); + changed = 1; + continue; + } + } else if (GET_ATTRIB(opcode, A_IMPLICIT_WRITES_P0) && + !GET_ATTRIB(opcode, A_NEWCMPJUMP)) { + if (flag) { + decode_send_insn_to(packet, i, 0); + changed = 1; + continue; + } + } else { + flag = 1; + } + } + if (changed) { + continue; + } + } while (changed); + + /* + * If we have a .new register compare/branch, move that to the very + * very end, past stores + */ + for (i = 0; i < last_insn; i++) { + if (GET_ATTRIB(packet->insn[i].opcode, A_DOTNEWVALUE)) { + decode_send_insn_to(packet, i, last_insn); + break; + } + } +} + +static void +apply_extender(Packet *pkt, int i, uint32_t extender) +{ + int immed_num; + uint32_t base_immed; + + immed_num = opcode_which_immediate_is_extended(pkt->insn[i].opcode); + base_immed = pkt->insn[i].immed[immed_num]; + + pkt->insn[i].immed[immed_num] = extender | fZXTN(6, 32, base_immed); +} + +static void decode_apply_extenders(Packet *packet) +{ + int i; + for (i = 0; i < packet->num_insns; i++) { + if (GET_ATTRIB(packet->insn[i].opcode, A_IT_EXTENDER)) { + packet->insn[i + 1].extension_valid = 1; + apply_extender(packet, i + 1, packet->insn[i].immed[0]); + } + } +} + +static void decode_remove_extenders(Packet *packet) +{ + int i, j; + for (i = 0; i < packet->num_insns; i++) { + if (GET_ATTRIB(packet->insn[i].opcode, A_IT_EXTENDER)) { + /* Remove this one by moving the remaining instructions down */ + for (j = i; + (j < packet->num_insns - 1) && (j < INSTRUCTIONS_MAX - 1); + j++) { + packet->insn[j] = packet->insn[j + 1]; + } + packet->num_insns--; + } + } +} + +static SlotMask get_valid_slots(const Packet *pkt, unsigned int slot) +{ + return find_iclass_slots(pkt->insn[slot].opcode, + pkt->insn[slot].iclass); +} + +#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) /* NOTHING */ +#define TABLE_LINK(TABLE) /* NOTHING */ +#define TERMINAL(TAG, ENC) /* NOTHING */ +#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) /* NOTHING */ +#define EXTSPACE(TAG, ENC) /* NOTHING */ +#define INVALID() /* NOTHING */ +#define DECODE_END_TABLE(...) /* NOTHING */ +#define DECODE_MATCH_INFO(...) /* NOTHING */ +#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ + +#define DECODE_REG(REGNO, WIDTH, STARTBIT) \ + insn->regno[REGNO] = ((encoding >> STARTBIT) & ((1 << WIDTH) - 1)); + +#define DECODE_IMPL_REG(REGNO, VAL) \ + insn->regno[REGNO] = VAL; + +#define DECODE_IMM(IMMNO, WIDTH, STARTBIT, VALSTART) \ + insn->immed[IMMNO] |= (((encoding >> STARTBIT) & ((1 << WIDTH) - 1))) << \ + (VALSTART); + +#define DECODE_IMM_SXT(IMMNO, WIDTH) \ + insn->immed[IMMNO] = ((((int32_t)insn->immed[IMMNO]) << (32 - WIDTH)) >> \ + (32 - WIDTH)); + +#define DECODE_IMM_NEG(IMMNO, WIDTH) \ + insn->immed[IMMNO] = -insn->immed[IMMNO]; + +#define DECODE_IMM_SHIFT(IMMNO, SHAMT) \ + if ((!insn->extension_valid) || \ + (insn->which_extended != IMMNO)) { \ + insn->immed[IMMNO] <<= SHAMT; \ + } + +#define DECODE_OPINFO(TAG, BEH) \ + case TAG: \ + { BEH } \ + break; \ + +/* + * Fill in the operands of the instruction + * dectree_generated.h.inc has a DECODE_OPINFO entry for each opcode + * For example, + * DECODE_OPINFO(A2_addi, + * DECODE_REG(0,5,0) + * DECODE_REG(1,5,16) + * DECODE_IMM(0,7,21,9) + * DECODE_IMM(0,9,5,0) + * DECODE_IMM_SXT(0,16) + * with the macros defined above, we'll fill in a switch statement + * where each case is an opcode tag. + */ +static void +decode_op(Insn *insn, Opcode tag, uint32_t encoding) +{ + insn->immed[0] = 0; + insn->immed[1] = 0; + insn->opcode = tag; + if (insn->extension_valid) { + insn->which_extended = opcode_which_immediate_is_extended(tag); + } + + switch (tag) { +#include "dectree_generated.h.inc" + default: + break; + } + + insn->generate = opcode_genptr[tag]; + + insn->iclass = iclass_bits(encoding); +} + +#undef DECODE_REG +#undef DECODE_IMPL_REG +#undef DECODE_IMM +#undef DECODE_IMM_SHIFT +#undef DECODE_OPINFO +#undef DECODE_MATCH_INFO +#undef DECODE_LEGACY_MATCH_INFO +#undef DECODE_END_TABLE +#undef INVALID +#undef TERMINAL +#undef SUBINSNS +#undef EXTSPACE +#undef TABLE_LINK +#undef DECODE_NEW_TABLE +#undef DECODE_SEPARATOR_BITS + +static unsigned int +decode_subinsn_tablewalk(Insn *insn, const DectreeTable *table, + uint32_t encoding) +{ + unsigned int i; + Opcode opc; + if (table->lookup_function) { + i = table->lookup_function(table->startbit, table->width, encoding); + } else { + i = extract32(encoding, table->startbit, table->width); + } + if (table->table[i].type == DECTREE_TABLE_LINK) { + return decode_subinsn_tablewalk(insn, table->table[i].table_link, + encoding); + } else if (table->table[i].type == DECTREE_TERMINAL) { + opc = table->table[i].opcode; + if ((encoding & decode_itable[opc].mask) != decode_itable[opc].match) { + return 0; + } + decode_op(insn, opc, encoding); + return 1; + } else { + return 0; + } +} + +static unsigned int get_insn_a(uint32_t encoding) +{ + return extract32(encoding, 0, 13); +} + +static unsigned int get_insn_b(uint32_t encoding) +{ + return extract32(encoding, 16, 13); +} + +static unsigned int +decode_insns_tablewalk(Insn *insn, const DectreeTable *table, + uint32_t encoding) +{ + unsigned int i; + unsigned int a, b; + Opcode opc; + if (table->lookup_function) { + i = table->lookup_function(table->startbit, table->width, encoding); + } else { + i = extract32(encoding, table->startbit, table->width); + } + if (table->table[i].type == DECTREE_TABLE_LINK) { + return decode_insns_tablewalk(insn, table->table[i].table_link, + encoding); + } else if (table->table[i].type == DECTREE_SUBINSNS) { + a = get_insn_a(encoding); + b = get_insn_b(encoding); + b = decode_subinsn_tablewalk(insn, table->table[i].table_link_b, b); + a = decode_subinsn_tablewalk(insn + 1, table->table[i].table_link, a); + if ((a == 0) || (b == 0)) { + return 0; + } + return 2; + } else if (table->table[i].type == DECTREE_TERMINAL) { + opc = table->table[i].opcode; + if ((encoding & decode_itable[opc].mask) != decode_itable[opc].match) { + if ((encoding & decode_legacy_itable[opc].mask) != + decode_legacy_itable[opc].match) { + return 0; + } + } + decode_op(insn, opc, encoding); + return 1; + } else { + return 0; + } +} + +static unsigned int +decode_insns(Insn *insn, uint32_t encoding) +{ + const DectreeTable *table; + if (parse_bits(encoding) != 0) { + /* Start with PP table - 32 bit instructions */ + table = &dectree_table_DECODE_ROOT_32; + } else { + /* start with EE table - duplex instructions */ + table = &dectree_table_DECODE_ROOT_EE; + } + return decode_insns_tablewalk(insn, table, encoding); +} + +static void decode_add_endloop_insn(Insn *insn, int loopnum) +{ + if (loopnum == 10) { + insn->opcode = J2_endloop01; + insn->generate = opcode_genptr[J2_endloop01]; + } else if (loopnum == 1) { + insn->opcode = J2_endloop1; + insn->generate = opcode_genptr[J2_endloop1]; + } else if (loopnum == 0) { + insn->opcode = J2_endloop0; + insn->generate = opcode_genptr[J2_endloop0]; + } else { + g_assert_not_reached(); + } +} + +static inline int decode_parsebits_is_loopend(uint32_t encoding32) +{ + uint32_t bits = parse_bits(encoding32); + return bits == 0x2; +} + +static void +decode_set_slot_number(Packet *pkt) +{ + int slot; + int i; + int hit_mem_insn = 0; + int hit_duplex = 0; + + /* + * The slots are encoded in reverse order + * For each instruction, count down until you find a suitable slot + */ + for (i = 0, slot = 3; i < pkt->num_insns; i++) { + SlotMask valid_slots = get_valid_slots(pkt, i); + + while (!(valid_slots & (1 << slot))) { + slot--; + } + pkt->insn[i].slot = slot; + if (slot) { + /* I've assigned the slot, now decrement it for the next insn */ + slot--; + } + } + + /* Fix the exceptions - mem insns to slot 0,1 */ + for (i = pkt->num_insns - 1; i >= 0; i--) { + /* First memory instruction always goes to slot 0 */ + if ((GET_ATTRIB(pkt->insn[i].opcode, A_MEMLIKE) || + GET_ATTRIB(pkt->insn[i].opcode, A_MEMLIKE_PACKET_RULES)) && + !hit_mem_insn) { + hit_mem_insn = 1; + pkt->insn[i].slot = 0; + continue; + } + + /* Next memory instruction always goes to slot 1 */ + if ((GET_ATTRIB(pkt->insn[i].opcode, A_MEMLIKE) || + GET_ATTRIB(pkt->insn[i].opcode, A_MEMLIKE_PACKET_RULES)) && + hit_mem_insn) { + pkt->insn[i].slot = 1; + } + } + + /* Fix the exceptions - duplex always slot 0,1 */ + for (i = pkt->num_insns - 1; i >= 0; i--) { + /* First subinsn always goes to slot 0 */ + if (GET_ATTRIB(pkt->insn[i].opcode, A_SUBINSN) && !hit_duplex) { + hit_duplex = 1; + pkt->insn[i].slot = 0; + continue; + } + + /* Next subinsn always goes to slot 1 */ + if (GET_ATTRIB(pkt->insn[i].opcode, A_SUBINSN) && hit_duplex) { + pkt->insn[i].slot = 1; + } + } + + /* Fix the exceptions - slot 1 is never empty, always aligns to slot 0 */ + int slot0_found = 0; + int slot1_found = 0; + int slot1_iidx = 0; + for (i = pkt->num_insns - 1; i >= 0; i--) { + /* Is slot0 used? */ + if (pkt->insn[i].slot == 0) { + int is_endloop = (pkt->insn[i].opcode == J2_endloop01); + is_endloop |= (pkt->insn[i].opcode == J2_endloop0); + is_endloop |= (pkt->insn[i].opcode == J2_endloop1); + + /* + * Make sure it's not endloop since, we're overloading + * slot0 for endloop + */ + if (!is_endloop) { + slot0_found = 1; + } + } + /* Is slot1 used? */ + if (pkt->insn[i].slot == 1) { + slot1_found = 1; + slot1_iidx = i; + } + } + /* Is slot0 empty and slot1 used? */ + if ((slot0_found == 0) && (slot1_found == 1)) { + /* Then push it to slot0 */ + pkt->insn[slot1_iidx].slot = 0; + } +} + +/* + * decode_packet + * Decodes packet with given words + * Returns 0 on insufficient words, + * or number of words used on success + */ + +int decode_packet(int max_words, const uint32_t *words, Packet *pkt, + bool disas_only) +{ + int num_insns = 0; + int words_read = 0; + int end_of_packet = 0; + int new_insns = 0; + uint32_t encoding32; + + /* Initialize */ + memset(pkt, 0, sizeof(*pkt)); + /* Try to build packet */ + while (!end_of_packet && (words_read < max_words)) { + encoding32 = words[words_read]; + end_of_packet = is_packet_end(encoding32); + new_insns = decode_insns(&pkt->insn[num_insns], encoding32); + g_assert(new_insns > 0); + /* + * If we saw an extender, mark next word extended so immediate + * decode works + */ + if (pkt->insn[num_insns].opcode == A4_ext) { + pkt->insn[num_insns + 1].extension_valid = 1; + } + num_insns += new_insns; + words_read++; + } + + pkt->num_insns = num_insns; + if (!end_of_packet) { + /* Ran out of words! */ + return 0; + } + pkt->encod_pkt_size_in_bytes = words_read * 4; + + /* + * Check for :endloop in the parse bits + * Section 10.6 of the Programmer's Reference describes the encoding + * The end of hardware loop 0 can be encoded with 2 words + * The end of hardware loop 1 needs 3 words + */ + if ((words_read == 2) && (decode_parsebits_is_loopend(words[0]))) { + decode_add_endloop_insn(&pkt->insn[pkt->num_insns++], 0); + } + if (words_read >= 3) { + uint32_t has_loop0, has_loop1; + has_loop0 = decode_parsebits_is_loopend(words[0]); + has_loop1 = decode_parsebits_is_loopend(words[1]); + if (has_loop0 && has_loop1) { + decode_add_endloop_insn(&pkt->insn[pkt->num_insns++], 10); + } else if (has_loop1) { + decode_add_endloop_insn(&pkt->insn[pkt->num_insns++], 1); + } else if (has_loop0) { + decode_add_endloop_insn(&pkt->insn[pkt->num_insns++], 0); + } + } + + decode_apply_extenders(pkt); + if (!disas_only) { + decode_remove_extenders(pkt); + } + decode_set_slot_number(pkt); + decode_fill_newvalue_regno(pkt); + + if (!disas_only) { + decode_shuffle_for_execution(pkt); + decode_split_cmpjump(pkt); + decode_set_insn_attr_fields(pkt); + } + + return words_read; +} + +/* Used for "-d in_asm" logging */ +int disassemble_hexagon(uint32_t *words, int nwords, bfd_vma pc, + GString *buf) +{ + Packet pkt; + + if (decode_packet(nwords, words, &pkt, true) > 0) { + snprint_a_pkt_disas(buf, &pkt, words, pc); + return pkt.encod_pkt_size_in_bytes; + } else { + g_string_assign(buf, ""); + return 0; + } +} From patchwork Wed Feb 17 23:40:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383938 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3221197jao; Wed, 17 Feb 2021 15:48:23 -0800 (PST) X-Google-Smtp-Source: ABdhPJwtJabpWI+8o6OP8fBcPmO7JZJLjySuXfAKIIMT5hPdhcUROg94iJ5vdd9tMprGmedNuuWp X-Received: by 2002:a25:4f85:: with SMTP id d127mr12540ybb.482.1613605703686; Wed, 17 Feb 2021 15:48:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605703; cv=none; d=google.com; s=arc-20160816; b=DLroB0Oe9GfcdYCvzN9k5m7WL6FgF5aASmmEoxoe3IewW43lF4vALvfl1YrDNCAqwk Qx51qzqz6HrU5AGGYGLNTCUsv6h1hSAr/AYs9ZlhLmGLxvUqnH/SCX+dgCZ4ej27IEBi CSULJBKcog+y3krOKsU0ui1vsqofhVCwliOprg4aJNTF4dr8saaWAl39t8t31q3rjf5s BWk5HKPondPEpYaiH6rIU75UVfRcO+Iz8nmrx9bqu1Ohr5TesUcdWDib0U1PwC2DBZ3M pc1SRr/cOAlePwMbOxrJtCkC3AmZTEOKoHaId6f0Lh72sOBS0Y8tZLsTyCNkyWz8eaW4 yNkQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=m+z7zKbfPSgVE/5d/mcHl+RUaATXirz6IlvqMojiK3Y=; b=HTWV/8rnpMAyvKQd3n6Vv0lPdinDcy3SmUD+3vRDtolylGatEDn3/DU5TWiL56EDq/ GEsAN2qx25ScpW54WTyniSAMrQmVP7qOhgPOX7M+azB+Nav6kMU1SD76TSkd9N9kATAW Q5UDetUaOBIvfosoAeBrIHJ5WU6Oysd8yrErSIYKInq2Vyb5JtHFELv+fEU5NhW2qBZW HILF3buL/+7oc5BFmjP/y0614HK14NlDL7uvembod6WUWXix4kPXeEm3eL3ACtCFqLSD c4oZVjFQdBvfN8F0ohgQAosjzqc0uWNujam+3Sds5U74oipJYVxvsbYv/jadfsUedw6S poFg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Qv+uKsLk; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id m137si3276132ybf.191.2021.02.17.15.48.23 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:48:23 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Qv+uKsLk; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:54052 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWYR-0007tB-4g for patch@linaro.org; Wed, 17 Feb 2021 18:48:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50732) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRL-0000DH-NV for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:03 -0500 Received: from mail-pf1-x434.google.com ([2607:f8b0:4864:20::434]:43146) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRI-0004fg-D2 for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:03 -0500 Received: by mail-pf1-x434.google.com with SMTP id c11so21437pfp.10 for ; Wed, 17 Feb 2021 15:41:00 -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 :mime-version:content-transfer-encoding; bh=m+z7zKbfPSgVE/5d/mcHl+RUaATXirz6IlvqMojiK3Y=; b=Qv+uKsLkJ5Ahnv0ys+VVoqlmuSsEydwMVIYY0FXtvnt0qJPScIN+cqR9Hwv8xnGOww a/STx1fMUv9SvYGSZM4DCrti4q4ouz8gkfhYdSn3Az5Bk3luxapp783gvSXGKllkz41J d0GteNC8Qw5tWV9njnIaCIr2zoCc1RpxmR/k/E0QB+TrzJ6s/Yv/iEAtv0+ozotL4lTm qJ/XfwiMR23VqS1O3L1BZljvhbUo/WfYn30dN0+8kQ6C/I1VfHeqU4aQLHlpwXpzEEq1 /WMNWKTtkpm/7eNtP/lkLzrS5M7tVOVS0ot4nwPGWmfA3wTt1dejJImA7vDEhAitKRnp 06eQ== 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:mime-version:content-transfer-encoding; bh=m+z7zKbfPSgVE/5d/mcHl+RUaATXirz6IlvqMojiK3Y=; b=Xe15U8icPc8+SMgstTLk1d1RxWeBRWHSQRhhBVm47CbQclgWQ1MmPjxUyyASmei2AG 76fWlv3PeawTgU5N3aA5B6OeIL0pvwLhrfU5PZ2gFUySoyoxJI25CM0lxzZMKvRw7YwO tQnvN64j8Ljzh2h+5Uryv1JLzmdnnEqp36BmHJEYxhZxhZSCqMipMfAJQhqAFEicDpOc K+CZstDTcZCwW9+YKna3JZx0XXfjeHn3JuqdMfdUhou7vksyUOadUFHmKVnhlZPUH8/h jiu2Cu1XcNLJA+c3UL2goCQ/Ob6JoOqnVSDoEdkmPupzHkR4VZr8LDZdgWTFJOTdDYGM zy3w== X-Gm-Message-State: AOAM531+IKyXBaCk/omr/13kNsd8xc+POYOnIvK45m1f2s5Q/hylz2Fa m2dIyoBl6btBMSjSxnfJEBrqnvcjtyrHNA== X-Received: by 2002:a05:6a00:2ac:b029:1e9:3cb7:324a with SMTP id q12-20020a056a0002acb02901e93cb7324amr1623242pfs.36.1613605258880; Wed, 17 Feb 2021 15:40:58 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:40:58 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 15/35] Hexagon (target/hexagon) instruction printing Date: Wed, 17 Feb 2021 15:40:03 -0800 Message-Id: <20210217234023.1742406-16-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::434; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x434.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Signed-off-by: Taylor Simpson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-15-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/printinsn.h | 27 +++++++ target/hexagon/printinsn.c | 146 +++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 target/hexagon/printinsn.h create mode 100644 target/hexagon/printinsn.c -- 2.25.1 diff --git a/target/hexagon/printinsn.h b/target/hexagon/printinsn.h new file mode 100644 index 0000000000..2ecd1731d0 --- /dev/null +++ b/target/hexagon/printinsn.h @@ -0,0 +1,27 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_PRINTINSN_H +#define HEXAGON_PRINTINSN_H + +#include "insn.h" + +void snprint_a_pkt_disas(GString *buf, Packet *pkt, uint32_t *words, + target_ulong pc); +void snprint_a_pkt_debug(GString *buf, Packet *pkt); + +#endif diff --git a/target/hexagon/printinsn.c b/target/hexagon/printinsn.c new file mode 100644 index 0000000000..4865cdd133 --- /dev/null +++ b/target/hexagon/printinsn.c @@ -0,0 +1,146 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "attribs.h" +#include "printinsn.h" +#include "insn.h" +#include "reg_fields.h" +#include "internal.h" + +static const char *sreg2str(unsigned int reg) +{ + if (reg < TOTAL_PER_THREAD_REGS) { + return hexagon_regnames[reg]; + } else { + return "???"; + } +} + +static const char *creg2str(unsigned int reg) +{ + return sreg2str(reg + HEX_REG_SA0); +} + +static void snprintinsn(GString *buf, Insn *insn) +{ + switch (insn->opcode) { +#define DEF_VECX_PRINTINFO(TAG, FMT, ...) DEF_PRINTINFO(TAG, FMT, __VA_ARGS__) +#define DEF_PRINTINFO(TAG, FMT, ...) \ + case TAG: \ + g_string_append_printf(buf, FMT, __VA_ARGS__); \ + break; +#include "printinsn_generated.h.inc" +#undef DEF_VECX_PRINTINFO +#undef DEF_PRINTINFO + } +} + +void snprint_a_pkt_disas(GString *buf, Packet *pkt, uint32_t *words, + target_ulong pc) +{ + bool has_endloop0 = false; + bool has_endloop1 = false; + bool has_endloop01 = false; + + for (int i = 0; i < pkt->num_insns; i++) { + if (pkt->insn[i].part1) { + continue; + } + + /* We'll print the endloop's at the end of the packet */ + if (pkt->insn[i].opcode == J2_endloop0) { + has_endloop0 = true; + continue; + } + if (pkt->insn[i].opcode == J2_endloop1) { + has_endloop1 = true; + continue; + } + if (pkt->insn[i].opcode == J2_endloop01) { + has_endloop01 = true; + continue; + } + + g_string_append_printf(buf, "0x" TARGET_FMT_lx "\t", words[i]); + + if (i == 0) { + g_string_append(buf, "{"); + } + + g_string_append(buf, "\t"); + snprintinsn(buf, &(pkt->insn[i])); + + if (i < pkt->num_insns - 1) { + /* + * Subinstructions are two instructions encoded + * in the same word. Print them on the same line. + */ + if (GET_ATTRIB(pkt->insn[i].opcode, A_SUBINSN)) { + g_string_append(buf, "; "); + snprintinsn(buf, &(pkt->insn[i + 1])); + i++; + } else if (pkt->insn[i + 1].opcode != J2_endloop0 && + pkt->insn[i + 1].opcode != J2_endloop1 && + pkt->insn[i + 1].opcode != J2_endloop01) { + pc += 4; + g_string_append_printf(buf, "\n0x" TARGET_FMT_lx ": ", pc); + } + } + } + g_string_append(buf, " }"); + if (has_endloop0) { + g_string_append(buf, " :endloop0"); + } + if (has_endloop1) { + g_string_append(buf, " :endloop1"); + } + if (has_endloop01) { + g_string_append(buf, " :endloop01"); + } +} + +void snprint_a_pkt_debug(GString *buf, Packet *pkt) +{ + int slot, opcode; + + if (pkt->num_insns > 1) { + g_string_append(buf, "\n{\n"); + } + + for (int i = 0; i < pkt->num_insns; i++) { + if (pkt->insn[i].part1) { + continue; + } + g_string_append(buf, "\t"); + snprintinsn(buf, &(pkt->insn[i])); + + if (GET_ATTRIB(pkt->insn[i].opcode, A_SUBINSN)) { + g_string_append(buf, " //subinsn"); + } + if (pkt->insn[i].extension_valid) { + g_string_append(buf, " //constant extended"); + } + slot = pkt->insn[i].slot; + opcode = pkt->insn[i].opcode; + g_string_append_printf(buf, " //slot=%d:tag=%s\n", + slot, opcode_names[opcode]); + } + if (pkt->num_insns > 1) { + g_string_append(buf, "}\n"); + } +} From patchwork Wed Feb 17 23:40:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384180 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3225910jao; Wed, 17 Feb 2021 15:57:41 -0800 (PST) X-Google-Smtp-Source: ABdhPJzb1H357Jz1zBqbyrtSE6GecUlphK+UtwIgkZT6ejIOMQfJRICquMMeh99e10zm5Mk73ZV4 X-Received: by 2002:a25:41c2:: with SMTP id o185mr3116226yba.83.1613606261354; Wed, 17 Feb 2021 15:57:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606261; cv=none; d=google.com; s=arc-20160816; b=bkqHNjI8WroZSdrwOBQPNsDJHga2XGK8wcKHDg3QknybnXznC5nKf0D9NjBoX/vNTL M3UqXdhEjxHNi/Np0A8zhgHEuZB7d0+xKYZ4IK+MY5ISCbfBPWeJD0scu8bzwxGnP7mg 1c7Q04/oHIiuyQJn3zpUDU6E9KblKkiQumtxPulDKSk3yCtTByUIEAzDkYirFQG7GvAM 9zaYCM/nqb947Os7SftNaDWHeNWzpHDUCQ3c/baVtZYu4gCfQn/vdgOfDXCAMbOowLmu 57tf2DTlATWxLNuaa7v1DHPyo5nGICCFL7kFVKbTljh0y8XVHja/2VZnD3aAwHoDpNdP V9LA== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=djrIDKwpqXpESsxZegRWeJHdpQe7kKeeT84+hbZKTlI=; b=vqnyV6Ig1wyeY9oRw39CyAGf6ySQKoXdOsZYuWGFBPoPmDvb8eebpRhY42rotmCdBU myHVgzcjw5Cwx10fE20XrzDMZzvsL+5We2v1Nh4ZfHqj8wb8jnWMnI+y6tQVR4GjjRM4 4Od5esY5YdCp47sL2FX4QPTypyWowqL8hMFbitbfBlg9rBpZDIGn2P6wcmHIy4yHtiIU D9dniX4vvby6RHabETJ7Q1UKEoRQnTdB4X32ReXGc4qi8cpbRIuVFPKSWqBBYzItpmmg gTJ05Rg9+npVbxc+mw+pz8DXR0QaLnTh3sxZw0wW0yJ6zuZg4FvHjI6l7vdYVHAVg2fZ GaeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KJ1SuDCw; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id a188si3482328ybg.248.2021.02.17.15.57.41 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:57:41 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KJ1SuDCw; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:55256 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWhQ-0003at-Ox for patch@linaro.org; Wed, 17 Feb 2021 18:57:40 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50772) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRN-0000GZ-36 for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:05 -0500 Received: from mail-pg1-x52a.google.com ([2607:f8b0:4864:20::52a]:38643) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRK-0004gN-9n for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:04 -0500 Received: by mail-pg1-x52a.google.com with SMTP id m2so9525523pgq.5 for ; Wed, 17 Feb 2021 15:41:01 -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 :mime-version:content-transfer-encoding; bh=djrIDKwpqXpESsxZegRWeJHdpQe7kKeeT84+hbZKTlI=; b=KJ1SuDCwjVyJohsvnZsXGAwKd0ehgpK0S20R6sQXqaXK85GFph6U38S8y/UW/+JUde sFf8qw7Od+FIzpE9GLeCXoibVnhluuKw8Vq7Yp6Q24R4fLPdL7vzmoUnKJUxHnhnOVzv 49kL1wP3TPr7oAC9VsTn5pdvGVVZ3/itY8WJVhRS0yJgMT0CCEvBDBD8zkl2Lg8PArWK RriCpUeNeRAdq8jClt9l5N3R0D0I3aByBW7AJFlHZRQ+fon+eEcOOf/ZgkwwyLKLGjFc 41d0FPN+hh0e99N89WJnFSCfMLp2/hK7mljgTsBhOPBG+xoPqilLmspIVs/Yx69WSsiH L2Lg== 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:mime-version:content-transfer-encoding; bh=djrIDKwpqXpESsxZegRWeJHdpQe7kKeeT84+hbZKTlI=; b=H1TthYcezrSk/M/XFFnmNBKFF5QxMltIKWjSxWrb96+5mUCU45Z8FSQO0hU9VF3hNu UEFES+aa+ZNx2MGAkI53zC+z6AtjPunTB+diQkwruWTWbpTqb2HNayjy7ChP8SFwBL+t 3EG4xNRQOCi+MGVOBDAcHM2JmXesIpumNq2o7wubO+H7T1aguGA4Yg97zjpDQAu/H2cp LBBu4NUUy4DB90aeP7uQRBgCqYmbDqOZSYvYLZoHyJpuchxAEkEPFA6TtwpIrQ0qj9L9 CZNFmRucdk8ECpEIAqYgThwdeiC9DhW4pwp7EaG0VzVWmz0pCuScfWXKJPJhQBgN8/EM KpHw== X-Gm-Message-State: AOAM531btZVyxzb5M7WMmhYhkKDeFRhIQexd7IMPl2vIq6kY1gbIZFFO Nf6W5SKLX3xHwBZ2lLP4wIfnwZWPRIt9UA== X-Received: by 2002:a05:6a00:854:b029:1b7:6233:c5f with SMTP id q20-20020a056a000854b02901b762330c5fmr1542050pfk.73.1613605260670; Wed, 17 Feb 2021 15:41:00 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.40.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:00 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 16/35] Hexagon (target/hexagon/arch.[ch]) utility functions Date: Wed, 17 Feb 2021 15:40:04 -0800 Message-Id: <20210217234023.1742406-17-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52a; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Signed-off-by: Taylor Simpson Message-Id: <1612763186-18161-16-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/arch.h | 34 +++++ target/hexagon/arch.c | 300 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 334 insertions(+) create mode 100644 target/hexagon/arch.h create mode 100644 target/hexagon/arch.c -- 2.25.1 diff --git a/target/hexagon/arch.h b/target/hexagon/arch.h new file mode 100644 index 0000000000..1f7f03693a --- /dev/null +++ b/target/hexagon/arch.h @@ -0,0 +1,34 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_ARCH_H +#define HEXAGON_ARCH_H + +#include "qemu/int128.h" + +uint64_t interleave(uint32_t odd, uint32_t even); +uint64_t deinterleave(uint64_t src); +uint32_t carry_from_add64(uint64_t a, uint64_t b, uint32_t c); +int32_t conv_round(int32_t a, int n); +void arch_fpop_start(CPUHexagonState *env); +void arch_fpop_end(CPUHexagonState *env); +int arch_sf_recip_common(float32 *Rs, float32 *Rt, float32 *Rd, + int *adjust, float_status *fp_status); +int arch_sf_invsqrt_common(float32 *Rs, float32 *Rd, int *adjust, + float_status *fp_status); + +#endif diff --git a/target/hexagon/arch.c b/target/hexagon/arch.c new file mode 100644 index 0000000000..09de124818 --- /dev/null +++ b/target/hexagon/arch.c @@ -0,0 +1,300 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "fpu/softfloat.h" +#include "cpu.h" +#include "fma_emu.h" +#include "arch.h" +#include "macros.h" + +#define SF_BIAS 127 +#define SF_MAXEXP 254 +#define SF_MANTBITS 23 +#define float32_nan make_float32(0xffffffff) + +#define BITS_MASK_8 0x5555555555555555ULL +#define PAIR_MASK_8 0x3333333333333333ULL +#define NYBL_MASK_8 0x0f0f0f0f0f0f0f0fULL +#define BYTE_MASK_8 0x00ff00ff00ff00ffULL +#define HALF_MASK_8 0x0000ffff0000ffffULL +#define WORD_MASK_8 0x00000000ffffffffULL + +uint64_t interleave(uint32_t odd, uint32_t even) +{ + /* Convert to long long */ + uint64_t myodd = odd; + uint64_t myeven = even; + /* First, spread bits out */ + myodd = (myodd | (myodd << 16)) & HALF_MASK_8; + myeven = (myeven | (myeven << 16)) & HALF_MASK_8; + myodd = (myodd | (myodd << 8)) & BYTE_MASK_8; + myeven = (myeven | (myeven << 8)) & BYTE_MASK_8; + myodd = (myodd | (myodd << 4)) & NYBL_MASK_8; + myeven = (myeven | (myeven << 4)) & NYBL_MASK_8; + myodd = (myodd | (myodd << 2)) & PAIR_MASK_8; + myeven = (myeven | (myeven << 2)) & PAIR_MASK_8; + myodd = (myodd | (myodd << 1)) & BITS_MASK_8; + myeven = (myeven | (myeven << 1)) & BITS_MASK_8; + /* Now OR together */ + return myeven | (myodd << 1); +} + +uint64_t deinterleave(uint64_t src) +{ + /* Get odd and even bits */ + uint64_t myodd = ((src >> 1) & BITS_MASK_8); + uint64_t myeven = (src & BITS_MASK_8); + + /* Unspread bits */ + myeven = (myeven | (myeven >> 1)) & PAIR_MASK_8; + myodd = (myodd | (myodd >> 1)) & PAIR_MASK_8; + myeven = (myeven | (myeven >> 2)) & NYBL_MASK_8; + myodd = (myodd | (myodd >> 2)) & NYBL_MASK_8; + myeven = (myeven | (myeven >> 4)) & BYTE_MASK_8; + myodd = (myodd | (myodd >> 4)) & BYTE_MASK_8; + myeven = (myeven | (myeven >> 8)) & HALF_MASK_8; + myodd = (myodd | (myodd >> 8)) & HALF_MASK_8; + myeven = (myeven | (myeven >> 16)) & WORD_MASK_8; + myodd = (myodd | (myodd >> 16)) & WORD_MASK_8; + + /* Return odd bits in upper half */ + return myeven | (myodd << 32); +} + +uint32_t carry_from_add64(uint64_t a, uint64_t b, uint32_t c) +{ + uint64_t tmpa, tmpb, tmpc; + tmpa = fGETUWORD(0, a); + tmpb = fGETUWORD(0, b); + tmpc = tmpa + tmpb + c; + tmpa = fGETUWORD(1, a); + tmpb = fGETUWORD(1, b); + tmpc = tmpa + tmpb + fGETUWORD(1, tmpc); + tmpc = fGETUWORD(1, tmpc); + return tmpc; +} + +int32_t conv_round(int32_t a, int n) +{ + int64_t val; + + if (n == 0) { + val = a; + } else if ((a & ((1 << (n - 1)) - 1)) == 0) { /* N-1..0 all zero? */ + /* Add LSB from int part */ + val = ((fSE32_64(a)) + (int64_t) (((uint32_t) ((1 << n) & a)) >> 1)); + } else { + val = ((fSE32_64(a)) + (1 << (n - 1))); + } + + val = val >> n; + return (int32_t)val; +} + +/* Floating Point Stuff */ + +static const int softfloat_roundingmodes[] = { + float_round_nearest_even, + float_round_to_zero, + float_round_down, + float_round_up, +}; + +void arch_fpop_start(CPUHexagonState *env) +{ + set_float_exception_flags(0, &env->fp_status); + set_float_rounding_mode( + softfloat_roundingmodes[fREAD_REG_FIELD(USR, USR_FPRND)], + &env->fp_status); +} + +#ifdef CONFIG_USER_ONLY +/* + * Hexagon Linux kernel only sets the relevant bits in USR (user status + * register). The exception isn't raised to user mode, so we don't + * model it in qemu user mode. + */ +#define RAISE_FP_EXCEPTION do {} while (0) +#endif + +#define SOFTFLOAT_TEST_FLAG(FLAG, MYF, MYE) \ + do { \ + if (flags & FLAG) { \ + if (GET_USR_FIELD(USR_##MYF) == 0) { \ + SET_USR_FIELD(USR_##MYF, 1); \ + if (GET_USR_FIELD(USR_##MYE)) { \ + RAISE_FP_EXCEPTION; \ + } \ + } \ + } \ + } while (0) + +void arch_fpop_end(CPUHexagonState *env) +{ + int flags = get_float_exception_flags(&env->fp_status); + if (flags != 0) { + SOFTFLOAT_TEST_FLAG(float_flag_inexact, FPINPF, FPINPE); + SOFTFLOAT_TEST_FLAG(float_flag_divbyzero, FPDBZF, FPDBZE); + SOFTFLOAT_TEST_FLAG(float_flag_invalid, FPINVF, FPINVE); + SOFTFLOAT_TEST_FLAG(float_flag_overflow, FPOVFF, FPOVFE); + SOFTFLOAT_TEST_FLAG(float_flag_underflow, FPUNFF, FPUNFE); + } +} + +static float32 float32_mul_pow2(float32 a, uint32_t p, float_status *fp_status) +{ + float32 b = make_float32((SF_BIAS + p) << SF_MANTBITS); + return float32_mul(a, b, fp_status); +} + +int arch_sf_recip_common(float32 *Rs, float32 *Rt, float32 *Rd, int *adjust, + float_status *fp_status) +{ + int n_exp; + int d_exp; + int ret = 0; + float32 RsV, RtV, RdV; + int PeV = 0; + RsV = *Rs; + RtV = *Rt; + if (float32_is_any_nan(RsV) && float32_is_any_nan(RtV)) { + if (extract32(RsV & RtV, 22, 1) == 0) { + float_raise(float_flag_invalid, fp_status); + } + RdV = RsV = RtV = float32_nan; + } else if (float32_is_any_nan(RsV)) { + if (extract32(RsV, 22, 1) == 0) { + float_raise(float_flag_invalid, fp_status); + } + RdV = RsV = RtV = float32_nan; + } else if (float32_is_any_nan(RtV)) { + /* or put NaN in num/den fixup? */ + if (extract32(RtV, 22, 1) == 0) { + float_raise(float_flag_invalid, fp_status); + } + RdV = RsV = RtV = float32_nan; + } else if (float32_is_infinity(RsV) && float32_is_infinity(RtV)) { + /* or put Inf in num fixup? */ + RdV = RsV = RtV = float32_nan; + float_raise(float_flag_invalid, fp_status); + } else if (float32_is_zero(RsV) && float32_is_zero(RtV)) { + /* or put zero in num fixup? */ + RdV = RsV = RtV = float32_nan; + float_raise(float_flag_invalid, fp_status); + } else if (float32_is_zero(RtV)) { + /* or put Inf in num fixup? */ + uint8_t RsV_sign = float32_is_neg(RsV); + uint8_t RtV_sign = float32_is_neg(RtV); + RsV = infinite_float32(RsV_sign ^ RtV_sign); + RtV = float32_one; + RdV = float32_one; + if (float32_is_infinity(RsV)) { + float_raise(float_flag_divbyzero, fp_status); + } + } else if (float32_is_infinity(RtV)) { + RsV = make_float32(0x80000000 & (RsV ^ RtV)); + RtV = float32_one; + RdV = float32_one; + } else if (float32_is_zero(RsV)) { + /* Does this just work itself out? */ + /* No, 0/Inf causes problems. */ + RsV = make_float32(0x80000000 & (RsV ^ RtV)); + RtV = float32_one; + RdV = float32_one; + } else if (float32_is_infinity(RsV)) { + uint8_t RsV_sign = float32_is_neg(RsV); + uint8_t RtV_sign = float32_is_neg(RtV); + RsV = infinite_float32(RsV_sign ^ RtV_sign); + RtV = float32_one; + RdV = float32_one; + } else { + PeV = 0x00; + /* Basic checks passed */ + n_exp = float32_getexp(RsV); + d_exp = float32_getexp(RtV); + if ((n_exp - d_exp + SF_BIAS) <= SF_MANTBITS) { + /* Near quotient underflow / inexact Q */ + PeV = 0x80; + RtV = float32_mul_pow2(RtV, -64, fp_status); + RsV = float32_mul_pow2(RsV, 64, fp_status); + } else if ((n_exp - d_exp + SF_BIAS) > (SF_MAXEXP - 24)) { + /* Near quotient overflow */ + PeV = 0x40; + RtV = float32_mul_pow2(RtV, 32, fp_status); + RsV = float32_mul_pow2(RsV, -32, fp_status); + } else if (n_exp <= SF_MANTBITS + 2) { + RtV = float32_mul_pow2(RtV, 64, fp_status); + RsV = float32_mul_pow2(RsV, 64, fp_status); + } else if (d_exp <= 1) { + RtV = float32_mul_pow2(RtV, 32, fp_status); + RsV = float32_mul_pow2(RsV, 32, fp_status); + } else if (d_exp > 252) { + RtV = float32_mul_pow2(RtV, -32, fp_status); + RsV = float32_mul_pow2(RsV, -32, fp_status); + } + RdV = 0; + ret = 1; + } + *Rs = RsV; + *Rt = RtV; + *Rd = RdV; + *adjust = PeV; + return ret; +} + +int arch_sf_invsqrt_common(float32 *Rs, float32 *Rd, int *adjust, + float_status *fp_status) +{ + float32 RsV, RdV; + int PeV = 0; + int r_exp; + int ret = 0; + RsV = *Rs; + if (float32_is_infinity(RsV)) { + if (extract32(RsV, 22, 1) == 0) { + float_raise(float_flag_invalid, fp_status); + } + RdV = RsV = float32_nan; + } else if (float32_lt(RsV, float32_zero, fp_status)) { + /* Negative nonzero values are NaN */ + float_raise(float_flag_invalid, fp_status); + RsV = float32_nan; + RdV = float32_nan; + } else if (float32_is_infinity(RsV)) { + /* or put Inf in num fixup? */ + RsV = infinite_float32(1); + RdV = infinite_float32(1); + } else if (float32_is_zero(RsV)) { + /* or put zero in num fixup? */ + RdV = float32_one; + } else { + PeV = 0x00; + /* Basic checks passed */ + r_exp = float32_getexp(RsV); + if (r_exp <= 24) { + RsV = float32_mul_pow2(RsV, 64, fp_status); + PeV = 0xe0; + } + RdV = 0; + ret = 1; + } + *Rs = RsV; + *Rd = RdV; + *adjust = PeV; + return ret; +} From patchwork Wed Feb 17 23:40:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384011 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3222210jao; Wed, 17 Feb 2021 15:50:26 -0800 (PST) X-Google-Smtp-Source: ABdhPJy+All9CD7OS3XVRlsyLf53WRbAIyKz30/aLYl4faww4FAnGMlzCZp1/1xkeK5d3Doc/KfX X-Received: by 2002:a25:d4d0:: with SMTP id m199mr3054190ybf.26.1613605826065; Wed, 17 Feb 2021 15:50:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605826; cv=none; d=google.com; s=arc-20160816; b=h+ec02atMqzfIYJLum/WU1dlSebYMAhs6W51kV7OXCPFKoYFqyYMFZhtp+EDs+/Wnp WeSnRG6cJHXQsXxEe9DEKPhscrbiGgyh4Oo99AUu12IEI/LH37sm3l0tX32Hvhaf8ypZ 82jsKgdD7a//66wM+esIfQIrixn7HyYMROJQ1QOmyLZBmK0N+W2DhqlpTQ+8UIGKHFXO OClt7t8fZ8LG3BmNqNBVpgF0PD8tQZS37/IxVfuJbEXIybedTX90Mtx7ceK23aA91lI/ XKFQK305MLeW43dhH46vTL6ZFWfRimGdee2b5mgvxPzHJBRaDPbIi/lhSmQ87IMujPDD FwkQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=nKMqug/uvk4wMgHy5mH79wL6sqcjbk2He0GvstqA04M=; b=Ub9bcH5KFIS3lZM1hwyfudIWYwwJufAASme3aFaxOrkZvrKZa0ZVNJOvlZHGfbzsML sNnQIQ5NPpHwsGX1EdQIAzXk9xqUGDQeJZymE17IMui1H1+qPeEpclj6AmQqroy2m6To +SmSjZ9l7QX/Prss/dwyiIp+LK4jhsEypmezGIAIaaASMPSmi13nQMMO+dRwEooF31mG Wh9pugphb/mUsIUGUG0FDworeHan2FIoB3iqBhi6OzojnBn4gHav0uZzhLsL4QePPOVM L4SiFHS6B6kk8mWANPm3LIe46wbkfPaC34KS3NKGo7oDtRBIYPjAD9VqXOQdqlwJwem3 orng== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dL6YCej4; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id b12si816212ybm.165.2021.02.17.15.50.25 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:50:26 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dL6YCej4; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:34194 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWaP-0002x0-HG for patch@linaro.org; Wed, 17 Feb 2021 18:50:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50788) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRP-0000Md-Be for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:07 -0500 Received: from mail-pg1-x530.google.com ([2607:f8b0:4864:20::530]:46488) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRM-0004gg-28 for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:06 -0500 Received: by mail-pg1-x530.google.com with SMTP id 75so6129874pgf.13 for ; Wed, 17 Feb 2021 15:41:03 -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 :mime-version:content-transfer-encoding; bh=nKMqug/uvk4wMgHy5mH79wL6sqcjbk2He0GvstqA04M=; b=dL6YCej4rLazl8wNXiSnLDcWaPzPpuCsNbwiQZ3zL12Xt1GBCE7bHsWq1setRHOr/J ODExBTvYB3lPHHeI/cNWe6YAu1MC1THz0wuPM4Yiyyb5v5KlBXSQHvr6uLOXoqj/Cxom haAZu401O93Ds0jss2QfxmvNC35QihNd/Er5DgYXke49vsj6poTI8BXsZuN2TgVnMjq6 t9RZbu7VXua/P3YVRwf7tg29J80M3gy6J5hq+RULTj3nxrIzzs+V41f2vJeKs1jyYD56 Lc7dkfY4GqXfNvVNRhMZZluhfbFt7ZtVPSoRr+T+B7Izo9Vn+tZ6vb+X1xJa+Dvg6QTy 9hRQ== 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:mime-version:content-transfer-encoding; bh=nKMqug/uvk4wMgHy5mH79wL6sqcjbk2He0GvstqA04M=; b=k9zgsrFk+4Lmhqk0jAcuMfL7QaXs3IA4l/3mOXl0f009fLvqxfzkJDObmdE/nEzlh1 O/PJenM5Ra1bBYgy8EpWzfNjxOo6qOQcvGx7TxfBjxNljymQt+3ivA/rWwxbeqtqghxn msqUG4NIl94dWL1+wb9VWeoYG2WOOgG2F3gL5kWhkXtZ4pf4Xod9hLoa1rUQEZ2kaADW zqf9qBAnC95CgncoSCSAwGcgrC4JtJte1cchiW6uRV8h+MSAqBy1Kq+Q4lhNCqj7g9OA tnBUFU+OAvIKvWtQj4ChjfCKWnfY5QEKiMgYgYkEsT/ujVZqfumU3DLqBAh9cEytqa7b iXxg== X-Gm-Message-State: AOAM531bSob4nDJNdGdIGNdBM2GEl6jjucsjb3a6nehjnhnec6InFOga LEU4BdEbEN2wL8sq2smFejticZqfJ62Rtw== X-Received: by 2002:aa7:92d9:0:b029:1bb:b6de:c872 with SMTP id k25-20020aa792d90000b02901bbb6dec872mr1577503pfa.68.1613605262469; Wed, 17 Feb 2021 15:41:02 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:01 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 17/35] Hexagon (target/hexagon/conv_emu.[ch]) utility functions Date: Wed, 17 Feb 2021 15:40:05 -0800 Message-Id: <20210217234023.1742406-18-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::530; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x530.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Signed-off-by: Taylor Simpson Message-Id: <1612763186-18161-17-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/conv_emu.h | 31 +++++++ target/hexagon/conv_emu.c | 177 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 target/hexagon/conv_emu.h create mode 100644 target/hexagon/conv_emu.c -- 2.25.1 diff --git a/target/hexagon/conv_emu.h b/target/hexagon/conv_emu.h new file mode 100644 index 0000000000..cade9de91f --- /dev/null +++ b/target/hexagon/conv_emu.h @@ -0,0 +1,31 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_CONV_EMU_H +#define HEXAGON_CONV_EMU_H + +uint64_t conv_sf_to_8u(float32 in, float_status *fp_status); +uint32_t conv_sf_to_4u(float32 in, float_status *fp_status); +int64_t conv_sf_to_8s(float32 in, float_status *fp_status); +int32_t conv_sf_to_4s(float32 in, float_status *fp_status); + +uint64_t conv_df_to_8u(float64 in, float_status *fp_status); +uint32_t conv_df_to_4u(float64 in, float_status *fp_status); +int64_t conv_df_to_8s(float64 in, float_status *fp_status); +int32_t conv_df_to_4s(float64 in, float_status *fp_status); + +#endif diff --git a/target/hexagon/conv_emu.c b/target/hexagon/conv_emu.c new file mode 100644 index 0000000000..3985b1032a --- /dev/null +++ b/target/hexagon/conv_emu.c @@ -0,0 +1,177 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/host-utils.h" +#include "fpu/softfloat.h" +#include "macros.h" +#include "conv_emu.h" + +#define LL_MAX_POS 0x7fffffffffffffffULL +#define MAX_POS 0x7fffffffU + +static uint64_t conv_f64_to_8u_n(float64 in, int will_negate, + float_status *fp_status) +{ + uint8_t sign = float64_is_neg(in); + if (float64_is_infinity(in)) { + float_raise(float_flag_invalid, fp_status); + if (float64_is_neg(in)) { + return 0ULL; + } else { + return ~0ULL; + } + } + if (float64_is_any_nan(in)) { + float_raise(float_flag_invalid, fp_status); + return ~0ULL; + } + if (float64_is_zero(in)) { + return 0; + } + if (sign) { + float_raise(float_flag_invalid, fp_status); + return 0; + } + if (float64_lt(in, float64_half, fp_status)) { + /* Near zero, captures large fracshifts, denorms, etc */ + float_raise(float_flag_inexact, fp_status); + switch (get_float_rounding_mode(fp_status)) { + case float_round_down: + if (will_negate) { + return 1; + } else { + return 0; + } + case float_round_up: + if (!will_negate) { + return 1; + } else { + return 0; + } + default: + return 0; /* nearest or towards zero */ + } + } + return float64_to_uint64(in, fp_status); +} + +static void clr_float_exception_flags(uint8_t flag, float_status *fp_status) +{ + uint8_t flags = fp_status->float_exception_flags; + flags &= ~flag; + set_float_exception_flags(flags, fp_status); +} + +static uint32_t conv_df_to_4u_n(float64 fp64, int will_negate, + float_status *fp_status) +{ + uint64_t tmp; + tmp = conv_f64_to_8u_n(fp64, will_negate, fp_status); + if (tmp > 0x00000000ffffffffULL) { + clr_float_exception_flags(float_flag_inexact, fp_status); + float_raise(float_flag_invalid, fp_status); + return ~0U; + } + return (uint32_t)tmp; +} + +uint64_t conv_df_to_8u(float64 in, float_status *fp_status) +{ + return conv_f64_to_8u_n(in, 0, fp_status); +} + +uint32_t conv_df_to_4u(float64 in, float_status *fp_status) +{ + return conv_df_to_4u_n(in, 0, fp_status); +} + +int64_t conv_df_to_8s(float64 in, float_status *fp_status) +{ + uint8_t sign = float64_is_neg(in); + uint64_t tmp; + if (float64_is_any_nan(in)) { + float_raise(float_flag_invalid, fp_status); + return -1; + } + if (sign) { + float64 minus_fp64 = float64_abs(in); + tmp = conv_f64_to_8u_n(minus_fp64, 1, fp_status); + } else { + tmp = conv_f64_to_8u_n(in, 0, fp_status); + } + if (tmp > (LL_MAX_POS + sign)) { + clr_float_exception_flags(float_flag_inexact, fp_status); + float_raise(float_flag_invalid, fp_status); + tmp = (LL_MAX_POS + sign); + } + if (sign) { + return -tmp; + } else { + return tmp; + } +} + +int32_t conv_df_to_4s(float64 in, float_status *fp_status) +{ + uint8_t sign = float64_is_neg(in); + uint64_t tmp; + if (float64_is_any_nan(in)) { + float_raise(float_flag_invalid, fp_status); + return -1; + } + if (sign) { + float64 minus_fp64 = float64_abs(in); + tmp = conv_f64_to_8u_n(minus_fp64, 1, fp_status); + } else { + tmp = conv_f64_to_8u_n(in, 0, fp_status); + } + if (tmp > (MAX_POS + sign)) { + clr_float_exception_flags(float_flag_inexact, fp_status); + float_raise(float_flag_invalid, fp_status); + tmp = (MAX_POS + sign); + } + if (sign) { + return -tmp; + } else { + return tmp; + } +} + +uint64_t conv_sf_to_8u(float32 in, float_status *fp_status) +{ + float64 fp64 = float32_to_float64(in, fp_status); + return conv_df_to_8u(fp64, fp_status); +} + +uint32_t conv_sf_to_4u(float32 in, float_status *fp_status) +{ + float64 fp64 = float32_to_float64(in, fp_status); + return conv_df_to_4u(fp64, fp_status); +} + +int64_t conv_sf_to_8s(float32 in, float_status *fp_status) +{ + float64 fp64 = float32_to_float64(in, fp_status); + return conv_df_to_8s(fp64, fp_status); +} + +int32_t conv_sf_to_4s(float32 in, float_status *fp_status) +{ + float64 fp64 = float32_to_float64(in, fp_status); + return conv_df_to_4s(fp64, fp_status); +} From patchwork Wed Feb 17 23:40:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384185 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3227143jao; Wed, 17 Feb 2021 16:00:14 -0800 (PST) X-Google-Smtp-Source: ABdhPJyL8VkcgNb6qT2bHMzQexFChB4oZKOaZvSiphvfmavCcpU7a0n/11YemwZcn2krmJdy2Ovy X-Received: by 2002:a25:903:: with SMTP id 3mr2613600ybj.275.1613606414283; Wed, 17 Feb 2021 16:00:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606414; cv=none; d=google.com; s=arc-20160816; b=QzY1UGknsht7GlDJSeeQ1MxhNbgQQW76a08QWCuVM5dr+sHhr3AGsOe7iyb0CDxURs vY7B45rEOjGBHlStv6tHxNUAJC0xr+PPwLSX9cP+kFm4LAEvjPexE2G27NF7OZhJ0v1C p5QCCLgWk1cknN+LuVL3IsqGgxb3aXbBTE+R64h6ETI1tCc0i9kLBF01HIEkXziv3pYG tn1ePMNgG/G5PlGBJWBprWQ05eaB356CgcsW2rSqRIiNrumDYoDjJ6J2ypQ/AmTTeC5R LxZqV2sK3j7u7ZeHCgfjdbnYL0T0YXCQ+MldyHcKDdGwcsdlZmtbyBw24XyAI7Ht0td+ LsoA== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=yxrWuJHCJz8lKt8K8c9u+iIMVOHEkTdiNJKvhZZoVh8=; b=AkLqZnHH8gUl7hDGZGKF5KU1yusoQbDVtdXeOqIjbM6uH8nIvzAE6TJEWB7P7pGstH e3lmuyFO51RepEtAWZS+P0syGdo6a8a2bhO2X96EvGISQOFT9VKKJt/A7HUBG1vWAFbs eaVwVh9GKGk7UIhifN1oqW96Pl5sQQe6t0WF3bO/NgUcCgm67JrFia8CKlep0PObaDoO LXf7kd9bzCbiihbr/Ns+kaZhChT9xKRCHWZwoadsQqQinISsJvYvij9Vk8Yxnmq9qeLn PEPAFHtRd6snzWeB9Oz1IyyBmGL1TOz9oUgkPCTBYQJzpNsH7s6v73iwBOuMqUlXp4jl XFMw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=c1DoOhDj; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id g32si4170346ybe.409.2021.02.17.16.00.14 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 16:00:14 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=c1DoOhDj; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:35700 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWjt-0007IC-Jc for patch@linaro.org; Wed, 17 Feb 2021 19:00:13 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50802) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRR-0000S7-Lj for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:09 -0500 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]:36455) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRO-0004hW-0k for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:09 -0500 Received: by mail-pj1-x1033.google.com with SMTP id gx20so272058pjb.1 for ; Wed, 17 Feb 2021 15:41:05 -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 :mime-version:content-transfer-encoding; bh=yxrWuJHCJz8lKt8K8c9u+iIMVOHEkTdiNJKvhZZoVh8=; b=c1DoOhDjfTeqCq96VavqLEEOOGVoczNwvq4IPFDebMbf2BQyap5oef1SV7T9QpvlUX eqkNr9V2+qFbaoTbX6CuWksaKlAFUgI7Ue0zzXVn2SJJpOKp/PGt1aHHz2uWROsMbrsj NtrVcynMVOeIX/RqJ60wJn7fCZfNPi/E6x94JVn+XarKJAPLNhl0Z0OlK4rpvMDqrjLr sTHMgIe1+DBIS5m9PCtDQubrNp8vB4PZvT48IqXDZUqe63dnNrq6EE6HMHaTBiYKQSpo f/MZlBISwws26bM5/+6SFFsvC02xu9zNuVpquiRqAw5r5Mip3LunLMQpaNtWpoyRsh0C x2kw== 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:mime-version:content-transfer-encoding; bh=yxrWuJHCJz8lKt8K8c9u+iIMVOHEkTdiNJKvhZZoVh8=; b=aCo/pih9VONs6VtcjXJQ74qR4ewafKJ5sfMYUzBusr2xnKhlx7vkzv/tuNt3d3tR63 +Jbhm9sm1KB1FW2utrOFTVqFEmphTLFEK234ATDuPsS+adin/etHQ79yiBzB/AtEtKLc 0npu4MOWoLa6Zrn+ic1uH64cS8Ad4KyuQ3238wSB3p8r9SizQE8Cp6TzptYI5XRi7f8Z iMt4siDV/vy6K7kWa3P1OrhekTbnMij9l5WYcoys3mcb7AFdEB1pwIYjDDBHNrnWSQOx F1qURGCb771RYGmofBToNLqaydvUARqat+WPYJhqr2tjlVmWKzp0LmaQ5IyCrA7Hap3U vOWw== X-Gm-Message-State: AOAM532kyKgin8nW1EPNF1auX4gp3P2n9+70D7/nmxzoAhoaeqa354G+ SHto9sD4BB7O/546bfLZZhIXr48MeKgbNA== X-Received: by 2002:a17:902:8483:b029:dc:3e69:4095 with SMTP id c3-20020a1709028483b02900dc3e694095mr1283258plo.66.1613605264463; Wed, 17 Feb 2021 15:41:04 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:03 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 18/35] Hexagon (target/hexagon/fma_emu.[ch]) utility functions Date: Wed, 17 Feb 2021 15:40:06 -0800 Message-Id: <20210217234023.1742406-19-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1033; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1033.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Signed-off-by: Taylor Simpson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1612763186-18161-18-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/fma_emu.h | 36 ++ target/hexagon/fma_emu.c | 702 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 738 insertions(+) create mode 100644 target/hexagon/fma_emu.h create mode 100644 target/hexagon/fma_emu.c -- 2.25.1 diff --git a/target/hexagon/fma_emu.h b/target/hexagon/fma_emu.h new file mode 100644 index 0000000000..e3b99a8cf4 --- /dev/null +++ b/target/hexagon/fma_emu.h @@ -0,0 +1,36 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_FMA_EMU_H +#define HEXAGON_FMA_EMU_H + +static inline bool is_finite(float64 x) +{ + return !float64_is_any_nan(x) && !float64_is_infinity(x); +} + +int32_t float64_getexp(float64 f64); +int32_t float32_getexp(float32 f32); +float32 infinite_float32(uint8_t sign); +float32 internal_fmafx(float32 a, float32 b, float32 c, + int scale, float_status *fp_status); +float32 internal_mpyf(float32 a, float32 b, float_status *fp_status); +float64 internal_mpyhh(float64 a, float64 b, + unsigned long long int accumulated, + float_status *fp_status); + +#endif diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c new file mode 100644 index 0000000000..842d903710 --- /dev/null +++ b/target/hexagon/fma_emu.c @@ -0,0 +1,702 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/int128.h" +#include "fpu/softfloat.h" +#include "macros.h" +#include "conv_emu.h" +#include "fma_emu.h" + +#define DF_INF_EXP 0x7ff +#define DF_BIAS 1023 +#define DF_MANTBITS 52 +#define DF_NAN 0xffffffffffffffffULL +#define DF_INF 0x7ff0000000000000ULL +#define DF_MINUS_INF 0xfff0000000000000ULL +#define DF_MAXF 0x7fefffffffffffffULL +#define DF_MINUS_MAXF 0xffefffffffffffffULL + +#define SF_INF_EXP 0xff +#define SF_BIAS 127 +#define SF_MANTBITS 23 +#define SF_INF 0x7f800000 +#define SF_MINUS_INF 0xff800000 +#define SF_MAXF 0x7f7fffff +#define SF_MINUS_MAXF 0xff7fffff + +#define HF_INF_EXP 0x1f +#define HF_BIAS 15 + +#define WAY_BIG_EXP 4096 + +typedef union { + double f; + uint64_t i; + struct { + uint64_t mant:52; + uint64_t exp:11; + uint64_t sign:1; + }; +} Double; + +typedef union { + float f; + uint32_t i; + struct { + uint32_t mant:23; + uint32_t exp:8; + uint32_t sign:1; + }; +} Float; + +static inline uint64_t float64_getmant(float64 f64) +{ + Double a = { .i = f64 }; + if (float64_is_normal(f64)) { + return a.mant | 1ULL << 52; + } + if (float64_is_zero(f64)) { + return 0; + } + if (float64_is_denormal(f64)) { + return a.mant; + } + return ~0ULL; +} + +int32_t float64_getexp(float64 f64) +{ + Double a = { .i = f64 }; + if (float64_is_normal(f64)) { + return a.exp; + } + if (float64_is_denormal(f64)) { + return a.exp + 1; + } + return -1; +} + +static inline uint64_t float32_getmant(float32 f32) +{ + Float a = { .i = f32 }; + if (float32_is_normal(f32)) { + return a.mant | 1ULL << 23; + } + if (float32_is_zero(f32)) { + return 0; + } + if (float32_is_denormal(f32)) { + return a.mant; + } + return ~0ULL; +} + +int32_t float32_getexp(float32 f32) +{ + Float a = { .i = f32 }; + if (float32_is_normal(f32)) { + return a.exp; + } + if (float32_is_denormal(f32)) { + return a.exp + 1; + } + return -1; +} + +static inline uint32_t int128_getw0(Int128 x) +{ + return int128_getlo(x); +} + +static inline uint32_t int128_getw1(Int128 x) +{ + return int128_getlo(x) >> 32; +} + +static inline Int128 int128_mul_6464(uint64_t ai, uint64_t bi) +{ + Int128 a, b; + uint64_t pp0, pp1a, pp1b, pp1s, pp2; + + a = int128_make64(ai); + b = int128_make64(bi); + pp0 = (uint64_t)int128_getw0(a) * (uint64_t)int128_getw0(b); + pp1a = (uint64_t)int128_getw1(a) * (uint64_t)int128_getw0(b); + pp1b = (uint64_t)int128_getw1(b) * (uint64_t)int128_getw0(a); + pp2 = (uint64_t)int128_getw1(a) * (uint64_t)int128_getw1(b); + + pp1s = pp1a + pp1b; + if ((pp1s < pp1a) || (pp1s < pp1b)) { + pp2 += (1ULL << 32); + } + uint64_t ret_low = pp0 + (pp1s << 32); + if ((ret_low < pp0) || (ret_low < (pp1s << 32))) { + pp2 += 1; + } + + return int128_make128(ret_low, pp2 + (pp1s >> 32)); +} + +static inline Int128 int128_sub_borrow(Int128 a, Int128 b, int borrow) +{ + Int128 ret = int128_sub(a, b); + if (borrow != 0) { + ret = int128_sub(ret, int128_one()); + } + return ret; +} + +typedef struct { + Int128 mant; + int32_t exp; + uint8_t sign; + uint8_t guard; + uint8_t round; + uint8_t sticky; +} Accum; + +static inline void accum_init(Accum *p) +{ + p->mant = int128_zero(); + p->exp = 0; + p->sign = 0; + p->guard = 0; + p->round = 0; + p->sticky = 0; +} + +static inline Accum accum_norm_left(Accum a) +{ + a.exp--; + a.mant = int128_lshift(a.mant, 1); + a.mant = int128_or(a.mant, int128_make64(a.guard)); + a.guard = a.round; + a.round = a.sticky; + return a; +} + +static inline Accum accum_norm_right(Accum a, int amt) +{ + if (amt > 130) { + a.sticky |= + a.round | a.guard | int128_nz(a.mant); + a.guard = a.round = 0; + a.mant = int128_zero(); + a.exp += amt; + return a; + + } + while (amt >= 64) { + a.sticky |= a.round | a.guard | (int128_getlo(a.mant) != 0); + a.guard = (int128_getlo(a.mant) >> 63) & 1; + a.round = (int128_getlo(a.mant) >> 62) & 1; + a.mant = int128_make64(int128_gethi(a.mant)); + a.exp += 64; + amt -= 64; + } + while (amt > 0) { + a.exp++; + a.sticky |= a.round; + a.round = a.guard; + a.guard = int128_getlo(a.mant) & 1; + a.mant = int128_rshift(a.mant, 1); + amt--; + } + return a; +} + +/* + * On the add/sub, we need to be able to shift out lots of bits, but need a + * sticky bit for what was shifted out, I think. + */ +static Accum accum_add(Accum a, Accum b); + +static inline Accum accum_sub(Accum a, Accum b, int negate) +{ + Accum ret; + accum_init(&ret); + int borrow; + + if (a.sign != b.sign) { + b.sign = !b.sign; + return accum_add(a, b); + } + if (b.exp > a.exp) { + /* small - big == - (big - small) */ + return accum_sub(b, a, !negate); + } + if ((b.exp == a.exp) && (int128_gt(b.mant, a.mant))) { + /* small - big == - (big - small) */ + return accum_sub(b, a, !negate); + } + + while (a.exp > b.exp) { + /* Try to normalize exponents: shrink a exponent and grow mantissa */ + if (int128_gethi(a.mant) & (1ULL << 62)) { + /* Can't grow a any more */ + break; + } else { + a = accum_norm_left(a); + } + } + + while (a.exp > b.exp) { + /* Try to normalize exponents: grow b exponent and shrink mantissa */ + /* Keep around shifted out bits... we might need those later */ + b = accum_norm_right(b, a.exp - b.exp); + } + + if ((int128_gt(b.mant, a.mant))) { + return accum_sub(b, a, !negate); + } + + /* OK, now things should be normalized! */ + ret.sign = a.sign; + ret.exp = a.exp; + assert(!int128_gt(b.mant, a.mant)); + borrow = (b.round << 2) | (b.guard << 1) | b.sticky; + ret.mant = int128_sub_borrow(a.mant, b.mant, (borrow != 0)); + borrow = 0 - borrow; + ret.guard = (borrow >> 2) & 1; + ret.round = (borrow >> 1) & 1; + ret.sticky = (borrow >> 0) & 1; + if (negate) { + ret.sign = !ret.sign; + } + return ret; +} + +static Accum accum_add(Accum a, Accum b) +{ + Accum ret; + accum_init(&ret); + if (a.sign != b.sign) { + b.sign = !b.sign; + return accum_sub(a, b, 0); + } + if (b.exp > a.exp) { + /* small + big == (big + small) */ + return accum_add(b, a); + } + if ((b.exp == a.exp) && int128_gt(b.mant, a.mant)) { + /* small + big == (big + small) */ + return accum_add(b, a); + } + + while (a.exp > b.exp) { + /* Try to normalize exponents: shrink a exponent and grow mantissa */ + if (int128_gethi(a.mant) & (1ULL << 62)) { + /* Can't grow a any more */ + break; + } else { + a = accum_norm_left(a); + } + } + + while (a.exp > b.exp) { + /* Try to normalize exponents: grow b exponent and shrink mantissa */ + /* Keep around shifted out bits... we might need those later */ + b = accum_norm_right(b, a.exp - b.exp); + } + + /* OK, now things should be normalized! */ + if (int128_gt(b.mant, a.mant)) { + return accum_add(b, a); + }; + ret.sign = a.sign; + ret.exp = a.exp; + assert(!int128_gt(b.mant, a.mant)); + ret.mant = int128_add(a.mant, b.mant); + ret.guard = b.guard; + ret.round = b.round; + ret.sticky = b.sticky; + return ret; +} + +/* Return an infinity with requested sign */ +static inline float64 infinite_float64(uint8_t sign) +{ + if (sign) { + return make_float64(DF_MINUS_INF); + } else { + return make_float64(DF_INF); + } +} + +/* Return a maximum finite value with requested sign */ +static inline float64 maxfinite_float64(uint8_t sign) +{ + if (sign) { + return make_float64(DF_MINUS_MAXF); + } else { + return make_float64(DF_MAXF); + } +} + +/* Return a zero value with requested sign */ +static inline float64 zero_float64(uint8_t sign) +{ + if (sign) { + return make_float64(0x8000000000000000); + } else { + return float64_zero; + } +} + +/* Return an infinity with the requested sign */ +float32 infinite_float32(uint8_t sign) +{ + if (sign) { + return make_float32(SF_MINUS_INF); + } else { + return make_float32(SF_INF); + } +} + +/* Return a maximum finite value with the requested sign */ +static inline float32 maxfinite_float32(uint8_t sign) +{ + if (sign) { + return make_float32(SF_MINUS_MAXF); + } else { + return make_float32(SF_MAXF); + } +} + +/* Return a zero value with requested sign */ +static inline float32 zero_float32(uint8_t sign) +{ + if (sign) { + return make_float32(0x80000000); + } else { + return float32_zero; + } +} + +#define GEN_XF_ROUND(SUFFIX, MANTBITS, INF_EXP, INTERNAL_TYPE) \ +static inline SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \ +{ \ + if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0) \ + && ((a.guard | a.round | a.sticky) == 0)) { \ + /* result zero */ \ + switch (fp_status->float_rounding_mode) { \ + case float_round_down: \ + return zero_##SUFFIX(1); \ + default: \ + return zero_##SUFFIX(0); \ + } \ + } \ + /* Normalize right */ \ + /* We want MANTBITS bits of mantissa plus the leading one. */ \ + /* That means that we want MANTBITS+1 bits, or 0x000000000000FF_FFFF */ \ + /* So we need to normalize right while the high word is non-zero and \ + * while the low word is nonzero when masked with 0xffe0_0000_0000_0000 */ \ + while ((int128_gethi(a.mant) != 0) || \ + ((int128_getlo(a.mant) >> (MANTBITS + 1)) != 0)) { \ + a = accum_norm_right(a, 1); \ + } \ + /* \ + * OK, now normalize left \ + * We want to normalize left until we have a leading one in bit 24 \ + * Theoretically, we only need to shift a maximum of one to the left if we \ + * shifted out lots of bits from B, or if we had no shift / 1 shift sticky \ + * shoudl be 0 \ + */ \ + while ((int128_getlo(a.mant) & (1ULL << MANTBITS)) == 0) { \ + a = accum_norm_left(a); \ + } \ + /* \ + * OK, now we might need to denormalize because of potential underflow. \ + * We need to do this before rounding, and rounding might make us normal \ + * again \ + */ \ + while (a.exp <= 0) { \ + a = accum_norm_right(a, 1 - a.exp); \ + /* \ + * Do we have underflow? \ + * That's when we get an inexact answer because we ran out of bits \ + * in a denormal. \ + */ \ + if (a.guard || a.round || a.sticky) { \ + float_raise(float_flag_underflow, fp_status); \ + } \ + } \ + /* OK, we're relatively canonical... now we need to round */ \ + if (a.guard || a.round || a.sticky) { \ + float_raise(float_flag_inexact, fp_status); \ + switch (fp_status->float_rounding_mode) { \ + case float_round_to_zero: \ + /* Chop and we're done */ \ + break; \ + case float_round_up: \ + if (a.sign == 0) { \ + a.mant = int128_add(a.mant, int128_one()); \ + } \ + break; \ + case float_round_down: \ + if (a.sign != 0) { \ + a.mant = int128_add(a.mant, int128_one()); \ + } \ + break; \ + default: \ + if (a.round || a.sticky) { \ + /* round up if guard is 1, down if guard is zero */ \ + a.mant = int128_add(a.mant, int128_make64(a.guard)); \ + } else if (a.guard) { \ + /* exactly .5, round up if odd */ \ + a.mant = int128_add(a.mant, int128_and(a.mant, int128_one())); \ + } \ + break; \ + } \ + } \ + /* \ + * OK, now we might have carried all the way up. \ + * So we might need to shr once \ + * at least we know that the lsb should be zero if we rounded and \ + * got a carry out... \ + */ \ + if ((int128_getlo(a.mant) >> (MANTBITS + 1)) != 0) { \ + a = accum_norm_right(a, 1); \ + } \ + /* Overflow? */ \ + if (a.exp >= INF_EXP) { \ + /* Yep, inf result */ \ + float_raise(float_flag_overflow, fp_status); \ + float_raise(float_flag_inexact, fp_status); \ + switch (fp_status->float_rounding_mode) { \ + case float_round_to_zero: \ + return maxfinite_##SUFFIX(a.sign); \ + case float_round_up: \ + if (a.sign == 0) { \ + return infinite_##SUFFIX(a.sign); \ + } else { \ + return maxfinite_##SUFFIX(a.sign); \ + } \ + case float_round_down: \ + if (a.sign != 0) { \ + return infinite_##SUFFIX(a.sign); \ + } else { \ + return maxfinite_##SUFFIX(a.sign); \ + } \ + default: \ + return infinite_##SUFFIX(a.sign); \ + } \ + } \ + /* Underflow? */ \ + if (int128_getlo(a.mant) & (1ULL << MANTBITS)) { \ + /* Leading one means: No, we're normal. So, we should be done... */ \ + INTERNAL_TYPE ret; \ + ret.i = 0; \ + ret.sign = a.sign; \ + ret.exp = a.exp; \ + ret.mant = int128_getlo(a.mant); \ + return ret.i; \ + } \ + assert(a.exp == 1); \ + INTERNAL_TYPE ret; \ + ret.i = 0; \ + ret.sign = a.sign; \ + ret.exp = 0; \ + ret.mant = int128_getlo(a.mant); \ + return ret.i; \ +} + +GEN_XF_ROUND(float64, DF_MANTBITS, DF_INF_EXP, Double) +GEN_XF_ROUND(float32, SF_MANTBITS, SF_INF_EXP, Float) + +static bool is_inf_prod(float64 a, float64 b) +{ + return ((float64_is_infinity(a) && float64_is_infinity(b)) || + (float64_is_infinity(a) && is_finite(b) && (!float64_is_zero(b))) || + (float64_is_infinity(b) && is_finite(a) && (!float64_is_zero(a)))); +} + +static inline float64 special_fma(float64 a, float64 b, float64 c, + float_status *fp_status) +{ + float64 ret = make_float64(0); + + /* + * If A multiplied by B is an exact infinity and C is also an infinity + * but with the opposite sign, FMA returns NaN and raises invalid. + */ + uint8_t a_sign = float64_is_neg(a); + uint8_t b_sign = float64_is_neg(b); + uint8_t c_sign = float64_is_neg(c); + if (is_inf_prod(a, b) && float64_is_infinity(c)) { + if ((a_sign ^ b_sign) != c_sign) { + ret = make_float64(DF_NAN); + float_raise(float_flag_invalid, fp_status); + return ret; + } + } + if ((float64_is_infinity(a) && float64_is_zero(b)) || + (float64_is_zero(a) && float64_is_infinity(b))) { + ret = make_float64(DF_NAN); + float_raise(float_flag_invalid, fp_status); + return ret; + } + /* + * If none of the above checks are true and C is a NaN, + * a NaN shall be returned + * If A or B are NaN, a NAN shall be returned. + */ + if (float64_is_any_nan(a) || + float64_is_any_nan(b) || + float64_is_any_nan(c)) { + if (float64_is_any_nan(a) && (fGETBIT(51, a) == 0)) { + float_raise(float_flag_invalid, fp_status); + } + if (float64_is_any_nan(b) && (fGETBIT(51, b) == 0)) { + float_raise(float_flag_invalid, fp_status); + } + if (float64_is_any_nan(c) && (fGETBIT(51, c) == 0)) { + float_raise(float_flag_invalid, fp_status); + } + ret = make_float64(DF_NAN); + return ret; + } + /* + * We have checked for adding opposite-signed infinities. + * Other infinities return infinity with the correct sign + */ + if (float64_is_infinity(c)) { + ret = infinite_float64(c_sign); + return ret; + } + if (float64_is_infinity(a) || float64_is_infinity(b)) { + ret = infinite_float64(a_sign ^ b_sign); + return ret; + } + g_assert_not_reached(); +} + +static inline float32 special_fmaf(float32 a, float32 b, float32 c, + float_status *fp_status) +{ + float64 aa, bb, cc; + aa = float32_to_float64(a, fp_status); + bb = float32_to_float64(b, fp_status); + cc = float32_to_float64(c, fp_status); + return float64_to_float32(special_fma(aa, bb, cc, fp_status), fp_status); +} + +float32 internal_fmafx(float32 a, float32 b, float32 c, int scale, + float_status *fp_status) +{ + Accum prod; + Accum acc; + Accum result; + accum_init(&prod); + accum_init(&acc); + accum_init(&result); + + uint8_t a_sign = float32_is_neg(a); + uint8_t b_sign = float32_is_neg(b); + uint8_t c_sign = float32_is_neg(c); + if (float32_is_infinity(a) || + float32_is_infinity(b) || + float32_is_infinity(c)) { + return special_fmaf(a, b, c, fp_status); + } + if (float32_is_any_nan(a) || + float32_is_any_nan(b) || + float32_is_any_nan(c)) { + return special_fmaf(a, b, c, fp_status); + } + if ((scale == 0) && (float32_is_zero(a) || float32_is_zero(b))) { + float32 tmp = float32_mul(a, b, fp_status); + tmp = float32_add(tmp, c, fp_status); + return tmp; + } + + /* (a * 2**b) * (c * 2**d) == a*c * 2**(b+d) */ + prod.mant = int128_mul_6464(float32_getmant(a), float32_getmant(b)); + + /* + * Note: extracting the mantissa into an int is multiplying by + * 2**23, so adjust here + */ + prod.exp = float32_getexp(a) + float32_getexp(b) - SF_BIAS - 23; + prod.sign = a_sign ^ b_sign; + if (float32_is_zero(a) || float32_is_zero(b)) { + prod.exp = -2 * WAY_BIG_EXP; + } + if ((scale > 0) && float32_is_denormal(c)) { + acc.mant = int128_mul_6464(0, 0); + acc.exp = -WAY_BIG_EXP; + acc.sign = c_sign; + acc.sticky = 1; + result = accum_add(prod, acc); + } else if (!float32_is_zero(c)) { + acc.mant = int128_mul_6464(float32_getmant(c), 1); + acc.exp = float32_getexp(c); + acc.sign = c_sign; + result = accum_add(prod, acc); + } else { + result = prod; + } + result.exp += scale; + return accum_round_float32(result, fp_status); +} + +float32 internal_mpyf(float32 a, float32 b, float_status *fp_status) +{ + if (float32_is_zero(a) || float32_is_zero(b)) { + return float32_mul(a, b, fp_status); + } + return internal_fmafx(a, b, float32_zero, 0, fp_status); +} + +float64 internal_mpyhh(float64 a, float64 b, + unsigned long long int accumulated, + float_status *fp_status) +{ + Accum x; + unsigned long long int prod; + unsigned int sticky; + uint8_t a_sign, b_sign; + + sticky = accumulated & 1; + accumulated >>= 1; + accum_init(&x); + if (float64_is_zero(a) || + float64_is_any_nan(a) || + float64_is_infinity(a)) { + return float64_mul(a, b, fp_status); + } + if (float64_is_zero(b) || + float64_is_any_nan(b) || + float64_is_infinity(b)) { + return float64_mul(a, b, fp_status); + } + x.mant = int128_mul_6464(accumulated, 1); + x.sticky = sticky; + prod = fGETUWORD(1, float64_getmant(a)) * fGETUWORD(1, float64_getmant(b)); + x.mant = int128_add(x.mant, int128_mul_6464(prod, 0x100000000ULL)); + x.exp = float64_getexp(a) + float64_getexp(b) - DF_BIAS - 20; + if (!float64_is_normal(a) || !float64_is_normal(b)) { + /* crush to inexact zero */ + x.sticky = 1; + x.exp = -4096; + } + a_sign = float64_is_neg(a); + b_sign = float64_is_neg(b); + x.sign = a_sign ^ b_sign; + return accum_round_float64(x, fp_status); +} From patchwork Wed Feb 17 23:40:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384042 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3223114jao; Wed, 17 Feb 2021 15:52:13 -0800 (PST) X-Google-Smtp-Source: ABdhPJywBtm+KAdn4/2LLZgb2PZhvXU+0qXvMngamyrd/I66cdJtaoF3/HT44ZBZksRw3LJ5nEz3 X-Received: by 2002:a25:ad26:: with SMTP id y38mr2761867ybi.391.1613605933585; Wed, 17 Feb 2021 15:52:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605933; cv=none; d=google.com; s=arc-20160816; b=nhyZJOAE3MY1f/6+LAMK3oxXJLUmSJUzKt+n/TMQqSlss7p1M2NF+MgYO/vw3vKn6r luy/spTtWpwvvcoe33aRTW4awY+KMHvd141gDrCCa7tATElkEvVoXE9+6xV87lFGIxjJ 9X1taaq9+ibF/9VA1JcJujyTUTh4PJ+h5MWz/91iTW9I8swgjtYCKiLB4ejodIzYmZ7t /HlXxskINn+Tp5J5fxaaY1745SFA4ec2X0JGB9RISC8G+yAPFNFXCbG9AnrqgNbA5E2U oRUGwfKOXWzsn2KPxnEQAgSXhPqm/Xc776wEbbWQuXS1ff/NwjCZaEso7v/gCz0ILVp0 MTfg== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=OVRS4mBybApnULSHrOfHU/FtHgRCaP56h3KYL3W42uk=; b=l+31/8xC32uSCv+xOVLHh39uKEbUjlYOVgH/4FA+TUEMe9kh4yLNcwhb/e/KJfdxTQ eXZwkO8xdALQ8TQElcgFwe6Z3zXT62Ik4MUJoyjhfqMYzyAcTLvahOFE/iGJmgnKKQg7 7UnJwyxfA02ecxH6VBjY48MljtgWVoJsoSdFNObjrufdzLQaCHsWCH38NJH5tziZMKUj ERTP4TIlK10p+uUU7pCa9JjiLywmBx4xc2xPCtlpTKaoeJWyBvW3xcUZ2lBYs2XctYif 7y/TzM2JbeiiVtkkwjYcc4e6q9JisAx3GmAZO9ZbF57s+1JCnKLICgjZ1ZvQ40iGpW6V KG7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Z7qkC/pF"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id j11si3586652ybg.350.2021.02.17.15.52.13 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:52:13 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Z7qkC/pF"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:39528 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWc8-0005HF-RY for patch@linaro.org; Wed, 17 Feb 2021 18:52:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50884) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRe-0000wZ-DR for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:22 -0500 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]:35628) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRX-0004jm-56 for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:22 -0500 Received: by mail-pl1-x62c.google.com with SMTP id g20so215645plo.2 for ; Wed, 17 Feb 2021 15:41:14 -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 :mime-version:content-transfer-encoding; bh=OVRS4mBybApnULSHrOfHU/FtHgRCaP56h3KYL3W42uk=; b=Z7qkC/pFy0mZsWYs1s/FIQrJOPtQDAjrNtrfyoXQJ1S0HHaEDD+zmOmnAgDJhpF/F9 3udl2bwr0D9S7BU+/GPJrBkkD1om27tjM3UwpnBLEIu5QQAtxdXympe6DyFJQ6LarwMD BQkjcUpIk8Xj++NmiFPXTbsr/S0MK+1clF2t/Z3NvN0IsV+lNFvq0Ucs9wf/3Zn8plJG uS5yiOyaKsxFpVsrG2tV5cWH+9Vwu/OeGGk4zzyxJCXVJe0gxoZAgwdyb2OT9osAnJhk PZG1+PM+VUbCzOm0FU88SjIvFzbsgpBukPSq5+91gu4XqzGco4JhLnn0Dkl+oKG80tw2 moyA== 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:mime-version:content-transfer-encoding; bh=OVRS4mBybApnULSHrOfHU/FtHgRCaP56h3KYL3W42uk=; b=kiBXYeyur8FJppZEu+bE6eA6ywEYwBBR1/Fq0EfilFCexsnzuNRoCcBnOhQu0ozNi8 vwXcSSCREEfn989EKINNtfgFDpsb9tlFHAADWPLqqKqIfRvDBmKgJL0z3DRICP1qHJko KVDzg/U2ocHDDLhlUfP5fjUzdswJgEvQpsjzG48EBD0TLt8psxJuZFx3eR5ASZXnnOpL N7O35JZdnKmi2Y0w6Zggls/6Wv+CGzbA4tAvfeS9cxJlcpeyV9hG4iwuc8q1Eq2bcAED p6pMTcfi444domudsQhnlL48llTfRvuKK/WzTKwMdCaWDzvJeVKdnGjzprEsmH3OszLN BVqg== X-Gm-Message-State: AOAM531TbHuKuwXshhAhHItsPg4uHX+XSlAVpZUpR94uzqOCBTznzrTH xGAIlXE/8rpgHrEwm/cebWbAYPteAQMO2w== X-Received: by 2002:a17:902:7c18:b029:e2:de98:59c9 with SMTP id x24-20020a1709027c18b02900e2de9859c9mr1356813pll.4.1613605271480; Wed, 17 Feb 2021 15:41:11 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:10 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 19/35] Hexagon (target/hexagon/imported) arch import Date: Wed, 17 Feb 2021 15:40:07 -0800 Message-Id: <20210217234023.1742406-20-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Imported from the Hexagon architecture library imported/macros.def The macro definitions specify instruction attributes that are applied to each instruction that references the macro. The generator will recursively apply attributes to each instruction that used the macro. imported/allidefs.def Top level instruction definition file imported/*.idef Instruction definition files These files are input to the first phase of the generator (gen_semantics.c) to create a python include file with the instruction semantics and attributes. The python include file is fed to the second phase to generate various header files. imported/encode*.def Instruction encoding bit patterns for every instruction Signed-off-by: Taylor Simpson Acked-by: Richard Henderson Message-Id: <1612763186-18161-19-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/imported/allidefs.def | 30 + target/hexagon/imported/alu.idef | 1258 ++++++++++++ target/hexagon/imported/branch.idef | 326 +++ target/hexagon/imported/compare.idef | 619 ++++++ target/hexagon/imported/encode.def | 124 ++ target/hexagon/imported/encode_pp.def | 2110 ++++++++++++++++++++ target/hexagon/imported/encode_subinsn.def | 149 ++ target/hexagon/imported/float.idef | 312 +++ target/hexagon/imported/ldst.idef | 286 +++ target/hexagon/imported/macros.def | 1531 ++++++++++++++ target/hexagon/imported/mpy.idef | 1208 +++++++++++ target/hexagon/imported/shift.idef | 1066 ++++++++++ target/hexagon/imported/subinsns.idef | 149 ++ target/hexagon/imported/system.idef | 68 + 14 files changed, 9236 insertions(+) create mode 100644 target/hexagon/imported/allidefs.def create mode 100644 target/hexagon/imported/alu.idef create mode 100644 target/hexagon/imported/branch.idef create mode 100644 target/hexagon/imported/compare.idef create mode 100644 target/hexagon/imported/encode.def create mode 100644 target/hexagon/imported/encode_pp.def create mode 100644 target/hexagon/imported/encode_subinsn.def create mode 100644 target/hexagon/imported/float.idef create mode 100644 target/hexagon/imported/ldst.idef create mode 100755 target/hexagon/imported/macros.def create mode 100644 target/hexagon/imported/mpy.idef create mode 100644 target/hexagon/imported/shift.idef create mode 100644 target/hexagon/imported/subinsns.idef create mode 100644 target/hexagon/imported/system.idef -- 2.25.1 diff --git a/target/hexagon/imported/allidefs.def b/target/hexagon/imported/allidefs.def new file mode 100644 index 0000000000..2aace29888 --- /dev/null +++ b/target/hexagon/imported/allidefs.def @@ -0,0 +1,30 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Top level instruction definition file + */ + +#include "branch.idef" +#include "ldst.idef" +#include "compare.idef" +#include "mpy.idef" +#include "alu.idef" +#include "float.idef" +#include "shift.idef" +#include "system.idef" +#include "subinsns.idef" diff --git a/target/hexagon/imported/alu.idef b/target/hexagon/imported/alu.idef new file mode 100644 index 0000000000..45cc529fbc --- /dev/null +++ b/target/hexagon/imported/alu.idef @@ -0,0 +1,1258 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * ALU Instructions + */ + + +/**********************************************/ +/* Add/Sub instructions */ +/**********************************************/ + +Q6INSN(A2_add,"Rd32=add(Rs32,Rt32)",ATTRIBS(), +"Add 32-bit registers", +{ RdV=RsV+RtV;}) + +Q6INSN(A2_sub,"Rd32=sub(Rt32,Rs32)",ATTRIBS(), +"Subtract 32-bit registers", +{ RdV=RtV-RsV;}) + +#define COND_ALU(TAG,OPER,DESCR,SEMANTICS)\ +Q6INSN(TAG##t,"if (Pu4) "OPER,ATTRIBS(A_ARCHV2),DESCR,{if(fLSBOLD(PuV)){SEMANTICS;} else {CANCEL;}})\ +Q6INSN(TAG##f,"if (!Pu4) "OPER,ATTRIBS(A_ARCHV2),DESCR,{if(fLSBOLDNOT(PuV)){SEMANTICS;} else {CANCEL;}})\ +Q6INSN(TAG##tnew,"if (Pu4.new) " OPER,ATTRIBS(A_ARCHV2),DESCR,{if(fLSBNEW(PuN)){SEMANTICS;} else {CANCEL;}})\ +Q6INSN(TAG##fnew,"if (!Pu4.new) "OPER,ATTRIBS(A_ARCHV2),DESCR,{if(fLSBNEWNOT(PuN)){SEMANTICS;} else {CANCEL;}}) + +COND_ALU(A2_padd,"Rd32=add(Rs32,Rt32)","Conditionally Add 32-bit registers",RdV=RsV+RtV) +COND_ALU(A2_psub,"Rd32=sub(Rt32,Rs32)","Conditionally Subtract 32-bit registers",RdV=RtV-RsV) +COND_ALU(A2_paddi,"Rd32=add(Rs32,#s8)","Conditionally Add Register and immediate",fIMMEXT(siV); RdV=RsV+siV) +COND_ALU(A2_pxor,"Rd32=xor(Rs32,Rt32)","Conditionally XOR registers",RdV=RsV^RtV) +COND_ALU(A2_pand,"Rd32=and(Rs32,Rt32)","Conditionally AND registers",RdV=RsV&RtV) +COND_ALU(A2_por,"Rd32=or(Rs32,Rt32)","Conditionally OR registers",RdV=RsV|RtV) + +COND_ALU(A4_psxtb,"Rd32=sxtb(Rs32)","Conditionally sign-extend byte", RdV=fSXTN(8,32,RsV)) +COND_ALU(A4_pzxtb,"Rd32=zxtb(Rs32)","Conditionally zero-extend byte", RdV=fZXTN(8,32,RsV)) +COND_ALU(A4_psxth,"Rd32=sxth(Rs32)","Conditionally sign-extend halfword", RdV=fSXTN(16,32,RsV)) +COND_ALU(A4_pzxth,"Rd32=zxth(Rs32)","Conditionally zero-extend halfword", RdV=fZXTN(16,32,RsV)) +COND_ALU(A4_paslh,"Rd32=aslh(Rs32)","Conditionally zero-extend halfword", RdV=RsV<<16) +COND_ALU(A4_pasrh,"Rd32=asrh(Rs32)","Conditionally zero-extend halfword", RdV=RsV>>16) + + +Q6INSN(A2_addsat,"Rd32=add(Rs32,Rt32):sat",ATTRIBS(), +"Add 32-bit registers with saturation", +{ RdV=fSAT(fSE32_64(RsV)+fSE32_64(RtV)); }) + +Q6INSN(A2_subsat,"Rd32=sub(Rt32,Rs32):sat",ATTRIBS(), +"Subtract 32-bit registers with saturation", +{ RdV=fSAT(fSE32_64(RtV) - fSE32_64(RsV)); }) + + +Q6INSN(A2_addi,"Rd32=add(Rs32,#s16)",ATTRIBS(), +"Add a signed immediate to a register", +{ fIMMEXT(siV); RdV=RsV+siV;}) + + +Q6INSN(C4_addipc,"Rd32=add(pc,#u6)",ATTRIBS(), +"Add immediate to PC", +{ RdV=fREAD_PC()+fIMMEXT(uiV);}) + + + +/**********************************************/ +/* Single-precision HL forms */ +/* These insns and the SP mpy are the ones */ +/* that can do .HL stuff */ +/**********************************************/ +#define STD_HL_INSN(TAG,OPER,AOPER,ATR,SEM)\ +Q6INSN(A2_##TAG##_ll, OPER"(Rt.L32,Rs.L32)"AOPER, ATR,"",{SEM(fGETHALF(0,RtV),fGETHALF(0,RsV));})\ +Q6INSN(A2_##TAG##_lh, OPER"(Rt.L32,Rs.H32)"AOPER, ATR,"",{SEM(fGETHALF(0,RtV),fGETHALF(1,RsV));})\ +Q6INSN(A2_##TAG##_hl, OPER"(Rt.H32,Rs.L32)"AOPER, ATR,"",{SEM(fGETHALF(1,RtV),fGETHALF(0,RsV));})\ +Q6INSN(A2_##TAG##_hh, OPER"(Rt.H32,Rs.H32)"AOPER, ATR,"",{SEM(fGETHALF(1,RtV),fGETHALF(1,RsV));}) + +#define SUBSTD_HL_INSN(TAG,OPER,AOPER,ATR,SEM)\ +Q6INSN(A2_##TAG##_ll, OPER"(Rt.L32,Rs.L32)"AOPER, ATR,"",{SEM(fGETHALF(0,RtV),fGETHALF(0,RsV));})\ +Q6INSN(A2_##TAG##_hl, OPER"(Rt.L32,Rs.H32)"AOPER, ATR,"",{SEM(fGETHALF(0,RtV),fGETHALF(1,RsV));}) + + +#undef HLSEM +#define HLSEM(A,B) RdV=fSXTN(16,32,(A+B)) +SUBSTD_HL_INSN(addh_l16,"Rd32=add","",ATTRIBS(),HLSEM) + +#undef HLSEM +#define HLSEM(A,B) RdV=fSATH(A+B) +SUBSTD_HL_INSN(addh_l16_sat,"Rd32=add",":sat",ATTRIBS(),HLSEM) + +#undef HLSEM +#define HLSEM(A,B) RdV=fSXTN(16,32,(A-B)) +SUBSTD_HL_INSN(subh_l16,"Rd32=sub","",ATTRIBS(),HLSEM) + +#undef HLSEM +#define HLSEM(A,B) RdV=fSATH(A-B) +SUBSTD_HL_INSN(subh_l16_sat,"Rd32=sub",":sat",ATTRIBS(),HLSEM) + +#undef HLSEM +#define HLSEM(A,B) RdV=(A+B)<<16 +STD_HL_INSN(addh_h16,"Rd32=add",":<<16",ATTRIBS(),HLSEM) + +#undef HLSEM +#define HLSEM(A,B) RdV=(fSATH(A+B))<<16 +STD_HL_INSN(addh_h16_sat,"Rd32=add",":sat:<<16",ATTRIBS(),HLSEM) + +#undef HLSEM +#define HLSEM(A,B) RdV=(A-B)<<16 +STD_HL_INSN(subh_h16,"Rd32=sub",":<<16",ATTRIBS(),HLSEM) + +#undef HLSEM +#define HLSEM(A,B) RdV=(fSATH(A-B))<<16 +STD_HL_INSN(subh_h16_sat,"Rd32=sub",":sat:<<16",ATTRIBS(),HLSEM) + + + + +Q6INSN(A2_aslh,"Rd32=aslh(Rs32)",ATTRIBS(), +"Arithmetic Shift Left by Halfword",{ RdV=RsV<<16; }) + +Q6INSN(A2_asrh,"Rd32=asrh(Rs32)",ATTRIBS(), +"Arithmetic Shift Right by Halfword",{ RdV=RsV>>16; }) + + +/* 64-bit versions */ + +Q6INSN(A2_addp,"Rdd32=add(Rss32,Rtt32)",ATTRIBS(), +"Add", +{ RddV=RssV+RttV;}) + +Q6INSN(A2_addpsat,"Rdd32=add(Rss32,Rtt32):sat",ATTRIBS(A_ARCHV3), +"Add", +{ fADDSAT64(RddV,RssV,RttV);}) + +Q6INSN(A2_addspl,"Rdd32=add(Rss32,Rtt32):raw:lo",ATTRIBS(A_ARCHV3), +"Add", +{ RddV=RttV+fSXTN(32,64,fGETWORD(0,RssV));}) + +Q6INSN(A2_addsph,"Rdd32=add(Rss32,Rtt32):raw:hi",ATTRIBS(A_ARCHV3), +"Add", +{ RddV=RttV+fSXTN(32,64,fGETWORD(1,RssV));}) + +Q6INSN(A2_subp,"Rdd32=sub(Rtt32,Rss32)",ATTRIBS(), +"Sub", +{ RddV=RttV-RssV;}) + +/* NEG and ABS */ + +Q6INSN(A2_negsat,"Rd32=neg(Rs32):sat",ATTRIBS(), +"Arithmetic negate register", { RdV = fSAT(-fCAST8s(RsV)); }) + +Q6INSN(A2_abs,"Rd32=abs(Rs32)",ATTRIBS(), +"Absolute Value register", { RdV = fABS(RsV); }) + +Q6INSN(A2_abssat,"Rd32=abs(Rs32):sat",ATTRIBS(), +"Arithmetic negate register", { RdV = fSAT(fABS(fCAST4_8s(RsV))); }) + +Q6INSN(A2_vconj,"Rdd32=vconj(Rss32):sat",ATTRIBS(A_ARCHV2), +"Vector Complex conjugate of Rss", +{ fSETHALF(1,RddV,fSATN(16,-fGETHALF(1,RssV))); + fSETHALF(0,RddV,fGETHALF(0,RssV)); + fSETHALF(3,RddV,fSATN(16,-fGETHALF(3,RssV))); + fSETHALF(2,RddV,fGETHALF(2,RssV)); +}) + + +/* 64-bit versions */ + +Q6INSN(A2_negp,"Rdd32=neg(Rss32)",ATTRIBS(), +"Arithmetic negate register", { RddV = -RssV; }) + +Q6INSN(A2_absp,"Rdd32=abs(Rss32)",ATTRIBS(), +"Absolute Value register", { RddV = fABS(RssV); }) + + +/* MIN and MAX R */ + +Q6INSN(A2_max,"Rd32=max(Rs32,Rt32)",ATTRIBS(), +"Maximum of two registers", +{ RdV = fMAX(RsV,RtV); }) + +Q6INSN(A2_maxu,"Rd32=maxu(Rs32,Rt32)",ATTRIBS(), +"Maximum of two registers (unsigned)", +{ RdV = fMAX(fCAST4u(RsV),fCAST4u(RtV)); }) + +Q6INSN(A2_min,"Rd32=min(Rt32,Rs32)",ATTRIBS(), +"Minimum of two registers", +{ RdV = fMIN(RtV,RsV); }) + +Q6INSN(A2_minu,"Rd32=minu(Rt32,Rs32)",ATTRIBS(), +"Minimum of two registers (unsigned)", +{ RdV = fMIN(fCAST4u(RtV),fCAST4u(RsV)); }) + +/* MIN and MAX Pairs */ +#if 1 +Q6INSN(A2_maxp,"Rdd32=max(Rss32,Rtt32)",ATTRIBS(A_ARCHV3), +"Maximum of two register pairs", +{ RddV = fMAX(RssV,RttV); }) + +Q6INSN(A2_maxup,"Rdd32=maxu(Rss32,Rtt32)",ATTRIBS(A_ARCHV3), +"Maximum of two register pairs (unsigned)", +{ RddV = fMAX(fCAST8u(RssV),fCAST8u(RttV)); }) + +Q6INSN(A2_minp,"Rdd32=min(Rtt32,Rss32)",ATTRIBS(A_ARCHV3), +"Minimum of two register pairs", +{ RddV = fMIN(RttV,RssV); }) + +Q6INSN(A2_minup,"Rdd32=minu(Rtt32,Rss32)",ATTRIBS(A_ARCHV3), +"Minimum of two register pairs (unsigned)", +{ RddV = fMIN(fCAST8u(RttV),fCAST8u(RssV)); }) +#endif + +/**********************************************/ +/* Register and Immediate Transfers */ +/**********************************************/ + +Q6INSN(A2_nop,"nop",ATTRIBS(A_IT_NOP), +"Nop (32-bit encoding)", + fHIDE( { } )) + + +Q6INSN(A4_ext,"immext(#u26:6)",ATTRIBS(A_IT_EXTENDER), +"This instruction carries the 26 most-significant immediate bits for the next instruction", +{ fHIDE(); }) + + +Q6INSN(A2_tfr,"Rd32=Rs32",ATTRIBS(), +"tfr register",{ RdV=RsV;}) + +Q6INSN(A2_tfrsi,"Rd32=#s16",ATTRIBS(), +"transfer signed immediate to register",{ fIMMEXT(siV); RdV=siV;}) + +Q6INSN(A2_sxtb,"Rd32=sxtb(Rs32)",ATTRIBS(), +"Sign extend byte", {RdV = fSXTN(8,32,RsV);}) + +Q6INSN(A2_zxth,"Rd32=zxth(Rs32)",ATTRIBS(), +"Zero extend half", {RdV = fZXTN(16,32,RsV);}) + +Q6INSN(A2_sxth,"Rd32=sxth(Rs32)",ATTRIBS(), +"Sign extend half", {RdV = fSXTN(16,32,RsV);}) + +Q6INSN(A2_combinew,"Rdd32=combine(Rs32,Rt32)",ATTRIBS(), +"Combine two words into a register pair", +{ fSETWORD(0,RddV,RtV); + fSETWORD(1,RddV,RsV); +}) + +Q6INSN(A4_combineri,"Rdd32=combine(Rs32,#s8)",ATTRIBS(), +"Combine a word and an immediate into a register pair", +{ fIMMEXT(siV); fSETWORD(0,RddV,siV); + fSETWORD(1,RddV,RsV); +}) + +Q6INSN(A4_combineir,"Rdd32=combine(#s8,Rs32)",ATTRIBS(), +"Combine a word and an immediate into a register pair", +{ fIMMEXT(siV); fSETWORD(0,RddV,RsV); + fSETWORD(1,RddV,siV); +}) + + + +Q6INSN(A2_combineii,"Rdd32=combine(#s8,#S8)",ATTRIBS(A_ARCHV2), +"Set two small immediates", +{ fIMMEXT(siV); fSETWORD(0,RddV,SiV); fSETWORD(1,RddV,siV); }) + +Q6INSN(A4_combineii,"Rdd32=combine(#s8,#U6)",ATTRIBS(),"Set two small immediates", +{ fIMMEXT(UiV); fSETWORD(0,RddV,UiV); fSETWORD(1,RddV,siV); }) + + +Q6INSN(A2_combine_hh,"Rd32=combine(Rt.H32,Rs.H32)",ATTRIBS(), +"Combine two halfs into a register", {RdV = (fGETUHALF(1,RtV)<<16) | fGETUHALF(1,RsV);}) + +Q6INSN(A2_combine_hl,"Rd32=combine(Rt.H32,Rs.L32)",ATTRIBS(), +"Combine two halfs into a register", {RdV = (fGETUHALF(1,RtV)<<16) | fGETUHALF(0,RsV);}) + +Q6INSN(A2_combine_lh,"Rd32=combine(Rt.L32,Rs.H32)",ATTRIBS(), +"Combine two halfs into a register", {RdV = (fGETUHALF(0,RtV)<<16) | fGETUHALF(1,RsV);}) + +Q6INSN(A2_combine_ll,"Rd32=combine(Rt.L32,Rs.L32)",ATTRIBS(), +"Combine two halfs into a register", {RdV = (fGETUHALF(0,RtV)<<16) | fGETUHALF(0,RsV);}) + +Q6INSN(A2_tfril,"Rx.L32=#u16",ATTRIBS(), +"Set low 16-bits, leave upper 16 unchanged",{ fSETHALF(0,RxV,uiV);}) + +Q6INSN(A2_tfrih,"Rx.H32=#u16",ATTRIBS(), +"Set high 16-bits, leave low 16 unchanged",{ fSETHALF(1,RxV,uiV);}) + +Q6INSN(A2_tfrcrr,"Rd32=Cs32",ATTRIBS(), +"transfer control register to general register",{ RdV=CsV;}) + +Q6INSN(A2_tfrrcr,"Cd32=Rs32",ATTRIBS(), +"transfer general register to control register",{ CdV=RsV;}) + +Q6INSN(A4_tfrcpp,"Rdd32=Css32",ATTRIBS(), +"transfer control register to general register",{ RddV=CssV;}) + +Q6INSN(A4_tfrpcp,"Cdd32=Rss32",ATTRIBS(), +"transfer general register to control register",{ CddV=RssV;}) + + +/**********************************************/ +/* Logicals */ +/**********************************************/ + +Q6INSN(A2_and,"Rd32=and(Rs32,Rt32)",ATTRIBS(), +"logical AND",{ RdV=RsV&RtV;}) + +Q6INSN(A2_or,"Rd32=or(Rs32,Rt32)",ATTRIBS(), +"logical OR",{ RdV=RsV|RtV;}) + +Q6INSN(A2_xor,"Rd32=xor(Rs32,Rt32)",ATTRIBS(), +"logical XOR",{ RdV=RsV^RtV;}) + +Q6INSN(M2_xor_xacc,"Rx32^=xor(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"logical XOR with XOR accumulation",{ RxV^=RsV^RtV;}) + +Q6INSN(M4_xor_xacc,"Rxx32^=xor(Rss32,Rtt32)",, +"logical XOR with XOR accumulation",{ RxxV^=RssV^RttV;}) + + + +Q6INSN(A4_andn,"Rd32=and(Rt32,~Rs32)",, +"And-Not", { RdV = (RtV & ~RsV); }) + +Q6INSN(A4_orn,"Rd32=or(Rt32,~Rs32)",, +"Or-Not", { RdV = (RtV | ~RsV); }) + + +Q6INSN(A4_andnp,"Rdd32=and(Rtt32,~Rss32)",, +"And-Not", { RddV = (RttV & ~RssV); }) + +Q6INSN(A4_ornp,"Rdd32=or(Rtt32,~Rss32)",, +"Or-Not", { RddV = (RttV | ~RssV); }) + + + + +/********************/ +/* Compound add-add */ +/********************/ + +Q6INSN(S4_addaddi,"Rd32=add(Rs32,add(Ru32,#s6))",ATTRIBS(), + "3-input add", + { RdV = RsV + RuV + fIMMEXT(siV); }) + + +Q6INSN(S4_subaddi,"Rd32=add(Rs32,sub(#s6,Ru32))",ATTRIBS(), + "3-input sub", + { RdV = RsV - RuV + fIMMEXT(siV); }) + + + +/****************************/ +/* Compound logical-logical */ +/****************************/ + +Q6INSN(M4_and_and,"Rx32&=and(Rs32,Rt32)",ATTRIBS(), +"Compound And-And", { RxV &= (RsV & RtV); }) + +Q6INSN(M4_and_andn,"Rx32&=and(Rs32,~Rt32)",ATTRIBS(), +"Compound And-Andn", { RxV &= (RsV & ~RtV); }) + +Q6INSN(M4_and_or,"Rx32&=or(Rs32,Rt32)",ATTRIBS(), +"Compound And-Or", { RxV &= (RsV | RtV); }) + +Q6INSN(M4_and_xor,"Rx32&=xor(Rs32,Rt32)",ATTRIBS(), +"Compound And-xor", { RxV &= (RsV ^ RtV); }) + + + +Q6INSN(M4_or_and,"Rx32|=and(Rs32,Rt32)",ATTRIBS(), +"Compound Or-And", { RxV |= (RsV & RtV); }) + +Q6INSN(M4_or_andn,"Rx32|=and(Rs32,~Rt32)",ATTRIBS(), +"Compound Or-AndN", { RxV |= (RsV & ~RtV); }) + +Q6INSN(M4_or_or,"Rx32|=or(Rs32,Rt32)",ATTRIBS(), +"Compound Or-Or", { RxV |= (RsV | RtV); }) + +Q6INSN(M4_or_xor,"Rx32|=xor(Rs32,Rt32)",ATTRIBS(), +"Compound Or-xor", { RxV |= (RsV ^ RtV); }) + + +Q6INSN(S4_or_andix,"Rx32=or(Ru32,and(Rx32,#s10))",ATTRIBS(), +"Compound Or-And", { RxV = RuV | (RxV & fIMMEXT(siV)); }) + +Q6INSN(S4_or_andi,"Rx32|=and(Rs32,#s10)",ATTRIBS(), +"Compound Or-And", { RxV = RxV | (RsV & fIMMEXT(siV)); }) + +Q6INSN(S4_or_ori,"Rx32|=or(Rs32,#s10)",ATTRIBS(), +"Compound Or-And", { RxV = RxV | (RsV | fIMMEXT(siV)); }) + + + + +Q6INSN(M4_xor_and,"Rx32^=and(Rs32,Rt32)",ATTRIBS(), +"Compound Xor-And", { RxV ^= (RsV & RtV); }) + +Q6INSN(M4_xor_or,"Rx32^=or(Rs32,Rt32)",ATTRIBS(), +"Compound Xor-Or", { RxV ^= (RsV | RtV); }) + +Q6INSN(M4_xor_andn,"Rx32^=and(Rs32,~Rt32)",ATTRIBS(), +"Compound Xor-And", { RxV ^= (RsV & ~RtV); }) + + + + + + +Q6INSN(A2_subri,"Rd32=sub(#s10,Rs32)",ATTRIBS(A_ARCHV2), +"Subtract register from immediate",{ fIMMEXT(siV); RdV=siV-RsV;}) + +Q6INSN(A2_andir,"Rd32=and(Rs32,#s10)",ATTRIBS(A_ARCHV2), +"logical AND with immediate",{ fIMMEXT(siV); RdV=RsV&siV;}) + +Q6INSN(A2_orir,"Rd32=or(Rs32,#s10)",ATTRIBS(A_ARCHV2), +"logical OR with immediate",{ fIMMEXT(siV); RdV=RsV|siV;}) + + + + +Q6INSN(A2_andp,"Rdd32=and(Rss32,Rtt32)",ATTRIBS(), +"logical AND pair",{ RddV=RssV&RttV;}) + +Q6INSN(A2_orp,"Rdd32=or(Rss32,Rtt32)",ATTRIBS(), +"logical OR pair",{ RddV=RssV|RttV;}) + +Q6INSN(A2_xorp,"Rdd32=xor(Rss32,Rtt32)",ATTRIBS(), +"logical eXclusive OR pair",{ RddV=RssV^RttV;}) + +Q6INSN(A2_notp,"Rdd32=not(Rss32)",ATTRIBS(), +"logical NOT pair",{ RddV=~RssV;}) + +Q6INSN(A2_sxtw,"Rdd32=sxtw(Rs32)",ATTRIBS(), +"Sign extend 32-bit word to 64-bit pair", +{ RddV = fCAST4_8s(RsV); }) + +Q6INSN(A2_sat,"Rd32=sat(Rss32)",ATTRIBS(), +"Saturate to 32-bit Signed", +{ RdV = fSAT(RssV); }) + +Q6INSN(A2_roundsat,"Rd32=round(Rss32):sat",ATTRIBS(), +"Round & Saturate to 32-bit Signed", +{ fHIDE(size8s_t tmp;) fADDSAT64(tmp,RssV,0x080000000ULL); RdV = fGETWORD(1,tmp); }) + +Q6INSN(A2_sath,"Rd32=sath(Rs32)",ATTRIBS(), +"Saturate to 16-bit Signed", +{ RdV = fSATH(RsV); }) + +Q6INSN(A2_satuh,"Rd32=satuh(Rs32)",ATTRIBS(), +"Saturate to 16-bit Unsigned", +{ RdV = fSATUH(RsV); }) + +Q6INSN(A2_satub,"Rd32=satub(Rs32)",ATTRIBS(), +"Saturate to 8-bit Unsigned", +{ RdV = fSATUB(RsV); }) + +Q6INSN(A2_satb,"Rd32=satb(Rs32)",ATTRIBS(A_ARCHV2), +"Saturate to 8-bit Signed", +{ RdV = fSATB(RsV); }) + +/**********************************************/ +/* Vector Add */ +/**********************************************/ + +Q6INSN(A2_vaddub,"Rdd32=vaddub(Rss32,Rtt32)",ATTRIBS(), +"Add vector of bytes", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBYTE(i,RddV,(fGETUBYTE(i,RssV)+fGETUBYTE(i,RttV))); + } +}) + +Q6INSN(A2_vaddubs,"Rdd32=vaddub(Rss32,Rtt32):sat",ATTRIBS(), +"Add vector of bytes", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBYTE(i,RddV,fSATUN(8,fGETUBYTE(i,RssV)+fGETUBYTE(i,RttV))); + } +}) + +Q6INSN(A2_vaddh,"Rdd32=vaddh(Rss32,Rtt32)",ATTRIBS(), +"Add vector of half integers", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fGETHALF(i,RssV)+fGETHALF(i,RttV)); + } +}) + +Q6INSN(A2_vaddhs,"Rdd32=vaddh(Rss32,Rtt32):sat",ATTRIBS(), +"Add vector of half integers with saturation", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fSATN(16,fGETHALF(i,RssV)+fGETHALF(i,RttV))); + } +}) + +Q6INSN(A2_vadduhs,"Rdd32=vadduh(Rss32,Rtt32):sat",ATTRIBS(), +"Add vector of unsigned half integers with saturation", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fSATUN(16,fGETUHALF(i,RssV)+fGETUHALF(i,RttV))); + } +}) + +Q6INSN(A5_vaddhubs,"Rd32=vaddhub(Rss32,Rtt32):sat",ATTRIBS(), +"Add vector of half integers with saturation and pack to unsigned bytes", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETBYTE(i,RdV,fSATUB(fGETHALF(i,RssV)+fGETHALF(i,RttV))); + } +}) + +Q6INSN(A2_vaddw,"Rdd32=vaddw(Rss32,Rtt32)",ATTRIBS(), +"Add vector of words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,fGETWORD(i,RssV)+fGETWORD(i,RttV)); + } +}) + +Q6INSN(A2_vaddws,"Rdd32=vaddw(Rss32,Rtt32):sat",ATTRIBS(), +"Add vector of words with saturation", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,fSATN(32,fGETWORD(i,RssV)+fGETWORD(i,RttV))); + } +}) + + + +Q6INSN(S4_vxaddsubw,"Rdd32=vxaddsubw(Rss32,Rtt32):sat",ATTRIBS(), +"Cross vector add-sub words with saturation", +{ + fSETWORD(0,RddV,fSAT(fGETWORD(0,RssV)+fGETWORD(1,RttV))); + fSETWORD(1,RddV,fSAT(fGETWORD(1,RssV)-fGETWORD(0,RttV))); +}) +Q6INSN(S4_vxsubaddw,"Rdd32=vxsubaddw(Rss32,Rtt32):sat",ATTRIBS(), +"Cross vector sub-add words with saturation", +{ + fSETWORD(0,RddV,fSAT(fGETWORD(0,RssV)-fGETWORD(1,RttV))); + fSETWORD(1,RddV,fSAT(fGETWORD(1,RssV)+fGETWORD(0,RttV))); +}) + + + +Q6INSN(S4_vxaddsubh,"Rdd32=vxaddsubh(Rss32,Rtt32):sat",ATTRIBS(), +"Cross vector add-sub halfwords with saturation", +{ + fSETHALF(0,RddV,fSATH(fGETHALF(0,RssV)+fGETHALF(1,RttV))); + fSETHALF(1,RddV,fSATH(fGETHALF(1,RssV)-fGETHALF(0,RttV))); + + fSETHALF(2,RddV,fSATH(fGETHALF(2,RssV)+fGETHALF(3,RttV))); + fSETHALF(3,RddV,fSATH(fGETHALF(3,RssV)-fGETHALF(2,RttV))); + +}) +Q6INSN(S4_vxsubaddh,"Rdd32=vxsubaddh(Rss32,Rtt32):sat",ATTRIBS(), +"Cross vector sub-add halfwords with saturation", +{ + fSETHALF(0,RddV,fSATH(fGETHALF(0,RssV)-fGETHALF(1,RttV))); + fSETHALF(1,RddV,fSATH(fGETHALF(1,RssV)+fGETHALF(0,RttV))); + + fSETHALF(2,RddV,fSATH(fGETHALF(2,RssV)-fGETHALF(3,RttV))); + fSETHALF(3,RddV,fSATH(fGETHALF(3,RssV)+fGETHALF(2,RttV))); +}) + + + + +Q6INSN(S4_vxaddsubhr,"Rdd32=vxaddsubh(Rss32,Rtt32):rnd:>>1:sat",ATTRIBS(), +"Cross vector add-sub halfwords with shift, round, and saturation", +{ + fSETHALF(0,RddV,fSATH((fGETHALF(0,RssV)+fGETHALF(1,RttV)+1)>>1)); + fSETHALF(1,RddV,fSATH((fGETHALF(1,RssV)-fGETHALF(0,RttV)+1)>>1)); + + fSETHALF(2,RddV,fSATH((fGETHALF(2,RssV)+fGETHALF(3,RttV)+1)>>1)); + fSETHALF(3,RddV,fSATH((fGETHALF(3,RssV)-fGETHALF(2,RttV)+1)>>1)); + +}) +Q6INSN(S4_vxsubaddhr,"Rdd32=vxsubaddh(Rss32,Rtt32):rnd:>>1:sat",ATTRIBS(), +"Cross vector sub-add halfwords with shift, round, and saturation", +{ + fSETHALF(0,RddV,fSATH((fGETHALF(0,RssV)-fGETHALF(1,RttV)+1)>>1)); + fSETHALF(1,RddV,fSATH((fGETHALF(1,RssV)+fGETHALF(0,RttV)+1)>>1)); + + fSETHALF(2,RddV,fSATH((fGETHALF(2,RssV)-fGETHALF(3,RttV)+1)>>1)); + fSETHALF(3,RddV,fSATH((fGETHALF(3,RssV)+fGETHALF(2,RttV)+1)>>1)); +}) + + + + + +/**********************************************/ +/* 1/2 Vector operations */ +/**********************************************/ + + +Q6INSN(A2_svavgh,"Rd32=vavgh(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Avg vector of half integers", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,((fGETHALF(i,RsV)+fGETHALF(i,RtV))>>1)); + } +}) + +Q6INSN(A2_svavghs,"Rd32=vavgh(Rs32,Rt32):rnd",ATTRIBS(A_ARCHV2), +"Avg vector of half integers with rounding", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,((fGETHALF(i,RsV)+fGETHALF(i,RtV)+1)>>1)); + } +}) + + + +Q6INSN(A2_svnavgh,"Rd32=vnavgh(Rt32,Rs32)",ATTRIBS(A_ARCHV2), +"Avg vector of half integers", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,((fGETHALF(i,RtV)-fGETHALF(i,RsV))>>1)); + } +}) + + +Q6INSN(A2_svaddh,"Rd32=vaddh(Rs32,Rt32)",ATTRIBS(), +"Add vector of half integers", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,fGETHALF(i,RsV)+fGETHALF(i,RtV)); + } +}) + +Q6INSN(A2_svaddhs,"Rd32=vaddh(Rs32,Rt32):sat",ATTRIBS(), +"Add vector of half integers with saturation", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,fSATN(16,fGETHALF(i,RsV)+fGETHALF(i,RtV))); + } +}) + +Q6INSN(A2_svadduhs,"Rd32=vadduh(Rs32,Rt32):sat",ATTRIBS(), +"Add vector of unsigned half integers with saturation", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,fSATUN(16,fGETUHALF(i,RsV)+fGETUHALF(i,RtV))); + } +}) + + +Q6INSN(A2_svsubh,"Rd32=vsubh(Rt32,Rs32)",ATTRIBS(), +"Sub vector of half integers", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,fGETHALF(i,RtV)-fGETHALF(i,RsV)); + } +}) + +Q6INSN(A2_svsubhs,"Rd32=vsubh(Rt32,Rs32):sat",ATTRIBS(), +"Sub vector of half integers with saturation", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,fSATN(16,fGETHALF(i,RtV)-fGETHALF(i,RsV))); + } +}) + +Q6INSN(A2_svsubuhs,"Rd32=vsubuh(Rt32,Rs32):sat",ATTRIBS(), +"Sub vector of unsigned half integers with saturation", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,fSATUN(16,fGETUHALF(i,RtV)-fGETUHALF(i,RsV))); + } +}) + + + + +/**********************************************/ +/* Vector Reduce Add */ +/**********************************************/ + +Q6INSN(A2_vraddub,"Rdd32=vraddub(Rss32,Rtt32)",ATTRIBS(), +"Sum: two vectors of unsigned bytes", +{ + fHIDE(int i;) + RddV = 0; + for (i=0;i<4;i++) { + fSETWORD(0,RddV,(fGETWORD(0,RddV) + (fGETUBYTE(i,RssV)+fGETUBYTE(i,RttV)))); + } + for (i=4;i<8;i++) { + fSETWORD(1,RddV,(fGETWORD(1,RddV) + (fGETUBYTE(i,RssV)+fGETUBYTE(i,RttV)))); + } +}) + +Q6INSN(A2_vraddub_acc,"Rxx32+=vraddub(Rss32,Rtt32)",ATTRIBS(), +"Sum: two vectors of unsigned bytes", +{ + fHIDE(int i;) + for (i = 0; i < 4; i++) { + fSETWORD(0,RxxV,(fGETWORD(0,RxxV) + (fGETUBYTE(i,RssV)+fGETUBYTE(i,RttV)))); + } + for (i = 4; i < 8; i++) { + fSETWORD(1,RxxV,(fGETWORD(1,RxxV) + (fGETUBYTE(i,RssV)+fGETUBYTE(i,RttV)))); + } +}) + + + +Q6INSN(M2_vraddh,"Rd32=vraddh(Rss32,Rtt32)",ATTRIBS(A_ARCHV3), +"Sum: two vectors of halves", +{ + fHIDE(int i;) + RdV = 0; + for (i=0;i<4;i++) { + RdV += (fGETHALF(i,RssV)+fGETHALF(i,RttV)); + } +}) + +Q6INSN(M2_vradduh,"Rd32=vradduh(Rss32,Rtt32)",ATTRIBS(A_ARCHV3), +"Sum: two vectors of unsigned halves", +{ + fHIDE(int i;) + RdV = 0; + for (i=0;i<4;i++) { + RdV += (fGETUHALF(i,RssV)+fGETUHALF(i,RttV)); + } +}) + +/**********************************************/ +/* Vector Sub */ +/**********************************************/ + +Q6INSN(A2_vsubub,"Rdd32=vsubub(Rtt32,Rss32)",ATTRIBS(), +"Sub vector of bytes", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBYTE(i,RddV,(fGETUBYTE(i,RttV)-fGETUBYTE(i,RssV))); + } +}) + +Q6INSN(A2_vsububs,"Rdd32=vsubub(Rtt32,Rss32):sat",ATTRIBS(), +"Sub vector of bytes", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBYTE(i,RddV,fSATUN(8,fGETUBYTE(i,RttV)-fGETUBYTE(i,RssV))); + } +}) + +Q6INSN(A2_vsubh,"Rdd32=vsubh(Rtt32,Rss32)",ATTRIBS(), +"Sub vector of half integers", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fGETHALF(i,RttV)-fGETHALF(i,RssV)); + } +}) + +Q6INSN(A2_vsubhs,"Rdd32=vsubh(Rtt32,Rss32):sat",ATTRIBS(), +"Sub vector of half integers with saturation", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fSATN(16,fGETHALF(i,RttV)-fGETHALF(i,RssV))); + } +}) + +Q6INSN(A2_vsubuhs,"Rdd32=vsubuh(Rtt32,Rss32):sat",ATTRIBS(), +"Sub vector of unsigned half integers with saturation", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fSATUN(16,fGETUHALF(i,RttV)-fGETUHALF(i,RssV))); + } +}) + +Q6INSN(A2_vsubw,"Rdd32=vsubw(Rtt32,Rss32)",ATTRIBS(), +"Sub vector of words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,fGETWORD(i,RttV)-fGETWORD(i,RssV)); + } +}) + +Q6INSN(A2_vsubws,"Rdd32=vsubw(Rtt32,Rss32):sat",ATTRIBS(), +"Sub vector of words with saturation", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,fSATN(32,fGETWORD(i,RttV)-fGETWORD(i,RssV))); + } +}) + + + + +/**********************************************/ +/* Vector Abs */ +/**********************************************/ + +Q6INSN(A2_vabsh,"Rdd32=vabsh(Rss32)",ATTRIBS(), +"Negate vector of half integers", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fABS(fGETHALF(i,RssV))); + } +}) + +Q6INSN(A2_vabshsat,"Rdd32=vabsh(Rss32):sat",ATTRIBS(), +"Negate vector of half integers", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fSATH(fABS(fGETHALF(i,RssV)))); + } +}) + +Q6INSN(A2_vabsw,"Rdd32=vabsw(Rss32)",ATTRIBS(), +"Absolute Value vector of words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,fABS(fGETWORD(i,RssV))); + } +}) + +Q6INSN(A2_vabswsat,"Rdd32=vabsw(Rss32):sat",ATTRIBS(), +"Absolute Value vector of words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,fSAT(fABS(fGETWORD(i,RssV)))); + } +}) + +/**********************************************/ +/* Vector SAD */ +/**********************************************/ + + +Q6INSN(M2_vabsdiffw,"Rdd32=vabsdiffw(Rtt32,Rss32)",ATTRIBS(A_ARCHV2), +"Absolute Differences: vector of words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,fABS(fGETWORD(i,RttV) - fGETWORD(i,RssV))); + } +}) + +Q6INSN(M2_vabsdiffh,"Rdd32=vabsdiffh(Rtt32,Rss32)",ATTRIBS(A_ARCHV2), +"Absolute Differences: vector of halfwords", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fABS(fGETHALF(i,RttV) - fGETHALF(i,RssV))); + } +}) + +Q6INSN(M6_vabsdiffb,"Rdd32=vabsdiffb(Rtt32,Rss32)",ATTRIBS(), +"Absolute Differences: vector of halfwords", +{ + fHIDE(int i;) + for (i=0;i<8;i++) { + fSETBYTE(i,RddV,fABS(fGETBYTE(i,RttV) - fGETBYTE(i,RssV))); + } +}) + +Q6INSN(M6_vabsdiffub,"Rdd32=vabsdiffub(Rtt32,Rss32)",ATTRIBS(), +"Absolute Differences: vector of halfwords", +{ + fHIDE(int i;) + for (i=0;i<8;i++) { + fSETBYTE(i,RddV,fABS(fGETUBYTE(i,RttV) - fGETUBYTE(i,RssV))); + } +}) + + + +Q6INSN(A2_vrsadub,"Rdd32=vrsadub(Rss32,Rtt32)",ATTRIBS(), +"Sum of Absolute Differences: vector of unsigned bytes", +{ + fHIDE(int i;) + RddV = 0; + for (i = 0; i < 4; i++) { + fSETWORD(0,RddV,(fGETWORD(0,RddV) + fABS((fGETUBYTE(i,RssV) - fGETUBYTE(i,RttV))))); + } + for (i = 4; i < 8; i++) { + fSETWORD(1,RddV,(fGETWORD(1,RddV) + fABS((fGETUBYTE(i,RssV) - fGETUBYTE(i,RttV))))); + } +}) + +Q6INSN(A2_vrsadub_acc,"Rxx32+=vrsadub(Rss32,Rtt32)",ATTRIBS(), +"Sum of Absolute Differences: vector of unsigned bytes", +{ + fHIDE(int i;) + for (i = 0; i < 4; i++) { + fSETWORD(0,RxxV,(fGETWORD(0,RxxV) + fABS((fGETUBYTE(i,RssV) - fGETUBYTE(i,RttV))))); + } + for (i = 4; i < 8; i++) { + fSETWORD(1,RxxV,(fGETWORD(1,RxxV) + fABS((fGETUBYTE(i,RssV) - fGETUBYTE(i,RttV))))); + } +}) + + +/**********************************************/ +/* Vector Average */ +/**********************************************/ + +Q6INSN(A2_vavgub,"Rdd32=vavgub(Rss32,Rtt32)",ATTRIBS(), +"Average vector of unsigned bytes", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBYTE(i,RddV,((fGETUBYTE(i,RssV) + fGETUBYTE(i,RttV))>>1)); + } +}) + +Q6INSN(A2_vavguh,"Rdd32=vavguh(Rss32,Rtt32)",ATTRIBS(), +"Average vector of unsigned halfwords", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,(fGETUHALF(i,RssV)+fGETUHALF(i,RttV))>>1); + } +}) + +Q6INSN(A2_vavgh,"Rdd32=vavgh(Rss32,Rtt32)",ATTRIBS(), +"Average vector of halfwords", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,(fGETHALF(i,RssV)+fGETHALF(i,RttV))>>1); + } +}) + +Q6INSN(A2_vnavgh,"Rdd32=vnavgh(Rtt32,Rss32)",ATTRIBS(), +"Negative Average vector of halfwords", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,(fGETHALF(i,RttV)-fGETHALF(i,RssV))>>1); + } +}) + +Q6INSN(A2_vavgw,"Rdd32=vavgw(Rss32,Rtt32)",ATTRIBS(), +"Average vector of words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,(fSXTN(32,33,fGETWORD(i,RssV))+fSXTN(32,33,fGETWORD(i,RttV)))>>1); + } +}) + +Q6INSN(A2_vnavgw,"Rdd32=vnavgw(Rtt32,Rss32)",ATTRIBS(A_ARCHV2), +"Average vector of words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,(fSXTN(32,33,fGETWORD(i,RttV))-fSXTN(32,33,fGETWORD(i,RssV)))>>1); + } +}) + +Q6INSN(A2_vavgwr,"Rdd32=vavgw(Rss32,Rtt32):rnd",ATTRIBS(), +"Average vector of words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,(fSXTN(32,33,fGETWORD(i,RssV))+fSXTN(32,33,fGETWORD(i,RttV))+1)>>1); + } +}) + +Q6INSN(A2_vnavgwr,"Rdd32=vnavgw(Rtt32,Rss32):rnd:sat",ATTRIBS(A_ARCHV2), +"Average vector of words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,fSAT((fSXTN(32,33,fGETWORD(i,RttV))-fSXTN(32,33,fGETWORD(i,RssV))+1)>>1)); + } +}) + +Q6INSN(A2_vavgwcr,"Rdd32=vavgw(Rss32,Rtt32):crnd",ATTRIBS(A_ARCHV2), +"Average vector of words with convergent rounding", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,(fCRND(fSXTN(32,33,fGETWORD(i,RssV))+fSXTN(32,33,fGETWORD(i,RttV)))>>1)); + } +}) + +Q6INSN(A2_vnavgwcr,"Rdd32=vnavgw(Rtt32,Rss32):crnd:sat",ATTRIBS(A_ARCHV2), +"Average negative vector of words with convergent rounding", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,fSAT(fCRND(fSXTN(32,33,fGETWORD(i,RttV))-fSXTN(32,33,fGETWORD(i,RssV)))>>1)); + } +}) + +Q6INSN(A2_vavghcr,"Rdd32=vavgh(Rss32,Rtt32):crnd",ATTRIBS(A_ARCHV2), +"Average vector of halfwords with conv rounding", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fCRND(fGETHALF(i,RssV)+fGETHALF(i,RttV))>>1); + } +}) + +Q6INSN(A2_vnavghcr,"Rdd32=vnavgh(Rtt32,Rss32):crnd:sat",ATTRIBS(A_ARCHV2), +"Average negative vector of halfwords with conv rounding", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fSATH(fCRND(fGETHALF(i,RttV)-fGETHALF(i,RssV))>>1)); + } +}) + + +Q6INSN(A2_vavguw,"Rdd32=vavguw(Rss32,Rtt32)",ATTRIBS(), +"Average vector of unsigned words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,(fZXTN(32,33,fGETUWORD(i,RssV))+fZXTN(32,33,fGETUWORD(i,RttV)))>>1); + } +}) + +Q6INSN(A2_vavguwr,"Rdd32=vavguw(Rss32,Rtt32):rnd",ATTRIBS(), +"Average vector of unsigned words", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,(fZXTN(32,33,fGETUWORD(i,RssV))+fZXTN(32,33,fGETUWORD(i,RttV))+1)>>1); + } +}) + +Q6INSN(A2_vavgubr,"Rdd32=vavgub(Rss32,Rtt32):rnd",ATTRIBS(), +"Average vector of unsigned bytes", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBYTE(i,RddV,((fGETUBYTE(i,RssV)+fGETUBYTE(i,RttV)+1)>>1)); + } +}) + +Q6INSN(A2_vavguhr,"Rdd32=vavguh(Rss32,Rtt32):rnd",ATTRIBS(), +"Average vector of unsigned halfwords with rounding", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,(fGETUHALF(i,RssV)+fGETUHALF(i,RttV)+1)>>1); + } +}) + +Q6INSN(A2_vavghr,"Rdd32=vavgh(Rss32,Rtt32):rnd",ATTRIBS(), +"Average vector of halfwords with rounding", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,(fGETHALF(i,RssV)+fGETHALF(i,RttV)+1)>>1); + } +}) + +Q6INSN(A2_vnavghr,"Rdd32=vnavgh(Rtt32,Rss32):rnd:sat",ATTRIBS(A_ARCHV2), +"Negative Average vector of halfwords with rounding", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV,fSATH((fGETHALF(i,RttV)-fGETHALF(i,RssV)+1)>>1)); + } +}) + + +/* Rounding Instruction */ + +Q6INSN(A4_round_ri,"Rd32=round(Rs32,#u5)",ATTRIBS(),"Round", {RdV = fRNDN(RsV,uiV)>>uiV; }) +Q6INSN(A4_round_rr,"Rd32=round(Rs32,Rt32)",ATTRIBS(),"Round", {RdV = fRNDN(RsV,fZXTN(5,32,RtV))>>fZXTN(5,32,RtV); }) +Q6INSN(A4_round_ri_sat,"Rd32=round(Rs32,#u5):sat",ATTRIBS(),"Round", {RdV = (fSAT(fRNDN(RsV,uiV)))>>uiV; }) +Q6INSN(A4_round_rr_sat,"Rd32=round(Rs32,Rt32):sat",ATTRIBS(),"Round", {RdV = (fSAT(fRNDN(RsV,fZXTN(5,32,RtV))))>>fZXTN(5,32,RtV); }) + + +Q6INSN(A4_cround_ri,"Rd32=cround(Rs32,#u5)",ATTRIBS(),"Convergent Round", {RdV = fCRNDN(RsV,uiV); }) +Q6INSN(A4_cround_rr,"Rd32=cround(Rs32,Rt32)",ATTRIBS(),"Convergent Round", {RdV = fCRNDN(RsV,fZXTN(5,32,RtV)); }) + + +#define CROUND(DST,SRC,SHIFT) \ + fHIDE(size16s_t rndbit_128;)\ + fHIDE(size16s_t tmp128;)\ + fHIDE(size16s_t src_128;)\ + if (SHIFT == 0) { \ + DST = SRC;\ + } else if ((SRC & (size8s_t)((1LL << (SHIFT - 1)) - 1LL)) == 0) { \ + src_128 = fCAST8S_16S(SRC);\ + rndbit_128 = fCAST8S_16S(1LL);\ + rndbit_128 = fSHIFTL128(rndbit_128, SHIFT);\ + rndbit_128 = fAND128(rndbit_128, src_128);\ + rndbit_128 = fSHIFTR128(rndbit_128, 1);\ + tmp128 = fADD128(src_128, rndbit_128);\ + tmp128 = fSHIFTR128(tmp128, SHIFT);\ + DST = fCAST16S_8S(tmp128);\ + } else {\ + size16s_t rndbit_128 = fCAST8S_16S((1LL << (SHIFT - 1))); \ + size16s_t src_128 = fCAST8S_16S(SRC); \ + size16s_t tmp128 = fADD128(src_128, rndbit_128);\ + tmp128 = fSHIFTR128(tmp128, SHIFT);\ + DST = fCAST16S_8S(tmp128);\ + } + +Q6INSN(A7_croundd_ri,"Rdd32=cround(Rss32,#u6)",ATTRIBS(),"Convergent Round", +{ +CROUND(RddV,RssV,uiV); +}) + +Q6INSN(A7_croundd_rr,"Rdd32=cround(Rss32,Rt32)",ATTRIBS(),"Convergent Round", +{ +CROUND(RddV,RssV,fZXTN(6,32,RtV)); +}) + + + + + + + + + +Q6INSN(A7_clip,"Rd32=clip(Rs32,#u5)",ATTRIBS(),"Clip to #s5", { fCLIP(RdV,RsV,uiV);}) +Q6INSN(A7_vclip,"Rdd32=vclip(Rss32,#u5)",ATTRIBS(),"Clip to #s5", +{ +fHIDE(size4s_t tmp;) +fCLIP(tmp, fGETWORD(0, RssV), uiV); +fSETWORD(0, RddV, tmp); +fCLIP(tmp,fGETWORD(1, RssV), uiV); +fSETWORD(1, RddV, tmp); +} +) + + + +/**********************************************/ +/* V4: Cross Vector Min/Max */ +/**********************************************/ + + +#define VRMINORMAX(TAG,STR,OP,SHORTTYPE,SETTYPE,GETTYPE,NEL,SHIFT) \ +Q6INSN(A4_vr##TAG##SHORTTYPE,"Rxx32=vr"#TAG#SHORTTYPE"(Rss32,Ru32)",ATTRIBS(), \ +"Choose " STR " elements of a vector", \ +{ \ + fHIDE(int i; size8s_t TAG; size4s_t addr;) \ + TAG = fGET##GETTYPE(0,RxxV); \ + addr = fGETWORD(1,RxxV); \ + for (i = 0; i < NEL; i++) { \ + if (TAG OP fGET##GETTYPE(i,RssV)) { \ + TAG = fGET##GETTYPE(i,RssV); \ + addr = RuV | i<,SHORTTYPE,SETTYPE,GETTYPE,NEL,SHIFT) \ +VRMINORMAX(max,"maximum",<,SHORTTYPE,SETTYPE,GETTYPE,NEL,SHIFT) + + +RMINMAX(h,HALF,HALF,4,1) +RMINMAX(uh,HALF,UHALF,4,1) +RMINMAX(w,WORD,WORD,2,2) +RMINMAX(uw,WORD,UWORD,2,2) + +#undef RMINMAX +#undef VRMINORMAX + +/**********************************************/ +/* Vector Min/Max */ +/**********************************************/ + +#define VMINORMAX(TAG,STR,FUNC,SHORTTYPE,SETTYPE,GETTYPE,NEL) \ +Q6INSN(A2_v##TAG##SHORTTYPE,"Rdd32=v"#TAG#SHORTTYPE"(Rtt32,Rss32)",ATTRIBS(), \ +"Choose " STR " elements of two vectors", \ +{ \ + fHIDE(int i;) \ + for (i = 0; i < NEL; i++) { \ + fSET##SETTYPE(i,RddV,FUNC(fGET##GETTYPE(i,RttV),fGET##GETTYPE(i,RssV))); \ + } \ +}) + +#define VMINORMAX3(TAG,STR,FUNC,SHORTTYPE,SETTYPE,GETTYPE,NEL) \ +Q6INSN(A6_v##TAG##SHORTTYPE##3,"Rxx32=v"#TAG#SHORTTYPE"3(Rtt32,Rss32)",ATTRIBS(), \ +"Choose " STR " elements of two vectors", \ +{ \ + fHIDE(int i;) \ + for (i = 0; i < NEL; i++) { \ + fSET##SETTYPE(i,RxxV,FUNC(fGET##GETTYPE(i,RxxV),FUNC(fGET##GETTYPE(i,RttV),fGET##GETTYPE(i,RssV)))); \ + } \ +}) + +#define MINMAX(SHORTTYPE,SETTYPE,GETTYPE,NEL) \ +VMINORMAX(min,"minimum",fMIN,SHORTTYPE,SETTYPE,GETTYPE,NEL) \ +VMINORMAX(max,"maximum",fMAX,SHORTTYPE,SETTYPE,GETTYPE,NEL) + +MINMAX(b,BYTE,BYTE,8) +MINMAX(ub,BYTE,UBYTE,8) +MINMAX(h,HALF,HALF,4) +MINMAX(uh,HALF,UHALF,4) +MINMAX(w,WORD,WORD,2) +MINMAX(uw,WORD,UWORD,2) + +#undef MINMAX +#undef VMINORMAX +#undef VMINORMAX3 + + +/**********************************************/ +/* Vector Min/Max */ +/**********************************************/ + + +Q6INSN(A4_modwrapu,"Rd32=modwrap(Rs32,Rt32)",ATTRIBS(), +"Wrap to an unsigned modulo buffer", +{ + if (RsV < 0) { + RdV = RsV + fCAST4u(RtV); + } else if (fCAST4u(RsV) >= fCAST4u(RtV)) { + RdV = RsV - fCAST4u(RtV); + } else { + RdV = RsV; + } +}) diff --git a/target/hexagon/imported/branch.idef b/target/hexagon/imported/branch.idef new file mode 100644 index 0000000000..88f5f48cce --- /dev/null +++ b/target/hexagon/imported/branch.idef @@ -0,0 +1,326 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + + +/*********************************************/ +/* Jump instructions */ +/*********************************************/ + +#define A_JDIR A_JUMP +#define A_CJNEWDIR A_JUMP +#define A_CJOLDDIR A_JUMP +#define A_NEWVALUEJ A_JUMP,A_DOTNEWVALUE,A_MEMLIKE_PACKET_RULES +#define A_JINDIR A_JUMP,A_INDIRECT +#define A_JINDIRNEW A_JUMP,A_INDIRECT +#define A_JINDIROLD A_JUMP,A_INDIRECT + +Q6INSN(J2_jump,"jump #r22:2",ATTRIBS(A_JDIR), "direct unconditional jump", +{fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}) + +Q6INSN(J2_jumpr,"jumpr Rs32",ATTRIBS(A_JINDIR), "indirect unconditional jump", +{fJUMPR(RsN,RsV,COF_TYPE_JUMPR);}) + +#define OLDCOND_JUMP(TAG,OPER,OPER2,ATTRIB,DESCR,SEMANTICS) \ +Q6INSN(TAG##t,"if (Pu4) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_NOT_TAKEN,12,0); if (fLSBOLD(PuV)) { SEMANTICS; }}) \ +Q6INSN(TAG##f,"if (!Pu4) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_NOT_TAKEN,12,0); if (fLSBOLDNOT(PuV)) { SEMANTICS; }}) \ +Q6INSN(TAG##tpt,"if (Pu4) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_TAKEN,12,0); if (fLSBOLD(PuV)) { SEMANTICS; }}) \ +Q6INSN(TAG##fpt,"if (!Pu4) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_TAKEN,12,0); if (fLSBOLDNOT(PuV)) { SEMANTICS; }}) + +OLDCOND_JUMP(J2_jump,"jump","#r15:2",ATTRIBS(A_CJOLDDIR),"direct conditional jump", +fIMMEXT(riV);fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);) + +OLDCOND_JUMP(J2_jumpr,"jumpr","Rs32",ATTRIBS(A_JINDIROLD),"indirect conditional jump", +fJUMPR(RsN,RsV,COF_TYPE_JUMPR);) + +#define NEWCOND_JUMP(TAG,OPER,OPER2,ATTRIB,DESCR,SEMANTICS)\ +Q6INSN(TAG##tnew,"if (Pu4.new) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEW(PuN),, SPECULATE_NOT_TAKEN , 12,0)} {if(fLSBNEW(PuN)){SEMANTICS;}})\ +Q6INSN(TAG##fnew,"if (!Pu4.new) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEWNOT(PuN),, SPECULATE_NOT_TAKEN , 12,0)} {if(fLSBNEWNOT(PuN)){SEMANTICS;}})\ +Q6INSN(TAG##tnewpt,"if (Pu4.new) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEW(PuN),, SPECULATE_TAKEN , 12,0)} {if(fLSBNEW(PuN)){SEMANTICS;}})\ +Q6INSN(TAG##fnewpt,"if (!Pu4.new) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEWNOT(PuN),, SPECULATE_TAKEN , 12,0)} {if(fLSBNEWNOT(PuN)){SEMANTICS;}}) + +NEWCOND_JUMP(J2_jump,"jump","#r15:2",ATTRIBS(A_CJNEWDIR,A_ARCHV2),"direct conditional jump", +fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMPNEW);) + +NEWCOND_JUMP(J2_jumpr,"jumpr","Rs32",ATTRIBS(A_JINDIRNEW,A_ARCHV3),"indirect conditional jump", +fJUMPR(RsN,RsV,COF_TYPE_JUMPR);) + + + +Q6INSN(J4_hintjumpr,"hintjr(Rs32)",ATTRIBS(A_JINDIR),"hint indirect conditional jump", +{fHINTJR(RsV);}) + + +/*********************************************/ +/* Compound Compare-Jumps */ +/*********************************************/ +Q6INSN(J2_jumprz,"if (Rs32!=#0) jump:nt #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register true", +{fBRANCH_SPECULATE_STALL((RsV!=0), , SPECULATE_NOT_TAKEN,12,0) if (RsV != 0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) + +Q6INSN(J2_jumprnz,"if (Rs32==#0) jump:nt #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register false", +{fBRANCH_SPECULATE_STALL((RsV==0), , SPECULATE_NOT_TAKEN,12,0) if (RsV == 0) {fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) + +Q6INSN(J2_jumprzpt,"if (Rs32!=#0) jump:t #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register true", +{fBRANCH_SPECULATE_STALL((RsV!=0), , SPECULATE_TAKEN,12,0) if (RsV != 0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) + +Q6INSN(J2_jumprnzpt,"if (Rs32==#0) jump:t #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register false", +{fBRANCH_SPECULATE_STALL((RsV==0), , SPECULATE_TAKEN,12,0) if (RsV == 0) {fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) + +Q6INSN(J2_jumprgtez,"if (Rs32>=#0) jump:nt #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register greater or equal to zero", +{fBRANCH_SPECULATE_STALL((RsV>=0), , SPECULATE_NOT_TAKEN,12,0) if (RsV>=0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) + +Q6INSN(J2_jumprgtezpt,"if (Rs32>=#0) jump:t #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register greater or equal to zero", +{fBRANCH_SPECULATE_STALL((RsV>=0), , SPECULATE_TAKEN,12,0) if (RsV>=0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) + +Q6INSN(J2_jumprltez,"if (Rs32<=#0) jump:nt #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register less than or equal to zero", +{fBRANCH_SPECULATE_STALL((RsV<=0), , SPECULATE_NOT_TAKEN,12,0) if (RsV<=0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) + +Q6INSN(J2_jumprltezpt,"if (Rs32<=#0) jump:t #r13:2",ATTRIBS(A_CJNEWDIR,A_ARCHV3),"direct conditional jump if register less than or equal to zero", +{fBRANCH_SPECULATE_STALL((RsV<=0), , SPECULATE_TAKEN,12,0) if (RsV<=0) { fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) + + + +/*********************************************/ +/* V4 Compound Compare-Jumps */ +/*********************************************/ + + +/* V4 compound compare jumps (CJ) */ +#define STD_CMPJUMP(TAG,TST,TSTSEM)\ +Q6INSN(J4_##TAG##_tp0_jump_nt, "p0="TST"; if (p0.new) jump:nt #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P0(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW0,,SPECULATE_NOT_TAKEN,13,0) if (fLSBNEW0) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ +Q6INSN(J4_##TAG##_fp0_jump_nt, "p0="TST"; if (!p0.new) jump:nt #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump",{fPART1(fWRITE_P0(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW0NOT,,SPECULATE_NOT_TAKEN,13,0) if (fLSBNEW0NOT) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ +Q6INSN(J4_##TAG##_tp0_jump_t, "p0="TST"; if (p0.new) jump:t #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P0(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW0,,SPECULATE_TAKEN,13,0) if (fLSBNEW0) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ +Q6INSN(J4_##TAG##_fp0_jump_t, "p0="TST"; if (!p0.new) jump:t #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P0(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW0NOT,,SPECULATE_TAKEN,13,0) if (fLSBNEW0NOT) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ +Q6INSN(J4_##TAG##_tp1_jump_nt, "p1="TST"; if (p1.new) jump:nt #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P1(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW1,,SPECULATE_NOT_TAKEN,13,0) if (fLSBNEW1) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ +Q6INSN(J4_##TAG##_fp1_jump_nt, "p1="TST"; if (!p1.new) jump:nt #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump",{fPART1(fWRITE_P1(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW1NOT,,SPECULATE_NOT_TAKEN,13,0) if (fLSBNEW1NOT) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ +Q6INSN(J4_##TAG##_tp1_jump_t, "p1="TST"; if (p1.new) jump:t #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P1(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW1,,SPECULATE_TAKEN,13,0) if (fLSBNEW1) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ +Q6INSN(J4_##TAG##_fp1_jump_t, "p1="TST"; if (!p1.new) jump:t #r9:2", ATTRIBS(A_CJNEWDIR,A_NEWCMPJUMP),"compound compare-jump", {fPART1(fWRITE_P1(f8BITSOF(TSTSEM))) fBRANCH_SPECULATE_STALL(fLSBNEW1NOT,,SPECULATE_TAKEN,13,0) if (fLSBNEW1NOT) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) + + +STD_CMPJUMP(cmpeqi,"cmp.eq(Rs16,#U5)",(RsV==UiV)) +STD_CMPJUMP(cmpgti,"cmp.gt(Rs16,#U5)",(RsV>UiV)) +STD_CMPJUMP(cmpgtui,"cmp.gtu(Rs16,#U5)",(fCAST4u(RsV)>UiV)) + +STD_CMPJUMP(cmpeqn1,"cmp.eq(Rs16,#-1)",(RsV==-1)) +STD_CMPJUMP(cmpgtn1,"cmp.gt(Rs16,#-1)",(RsV>-1)) +STD_CMPJUMP(tstbit0,"tstbit(Rs16,#0)",(RsV & 1)) + +STD_CMPJUMP(cmpeq,"cmp.eq(Rs16,Rt16)",(RsV==RtV)) +STD_CMPJUMP(cmpgt,"cmp.gt(Rs16,Rt16)",(RsV>RtV)) +STD_CMPJUMP(cmpgtu,"cmp.gtu(Rs16,Rt16)",(fCAST4u(RsV)>RtV)) + + + +/* V4 jump and transfer (CJ) */ +Q6INSN(J4_jumpseti,"Rd16=#U6 ; jump #r9:2",ATTRIBS(A_JDIR), "direct unconditional jump and set register to immediate", +{fIMMEXT(riV); fPCALIGN(riV); RdV=UiV; fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}) + +Q6INSN(J4_jumpsetr,"Rd16=Rs16 ; jump #r9:2",ATTRIBS(A_JDIR), "direct unconditional jump and transfer register", +{fIMMEXT(riV); fPCALIGN(riV); RdV=RsV; fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}) + + +/* V4 new-value jumps (NCJ) */ +#define STD_CMPJUMPNEWRS(TAG,TST,TSTSEM)\ +Q6INSN(J4_##TAG##_jumpnv_t, "if ("TST") jump:t #r9:2", ATTRIBS(A_NEWVALUEJ),"compound compare-jump",{fBRANCH_SPECULATE_STALL(TSTSEM,,SPECULATE_TAKEN,13,0);if (TSTSEM) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}})\ +Q6INSN(J4_##TAG##_jumpnv_nt,"if ("TST") jump:nt #r9:2",ATTRIBS(A_NEWVALUEJ),"compound compare-jump",{fBRANCH_SPECULATE_STALL(TSTSEM,,SPECULATE_NOT_TAKEN,13,0); if (TSTSEM) {fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);}}) + + + + +STD_CMPJUMPNEWRS(cmpeqi_t,"cmp.eq(Ns8.new,#U5)",(fNEWREG(NsN)==(UiV))) +STD_CMPJUMPNEWRS(cmpeqi_f,"!cmp.eq(Ns8.new,#U5)",(fNEWREG(NsN)!=(UiV))) +STD_CMPJUMPNEWRS(cmpgti_t,"cmp.gt(Ns8.new,#U5)",(fNEWREG(NsN)>(UiV))) +STD_CMPJUMPNEWRS(cmpgti_f,"!cmp.gt(Ns8.new,#U5)",!(fNEWREG(NsN)>(UiV))) +STD_CMPJUMPNEWRS(cmpgtui_t,"cmp.gtu(Ns8.new,#U5)",(fCAST4u(fNEWREG(NsN))>(UiV))) +STD_CMPJUMPNEWRS(cmpgtui_f,"!cmp.gtu(Ns8.new,#U5)",!(fCAST4u(fNEWREG(NsN))>(UiV))) + + +STD_CMPJUMPNEWRS(cmpeqn1_t,"cmp.eq(Ns8.new,#-1)",(fNEWREG(NsN)==(-1))) +STD_CMPJUMPNEWRS(cmpeqn1_f,"!cmp.eq(Ns8.new,#-1)",(fNEWREG(NsN)!=(-1))) +STD_CMPJUMPNEWRS(cmpgtn1_t,"cmp.gt(Ns8.new,#-1)",(fNEWREG(NsN)>(-1))) +STD_CMPJUMPNEWRS(cmpgtn1_f,"!cmp.gt(Ns8.new,#-1)",!(fNEWREG(NsN)>(-1))) +STD_CMPJUMPNEWRS(tstbit0_t,"tstbit(Ns8.new,#0)",((fNEWREG(NsN)) & 1)) +STD_CMPJUMPNEWRS(tstbit0_f,"!tstbit(Ns8.new,#0)",!((fNEWREG(NsN)) & 1)) + + +STD_CMPJUMPNEWRS(cmpeq_t, "cmp.eq(Ns8.new,Rt32)", (fNEWREG(NsN)==RtV)) +STD_CMPJUMPNEWRS(cmpgt_t, "cmp.gt(Ns8.new,Rt32)", (fNEWREG(NsN)>RtV)) +STD_CMPJUMPNEWRS(cmpgtu_t,"cmp.gtu(Ns8.new,Rt32)",(fCAST4u(fNEWREG(NsN))>fCAST4u(RtV))) +STD_CMPJUMPNEWRS(cmplt_t, "cmp.gt(Rt32,Ns8.new)", (RtV>fNEWREG(NsN))) +STD_CMPJUMPNEWRS(cmpltu_t,"cmp.gtu(Rt32,Ns8.new)",(fCAST4u(RtV)>fCAST4u(fNEWREG(NsN)))) +STD_CMPJUMPNEWRS(cmpeq_f, "!cmp.eq(Ns8.new,Rt32)", (fNEWREG(NsN)!=RtV)) +STD_CMPJUMPNEWRS(cmpgt_f, "!cmp.gt(Ns8.new,Rt32)", !(fNEWREG(NsN)>RtV)) +STD_CMPJUMPNEWRS(cmpgtu_f,"!cmp.gtu(Ns8.new,Rt32)",!(fCAST4u(fNEWREG(NsN))>fCAST4u(RtV))) +STD_CMPJUMPNEWRS(cmplt_f, "!cmp.gt(Rt32,Ns8.new)", !(RtV>fNEWREG(NsN))) +STD_CMPJUMPNEWRS(cmpltu_f,"!cmp.gtu(Rt32,Ns8.new)",!(fCAST4u(RtV)>fCAST4u(fNEWREG(NsN)))) + + + + + +/*********************************************/ +/* Subroutine Call instructions */ +/*********************************************/ + +#define CDIR_STD A_CALL +#define CINDIR_STD A_CALL,A_INDIRECT + +Q6INSN(J2_call,"call #r22:2",ATTRIBS(CDIR_STD), "direct unconditional call", +{fIMMEXT(riV); fPCALIGN(riV); fCALL(fREAD_PC()+riV); }) + +Q6INSN(J2_callt,"if (Pu4) call #r15:2",ATTRIBS(CDIR_STD),"direct conditional call if true", +{fIMMEXT(riV); fPCALIGN(riV); fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_NOT_TAKEN,12,0); if (fLSBOLD(PuV)) { fCALL(fREAD_PC()+riV); }}) + +Q6INSN(J2_callf,"if (!Pu4) call #r15:2",ATTRIBS(CDIR_STD),"direct conditional call if false", +{fIMMEXT(riV); fPCALIGN(riV); fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_NOT_TAKEN,12,0);if (fLSBOLDNOT(PuV)) { fCALL(fREAD_PC()+riV); }}) + +Q6INSN(J2_callr,"callr Rs32",ATTRIBS(CINDIR_STD), "indirect unconditional call", +{ fCALLR(RsV); }) + +Q6INSN(J2_callrt,"if (Pu4) callr Rs32",ATTRIBS(CINDIR_STD),"indirect conditional call if true", +{fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_NOT_TAKEN,12,0);if (fLSBOLD(PuV)) { fCALLR(RsV); }}) + +Q6INSN(J2_callrf,"if (!Pu4) callr Rs32",ATTRIBS(CINDIR_STD),"indirect conditional call if false", +{fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_NOT_TAKEN,12,0);if (fLSBOLDNOT(PuV)) { fCALLR(RsV); }}) + + + + +/*********************************************/ +/* HW Loop instructions */ +/*********************************************/ + +Q6INSN(J2_loop0r,"loop0(#r7:2,Rs32)",ATTRIBS(),"Initialize HW loop 0", +{ fIMMEXT(riV); fPCALIGN(riV); + fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, RsV); + fSET_LPCFG(0); +}) + +Q6INSN(J2_loop1r,"loop1(#r7:2,Rs32)",ATTRIBS(),"Initialize HW loop 1", +{ fIMMEXT(riV); fPCALIGN(riV); + fWRITE_LOOP_REGS1(/*sa,lc*/ fREAD_PC()+riV, RsV); +}) + +Q6INSN(J2_loop0i,"loop0(#r7:2,#U10)",ATTRIBS(),"Initialize HW loop 0", +{ fIMMEXT(riV); fPCALIGN(riV); + fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, UiV); + fSET_LPCFG(0); +}) + +Q6INSN(J2_loop1i,"loop1(#r7:2,#U10)",ATTRIBS(),"Initialize HW loop 1", +{ fIMMEXT(riV); fPCALIGN(riV); + fWRITE_LOOP_REGS1(/*sa,lc*/ fREAD_PC()+riV, UiV); +}) + + +Q6INSN(J2_ploop1sr,"p3=sp1loop0(#r7:2,Rs32)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", +{ fIMMEXT(riV); fPCALIGN(riV); + fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, RsV); + fSET_LPCFG(1); + fWRITE_P3(0); +}) +Q6INSN(J2_ploop1si,"p3=sp1loop0(#r7:2,#U10)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", +{ fIMMEXT(riV); fPCALIGN(riV); + fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, UiV); + fSET_LPCFG(1); + fWRITE_P3(0); +}) + +Q6INSN(J2_ploop2sr,"p3=sp2loop0(#r7:2,Rs32)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", +{ fIMMEXT(riV); fPCALIGN(riV); + fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, RsV); + fSET_LPCFG(2); + fWRITE_P3(0); +}) +Q6INSN(J2_ploop2si,"p3=sp2loop0(#r7:2,#U10)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", +{ fIMMEXT(riV); fPCALIGN(riV); + fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, UiV); + fSET_LPCFG(2); + fWRITE_P3(0); +}) + +Q6INSN(J2_ploop3sr,"p3=sp3loop0(#r7:2,Rs32)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", +{ fIMMEXT(riV); fPCALIGN(riV); + fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, RsV); + fSET_LPCFG(3); + fWRITE_P3(0); +}) +Q6INSN(J2_ploop3si,"p3=sp3loop0(#r7:2,#U10)",ATTRIBS(A_ARCHV2),"Initialize HW loop 0", +{ fIMMEXT(riV); fPCALIGN(riV); + fWRITE_LOOP_REGS0(/*sa,lc*/ fREAD_PC()+riV, UiV); + fSET_LPCFG(3); + fWRITE_P3(0); +}) + + + +Q6INSN(J2_endloop01,"endloop01",ATTRIBS(A_HWLOOP0_END,A_HWLOOP1_END),"Loopend for inner and outer loop", +{ + + /* V2: With predicate control */ + if (fGET_LPCFG) { + fHIDE( if (fGET_LPCFG >= 2) { /* Nothing */ } else ) + if (fGET_LPCFG==1) { + fWRITE_P3(0xff); + } + fSET_LPCFG(fGET_LPCFG-1); + } + + /* check if iterate */ + if (fREAD_LC0>1) { + fBRANCH(fREAD_SA0,COF_TYPE_LOOPEND0); + /* decrement loop count */ + fWRITE_LC0(fREAD_LC0-1); + } else { + /* check if iterate */ + if (fREAD_LC1>1) { + fBRANCH(fREAD_SA1,COF_TYPE_LOOPEND1); + /* decrement loop count */ + fWRITE_LC1(fREAD_LC1-1); + } + } + +}) + +Q6INSN(J2_endloop0,"endloop0",ATTRIBS(A_HWLOOP0_END),"Loopend for inner loop", +{ + + /* V2: With predicate control */ + if (fGET_LPCFG) { + fHIDE( if (fGET_LPCFG >= 2) { /* Nothing */ } else ) + if (fGET_LPCFG==1) { + fWRITE_P3(0xff); + } + fSET_LPCFG(fGET_LPCFG-1); + } + + /* check if iterate */ + if (fREAD_LC0>1) { + fBRANCH(fREAD_SA0,COF_TYPE_LOOPEND0); + /* decrement loop count */ + fWRITE_LC0(fREAD_LC0-1); + } +}) + +Q6INSN(J2_endloop1,"endloop1",ATTRIBS(A_HWLOOP1_END),"Loopend for outer loop", +{ + /* check if iterate */ + if (fREAD_LC1>1) { + fBRANCH(fREAD_SA1,COF_TYPE_LOOPEND1); + /* decrement loop count */ + fWRITE_LC1(fREAD_LC1-1); + } +}) diff --git a/target/hexagon/imported/compare.idef b/target/hexagon/imported/compare.idef new file mode 100644 index 0000000000..3551467854 --- /dev/null +++ b/target/hexagon/imported/compare.idef @@ -0,0 +1,619 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Compare Instructions + */ + + + +/*********************************************/ +/* Scalar compare instructions */ +/*********************************************/ + +Q6INSN(C2_cmpeq,"Pd4=cmp.eq(Rs32,Rt32)",ATTRIBS(), +"Compare for Equal", +{PdV=f8BITSOF(RsV==RtV);}) + +Q6INSN(C2_cmpgt,"Pd4=cmp.gt(Rs32,Rt32)",ATTRIBS(), +"Compare for signed Greater Than", +{PdV=f8BITSOF(RsV>RtV);}) + +Q6INSN(C2_cmpgtu,"Pd4=cmp.gtu(Rs32,Rt32)",ATTRIBS(), +"Compare for Greater Than Unsigned", +{PdV=f8BITSOF(fCAST4u(RsV)>fCAST4u(RtV));}) + +Q6INSN(C2_cmpeqp,"Pd4=cmp.eq(Rss32,Rtt32)",ATTRIBS(), +"Compare for Equal", +{PdV=f8BITSOF(RssV==RttV);}) + +Q6INSN(C2_cmpgtp,"Pd4=cmp.gt(Rss32,Rtt32)",ATTRIBS(), +"Compare for signed Greater Than", +{PdV=f8BITSOF(RssV>RttV);}) + +Q6INSN(C2_cmpgtup,"Pd4=cmp.gtu(Rss32,Rtt32)",ATTRIBS(), +"Compare for Greater Than Unsigned", +{PdV=f8BITSOF(fCAST8u(RssV)>fCAST8u(RttV));}) + + + + +/*********************************************/ +/* Compare and put result in GPR */ +/* typically for function I/O */ +/*********************************************/ + +Q6INSN(A4_rcmpeqi,"Rd32=cmp.eq(Rs32,#s8)",ATTRIBS(), +"Compare for Equal", +{fIMMEXT(siV); RdV=(RsV==siV); }) + +Q6INSN(A4_rcmpneqi,"Rd32=!cmp.eq(Rs32,#s8)",ATTRIBS(), +"Compare for Equal", +{fIMMEXT(siV); RdV=(RsV!=siV); }) + + +Q6INSN(A4_rcmpeq,"Rd32=cmp.eq(Rs32,Rt32)",ATTRIBS(), +"Compare for Equal", +{RdV=(RsV==RtV); }) + +Q6INSN(A4_rcmpneq,"Rd32=!cmp.eq(Rs32,Rt32)",ATTRIBS(), +"Compare for Equal", +{RdV=(RsV!=RtV); }) + + + +/*********************************************/ +/* Scalar compare instructions */ +/*********************************************/ + + +Q6INSN(C2_bitsset,"Pd4=bitsset(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Compare for selected bits set", +{PdV=f8BITSOF((RsV&RtV)==RtV);}) + +Q6INSN(C2_bitsclr,"Pd4=bitsclr(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Compare for selected bits clear", +{PdV=f8BITSOF((RsV&RtV)==0);}) + + +Q6INSN(C4_nbitsset,"Pd4=!bitsset(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Compare for selected bits set", +{PdV=f8BITSOF((RsV&RtV)!=RtV);}) + +Q6INSN(C4_nbitsclr,"Pd4=!bitsclr(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Compare for selected bits clear", +{PdV=f8BITSOF((RsV&RtV)!=0);}) + + + +/*********************************************/ +/* Scalar compare instructions W/ immediate */ +/*********************************************/ + +Q6INSN(C2_cmpeqi,"Pd4=cmp.eq(Rs32,#s10)",ATTRIBS(), +"Compare for Equal", +{fIMMEXT(siV); PdV=f8BITSOF(RsV==siV);}) + +Q6INSN(C2_cmpgti,"Pd4=cmp.gt(Rs32,#s10)",ATTRIBS(), +"Compare for signed Greater Than", +{fIMMEXT(siV); PdV=f8BITSOF(RsV>siV);}) + +Q6INSN(C2_cmpgtui,"Pd4=cmp.gtu(Rs32,#u9)",ATTRIBS(), +"Compare for Greater Than Unsigned", +{fIMMEXT(uiV); PdV=f8BITSOF(fCAST4u(RsV)>fCAST4u(uiV));}) + +Q6INSN(C2_bitsclri,"Pd4=bitsclr(Rs32,#u6)",ATTRIBS(A_ARCHV2), +"Compare for selected bits clear", +{PdV=f8BITSOF((RsV&uiV)==0);}) + +Q6INSN(C4_nbitsclri,"Pd4=!bitsclr(Rs32,#u6)",ATTRIBS(A_ARCHV2), +"Compare for selected bits clear", +{PdV=f8BITSOF((RsV&uiV)!=0);}) + + + + +Q6INSN(C4_cmpneqi,"Pd4=!cmp.eq(Rs32,#s10)",ATTRIBS(), "Compare for Not Equal", {fIMMEXT(siV); PdV=f8BITSOF(RsV!=siV);}) +Q6INSN(C4_cmpltei,"Pd4=!cmp.gt(Rs32,#s10)",ATTRIBS(), "Compare for Less Than or Equal", {fIMMEXT(siV); PdV=f8BITSOF(RsV<=siV);}) +Q6INSN(C4_cmplteui,"Pd4=!cmp.gtu(Rs32,#u9)",ATTRIBS(), "Compare for Less Than or Equal Unsigned", {fIMMEXT(uiV); PdV=f8BITSOF(fCAST4u(RsV)<=fCAST4u(uiV));}) + +Q6INSN(C4_cmpneq,"Pd4=!cmp.eq(Rs32,Rt32)",ATTRIBS(), "And-Compare for Equal", {PdV=f8BITSOF(RsV!=RtV);}) +Q6INSN(C4_cmplte,"Pd4=!cmp.gt(Rs32,Rt32)",ATTRIBS(), "And-Compare for signed Greater Than", {PdV=f8BITSOF(RsV<=RtV);}) +Q6INSN(C4_cmplteu,"Pd4=!cmp.gtu(Rs32,Rt32)",ATTRIBS(), "And-Compare for Greater Than Unsigned", {PdV=f8BITSOF(fCAST4u(RsV)<=fCAST4u(RtV));}) + + + + + +/* Predicate Logical Operations */ + +Q6INSN(C2_and,"Pd4=and(Pt4,Ps4)",ATTRIBS(A_CRSLOT23), +"Predicate AND", +{PdV=PsV & PtV;}) + +Q6INSN(C2_or,"Pd4=or(Pt4,Ps4)",ATTRIBS(A_CRSLOT23), +"Predicate OR", +{PdV=PsV | PtV;}) + +Q6INSN(C2_xor,"Pd4=xor(Ps4,Pt4)",ATTRIBS(A_CRSLOT23), +"Predicate XOR", +{PdV=PsV ^ PtV;}) + +Q6INSN(C2_andn,"Pd4=and(Pt4,!Ps4)",ATTRIBS(A_CRSLOT23), +"Predicate AND NOT", +{PdV=PtV & (~PsV);}) + +Q6INSN(C2_not,"Pd4=not(Ps4)",ATTRIBS(A_CRSLOT23), +"Logical NOT Predicate", +{PdV=~PsV;}) + +Q6INSN(C2_orn,"Pd4=or(Pt4,!Ps4)",ATTRIBS(A_ARCHV2,A_CRSLOT23), +"Predicate OR NOT", +{PdV=PtV | (~PsV);}) + + + + + +Q6INSN(C4_and_and,"Pd4=and(Ps4,and(Pt4,Pu4))",ATTRIBS(A_CRSLOT23), +"Compound And-And", { PdV = PsV & PtV & PuV; }) + +Q6INSN(C4_and_or,"Pd4=and(Ps4,or(Pt4,Pu4))",ATTRIBS(A_CRSLOT23), +"Compound And-Or", { PdV = PsV & (PtV | PuV); }) + +Q6INSN(C4_or_and,"Pd4=or(Ps4,and(Pt4,Pu4))",ATTRIBS(A_CRSLOT23), +"Compound Or-And", { PdV = PsV | (PtV & PuV); }) + +Q6INSN(C4_or_or,"Pd4=or(Ps4,or(Pt4,Pu4))",ATTRIBS(A_CRSLOT23), +"Compound Or-Or", { PdV = PsV | PtV | PuV; }) + + + +Q6INSN(C4_and_andn,"Pd4=and(Ps4,and(Pt4,!Pu4))",ATTRIBS(A_CRSLOT23), +"Compound And-And", { PdV = PsV & PtV & (~PuV); }) + +Q6INSN(C4_and_orn,"Pd4=and(Ps4,or(Pt4,!Pu4))",ATTRIBS(A_CRSLOT23), +"Compound And-Or", { PdV = PsV & (PtV | (~PuV)); }) + +Q6INSN(C4_or_andn,"Pd4=or(Ps4,and(Pt4,!Pu4))",ATTRIBS(A_CRSLOT23), +"Compound Or-And", { PdV = PsV | (PtV & (~PuV)); }) + +Q6INSN(C4_or_orn,"Pd4=or(Ps4,or(Pt4,!Pu4))",ATTRIBS(A_CRSLOT23), +"Compound Or-Or", { PdV = PsV | PtV | (~PuV); }) + + +Q6INSN(C2_any8,"Pd4=any8(Ps4)",ATTRIBS(A_CRSLOT23), +"Logical ANY of low 8 predicate bits", +{ PsV ? (PdV=0xff) : (PdV=0x00); }) + +Q6INSN(C2_all8,"Pd4=all8(Ps4)",ATTRIBS(A_CRSLOT23), +"Logical ALL of low 8 predicate bits", +{ (PsV==0xff) ? (PdV=0xff) : (PdV=0x00); }) + +Q6INSN(C2_vitpack,"Rd32=vitpack(Ps4,Pt4)",ATTRIBS(), +"Pack the odd and even bits of two predicate registers", +{ RdV = (PsV&0x55) | (PtV&0xAA); }) + +/* Mux instructions */ + +Q6INSN(C2_mux,"Rd32=mux(Pu4,Rs32,Rt32)",ATTRIBS(), +"Scalar MUX", +{ (fLSBOLD(PuV)) ? (RdV=RsV):(RdV=RtV); }) + + +Q6INSN(C2_cmovenewit,"if (Pu4.new) Rd32=#s12",ATTRIBS(A_ARCHV2), +"Scalar conditional move", +{ fIMMEXT(siV); if (fLSBNEW(PuN)) RdV=siV; else CANCEL;}) + +Q6INSN(C2_cmovenewif,"if (!Pu4.new) Rd32=#s12",ATTRIBS(A_ARCHV2), +"Scalar conditional move", +{ fIMMEXT(siV); if (fLSBNEWNOT(PuN)) RdV=siV; else CANCEL;}) + +Q6INSN(C2_cmoveit,"if (Pu4) Rd32=#s12",ATTRIBS(A_ARCHV2), +"Scalar conditional move", +{ fIMMEXT(siV); if (fLSBOLD(PuV)) RdV=siV; else CANCEL;}) + +Q6INSN(C2_cmoveif,"if (!Pu4) Rd32=#s12",ATTRIBS(A_ARCHV2), +"Scalar conditional move", +{ fIMMEXT(siV); if (fLSBOLDNOT(PuV)) RdV=siV; else CANCEL;}) + + + +Q6INSN(C2_ccombinewnewt,"if (Pu4.new) Rdd32=combine(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Conditionally combine two words into a register pair", +{ if (fLSBNEW(PuN)) { + fSETWORD(0,RddV,RtV); + fSETWORD(1,RddV,RsV); + } else {CANCEL;} +}) + +Q6INSN(C2_ccombinewnewf,"if (!Pu4.new) Rdd32=combine(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Conditionally combine two words into a register pair", +{ if (fLSBNEWNOT(PuN)) { + fSETWORD(0,RddV,RtV); + fSETWORD(1,RddV,RsV); + } else {CANCEL;} +}) + +Q6INSN(C2_ccombinewt,"if (Pu4) Rdd32=combine(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Conditionally combine two words into a register pair", +{ if (fLSBOLD(PuV)) { + fSETWORD(0,RddV,RtV); + fSETWORD(1,RddV,RsV); + } else {CANCEL;} +}) + +Q6INSN(C2_ccombinewf,"if (!Pu4) Rdd32=combine(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Conditionally combine two words into a register pair", +{ if (fLSBOLDNOT(PuV)) { + fSETWORD(0,RddV,RtV); + fSETWORD(1,RddV,RsV); + } else {CANCEL;} +}) + + + +Q6INSN(C2_muxii,"Rd32=mux(Pu4,#s8,#S8)",ATTRIBS(A_ARCHV2), +"Scalar MUX immediates", +{ fIMMEXT(siV); (fLSBOLD(PuV)) ? (RdV=siV):(RdV=SiV); }) + + + +Q6INSN(C2_muxir,"Rd32=mux(Pu4,Rs32,#s8)",ATTRIBS(A_ARCHV2), +"Scalar MUX register immediate", +{ fIMMEXT(siV); (fLSBOLD(PuV)) ? (RdV=RsV):(RdV=siV); }) + + +Q6INSN(C2_muxri,"Rd32=mux(Pu4,#s8,Rs32)",ATTRIBS(A_ARCHV2), +"Scalar MUX register immediate", +{ fIMMEXT(siV); (fLSBOLD(PuV)) ? (RdV=siV):(RdV=RsV); }) + + + +Q6INSN(C2_vmux,"Rdd32=vmux(Pu4,Rss32,Rtt32)",ATTRIBS(), +"Vector MUX", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBYTE(i,RddV,(fGETBIT(i,PuV)?(fGETBYTE(i,RssV)):(fGETBYTE(i,RttV)))); + } +}) + +Q6INSN(C2_mask,"Rdd32=mask(Pt4)",ATTRIBS(), +"Vector Mask Generation", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBYTE(i,RddV,(fGETBIT(i,PtV)?(0xff):(0x00))); + } +}) + +/* VCMP */ + +Q6INSN(A2_vcmpbeq,"Pd4=vcmpb.eq(Rss32,Rtt32)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBIT(i,PdV,(fGETBYTE(i,RssV) == fGETBYTE(i,RttV))); + } +}) + +Q6INSN(A4_vcmpbeqi,"Pd4=vcmpb.eq(Rss32,#u8)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBIT(i,PdV,(fGETUBYTE(i,RssV) == uiV)); + } +}) + +Q6INSN(A4_vcmpbeq_any,"Pd4=any8(vcmpb.eq(Rss32,Rtt32))",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + PdV = 0; + for (i = 0; i < 8; i++) { + if (fGETBYTE(i,RssV) == fGETBYTE(i,RttV)) PdV = 0xff; + } +}) + +Q6INSN(A6_vcmpbeq_notany,"Pd4=!any8(vcmpb.eq(Rss32,Rtt32))",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + PdV = 0; + for (i = 0; i < 8; i++) { + if (fGETBYTE(i,RssV) == fGETBYTE(i,RttV)) PdV = 0xff; + } + PdV = ~PdV; +}) + +Q6INSN(A2_vcmpbgtu,"Pd4=vcmpb.gtu(Rss32,Rtt32)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBIT(i,PdV,(fGETUBYTE(i,RssV) > fGETUBYTE(i,RttV))); + } +}) + +Q6INSN(A4_vcmpbgtui,"Pd4=vcmpb.gtu(Rss32,#u7)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBIT(i,PdV,(fGETUBYTE(i,RssV) > uiV)); + } +}) + +Q6INSN(A4_vcmpbgt,"Pd4=vcmpb.gt(Rss32,Rtt32)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBIT(i,PdV,(fGETBYTE(i,RssV) > fGETBYTE(i,RttV))); + } +}) + +Q6INSN(A4_vcmpbgti,"Pd4=vcmpb.gt(Rss32,#s8)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 8; i++) { + fSETBIT(i,PdV,(fGETBYTE(i,RssV) > siV)); + } +}) + + + +Q6INSN(A4_cmpbeq,"Pd4=cmpb.eq(Rs32,Rt32)",ATTRIBS(), +"Compare bytes ", +{ + PdV=f8BITSOF(fGETBYTE(0,RsV) == fGETBYTE(0,RtV)); +}) + +Q6INSN(A4_cmpbeqi,"Pd4=cmpb.eq(Rs32,#u8)",ATTRIBS(), +"Compare bytes ", +{ + PdV=f8BITSOF(fGETUBYTE(0,RsV) == uiV); +}) + +Q6INSN(A4_cmpbgtu,"Pd4=cmpb.gtu(Rs32,Rt32)",ATTRIBS(), +"Compare bytes ", +{ + PdV=f8BITSOF(fGETUBYTE(0,RsV) > fGETUBYTE(0,RtV)); +}) + +Q6INSN(A4_cmpbgtui,"Pd4=cmpb.gtu(Rs32,#u7)",ATTRIBS(), +"Compare bytes ", +{ + fIMMEXT(uiV); + PdV=f8BITSOF(fGETUBYTE(0,RsV) > fCAST4u(uiV)); +}) + +Q6INSN(A4_cmpbgt,"Pd4=cmpb.gt(Rs32,Rt32)",ATTRIBS(), +"Compare bytes ", +{ + PdV=f8BITSOF(fGETBYTE(0,RsV) > fGETBYTE(0,RtV)); +}) + +Q6INSN(A4_cmpbgti,"Pd4=cmpb.gt(Rs32,#s8)",ATTRIBS(), +"Compare bytes ", +{ + PdV=f8BITSOF(fGETBYTE(0,RsV) > siV); +}) + +Q6INSN(A2_vcmpheq,"Pd4=vcmph.eq(Rss32,Rtt32)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 4; i++) { + fSETBIT(i*2,PdV, (fGETHALF(i,RssV) == fGETHALF(i,RttV))); + fSETBIT(i*2+1,PdV,(fGETHALF(i,RssV) == fGETHALF(i,RttV))); + } +}) + +Q6INSN(A2_vcmphgt,"Pd4=vcmph.gt(Rss32,Rtt32)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 4; i++) { + fSETBIT(i*2, PdV, (fGETHALF(i,RssV) > fGETHALF(i,RttV))); + fSETBIT(i*2+1,PdV, (fGETHALF(i,RssV) > fGETHALF(i,RttV))); + } +}) + +Q6INSN(A2_vcmphgtu,"Pd4=vcmph.gtu(Rss32,Rtt32)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 4; i++) { + fSETBIT(i*2, PdV, (fGETUHALF(i,RssV) > fGETUHALF(i,RttV))); + fSETBIT(i*2+1,PdV, (fGETUHALF(i,RssV) > fGETUHALF(i,RttV))); + } +}) + +Q6INSN(A4_vcmpheqi,"Pd4=vcmph.eq(Rss32,#s8)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 4; i++) { + fSETBIT(i*2,PdV, (fGETHALF(i,RssV) == siV)); + fSETBIT(i*2+1,PdV,(fGETHALF(i,RssV) == siV)); + } +}) + +Q6INSN(A4_vcmphgti,"Pd4=vcmph.gt(Rss32,#s8)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 4; i++) { + fSETBIT(i*2, PdV, (fGETHALF(i,RssV) > siV)); + fSETBIT(i*2+1,PdV, (fGETHALF(i,RssV) > siV)); + } +}) + + +Q6INSN(A4_vcmphgtui,"Pd4=vcmph.gtu(Rss32,#u7)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fHIDE(int i;) + for (i = 0; i < 4; i++) { + fSETBIT(i*2, PdV, (fGETUHALF(i,RssV) > uiV)); + fSETBIT(i*2+1,PdV, (fGETUHALF(i,RssV) > uiV)); + } +}) + +Q6INSN(A4_cmpheq,"Pd4=cmph.eq(Rs32,Rt32)",ATTRIBS(), +"Compare halfwords ", +{ + PdV=f8BITSOF(fGETHALF(0,RsV) == fGETHALF(0,RtV)); +}) + +Q6INSN(A4_cmphgt,"Pd4=cmph.gt(Rs32,Rt32)",ATTRIBS(), +"Compare halfwords ", +{ + PdV=f8BITSOF(fGETHALF(0,RsV) > fGETHALF(0,RtV)); +}) + +Q6INSN(A4_cmphgtu,"Pd4=cmph.gtu(Rs32,Rt32)",ATTRIBS(), +"Compare halfwords ", +{ + PdV=f8BITSOF(fGETUHALF(0,RsV) > fGETUHALF(0,RtV)); +}) + +Q6INSN(A4_cmpheqi,"Pd4=cmph.eq(Rs32,#s8)",ATTRIBS(), +"Compare halfwords ", +{ + fIMMEXT(siV); + PdV=f8BITSOF(fGETHALF(0,RsV) == siV); +}) + +Q6INSN(A4_cmphgti,"Pd4=cmph.gt(Rs32,#s8)",ATTRIBS(), +"Compare halfwords ", +{ + fIMMEXT(siV); + PdV=f8BITSOF(fGETHALF(0,RsV) > siV); +}) + +Q6INSN(A4_cmphgtui,"Pd4=cmph.gtu(Rs32,#u7)",ATTRIBS(), +"Compare halfwords ", +{ + fIMMEXT(uiV); + PdV=f8BITSOF(fGETUHALF(0,RsV) > fCAST4u(uiV)); +}) + +Q6INSN(A2_vcmpweq,"Pd4=vcmpw.eq(Rss32,Rtt32)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fSETBITS(3,0,PdV,(fGETWORD(0,RssV)==fGETWORD(0,RttV))); + fSETBITS(7,4,PdV,(fGETWORD(1,RssV)==fGETWORD(1,RttV))); +}) + +Q6INSN(A2_vcmpwgt,"Pd4=vcmpw.gt(Rss32,Rtt32)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fSETBITS(3,0,PdV,(fGETWORD(0,RssV)>fGETWORD(0,RttV))); + fSETBITS(7,4,PdV,(fGETWORD(1,RssV)>fGETWORD(1,RttV))); +}) + +Q6INSN(A2_vcmpwgtu,"Pd4=vcmpw.gtu(Rss32,Rtt32)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fSETBITS(3,0,PdV,(fGETUWORD(0,RssV)>fGETUWORD(0,RttV))); + fSETBITS(7,4,PdV,(fGETUWORD(1,RssV)>fGETUWORD(1,RttV))); +}) + +Q6INSN(A4_vcmpweqi,"Pd4=vcmpw.eq(Rss32,#s8)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fSETBITS(3,0,PdV,(fGETWORD(0,RssV)==siV)); + fSETBITS(7,4,PdV,(fGETWORD(1,RssV)==siV)); +}) + +Q6INSN(A4_vcmpwgti,"Pd4=vcmpw.gt(Rss32,#s8)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fSETBITS(3,0,PdV,(fGETWORD(0,RssV)>siV)); + fSETBITS(7,4,PdV,(fGETWORD(1,RssV)>siV)); +}) + +Q6INSN(A4_vcmpwgtui,"Pd4=vcmpw.gtu(Rss32,#u7)",ATTRIBS(), +"Compare elements of two vectors ", +{ + fSETBITS(3,0,PdV,(fGETUWORD(0,RssV)>fCAST4u(uiV))); + fSETBITS(7,4,PdV,(fGETUWORD(1,RssV)>fCAST4u(uiV))); +}) + +Q6INSN(A4_boundscheck_hi,"Pd4=boundscheck(Rss32,Rtt32):raw:hi",ATTRIBS(), +"Detect if a register is within bounds", +{ + fHIDE(size4u_t src;) + src = fGETUWORD(1,RssV); + PdV = f8BITSOF((fCAST4u(src) >= fGETUWORD(0,RttV)) && (fCAST4u(src) < fGETUWORD(1,RttV))); +}) + +Q6INSN(A4_boundscheck_lo,"Pd4=boundscheck(Rss32,Rtt32):raw:lo",ATTRIBS(), +"Detect if a register is within bounds", +{ + fHIDE(size4u_t src;) + src = fGETUWORD(0,RssV); + PdV = f8BITSOF((fCAST4u(src) >= fGETUWORD(0,RttV)) && (fCAST4u(src) < fGETUWORD(1,RttV))); +}) + +Q6INSN(A4_tlbmatch,"Pd4=tlbmatch(Rss32,Rt32)",ATTRIBS(), +"Detect if a VA/ASID matches a TLB entry", +{ + fHIDE(size4u_t TLBHI; size4u_t TLBLO; size4u_t MASK; size4u_t SIZE;) + MASK = 0x07ffffff; + TLBLO = fGETUWORD(0,RssV); + TLBHI = fGETUWORD(1,RssV); + SIZE = fMIN(6,fCL1_4(~fBREV_4(TLBLO))); + MASK &= (0xffffffff << 2*SIZE); + PdV = f8BITSOF(fGETBIT(31,TLBHI) && ((TLBHI & MASK) == (RtV & MASK))); +}) + +Q6INSN(C2_tfrpr,"Rd32=Ps4",ATTRIBS(), +"Transfer predicate to general register", { RdV = fZXTN(8,32,PsV); }) + +Q6INSN(C2_tfrrp,"Pd4=Rs32",ATTRIBS(), +"Transfer general register to Predicate", { PdV = fGETUBYTE(0,RsV); }) + +Q6INSN(C4_fastcorner9,"Pd4=fastcorner9(Ps4,Pt4)",ATTRIBS(A_CRSLOT23), +"Determine whether the predicate sources define a corner", +{ + fHIDE(size4u_t tmp = 0; size4u_t i;) + fSETHALF(0,tmp,(PsV<<8)|PtV); + fSETHALF(1,tmp,(PsV<<8)|PtV); + for (i = 1; i < 9; i++) { + tmp &= tmp >> 1; + } + PdV = f8BITSOF(tmp != 0); +}) + +Q6INSN(C4_fastcorner9_not,"Pd4=!fastcorner9(Ps4,Pt4)",ATTRIBS(A_CRSLOT23), +"Determine whether the predicate sources define a corner", +{ + fHIDE(size4u_t tmp = 0; size4u_t i;) + fSETHALF(0,tmp,(PsV<<8)|PtV); + fSETHALF(1,tmp,(PsV<<8)|PtV); + for (i = 1; i < 9; i++) { + tmp &= tmp >> 1; + } + PdV = f8BITSOF(tmp == 0); +}) diff --git a/target/hexagon/imported/encode.def b/target/hexagon/imported/encode.def new file mode 100644 index 0000000000..b9368d1284 --- /dev/null +++ b/target/hexagon/imported/encode.def @@ -0,0 +1,124 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * This just includes all encoding files + */ + +#ifndef DEF_FIELD32 +#define __SELF_DEF_FIELD32 +#define DEF_FIELD32(...) /* nothing */ +#endif + +#ifndef DEF_CLASS32 +#define __SELF_DEF_CLASS32 +#define DEF_CLASS32(...) /* nothing */ +#endif + +#ifndef DEF_ANTICLASS32 +#define __SELF_DEF_ANTICLASS32 +#define DEF_ANTICLASS32(...) /* nothing */ +#endif + +#ifndef LEGACY_DEF_ENC32 +#define __SELF_DEF_LEGACY_DEF_ENC32 +#define LEGACY_DEF_ENC32(...) /* nothing */ +#endif + +#ifndef DEF_FIELDROW_DESC32 +#define __SELF_DEF_FIELDROW_DESC32 +#define DEF_FIELDROW_DESC32(...) /* nothing */ +#endif + +#ifndef DEF_ENC32 +#define __SELF_DEF_ENC32 +#define DEF_ENC32(...) /* nothing */ +#endif + +#ifndef DEF_PACKED32 +#define __SELF_DEF_PACKED32 +#define DEF_PACKED32(...) /* nothing */ +#endif + +#ifndef DEF_ENC_SUBINSN +#define __SELF_DEF_ENC_SUBINSN +#define DEF_ENC_SUBINSN(...) /* nothing */ +#endif + +#ifndef DEF_EXT_ENC +#define __SELF_DEF_EXT_ENC +#define DEF_EXT_ENC(...) /* nothing */ +#endif + +#ifndef DEF_EXT_SPACE +#define __SELF_DEF_EXT_SPACE +#define DEF_EXT_SPACE(...) /* nothing */ +#endif + +#include "encode_pp.def" +#include "encode_subinsn.def" + +#ifdef __SELF_DEF_FIELD32 +#undef __SELF_DEF_FIELD32 +#undef DEF_FIELD32 +#endif + +#ifdef __SELF_DEF_CLASS32 +#undef __SELF_DEF_CLASS32 +#undef DEF_CLASS32 +#endif + +#ifdef __SELF_DEF_ANTICLASS32 +#undef __SELF_DEF_ANTICLASS32 +#undef DEF_ANTICLASS32 +#endif + +#ifdef __SELF_DEF_LEGACY_DEF_ENC32 +#undef __SELF_DEF_LEGACY_DEF_ENC32 +#undef LEGACY_DEF_ENC32 +#endif + +#ifdef __SELF_DEF_FIELDROW_DESC32 +#undef __SELF_DEF_FIELDROW_DESC32 +#undef DEF_FIELDROW_DESC32 +#endif + +#ifdef __SELF_DEF_ENC32 +#undef __SELF_DEF_ENC32 +#undef DEF_ENC32 +#endif + +#ifdef __SELF_DEF_EXT_SPACE +#undef __SELF_DEF_EXT_SPACE +#undef DEF_EXT_SPACE +#endif + + +#ifdef __SELF_DEF_PACKED32 +#undef __SELF_DEF_PACKED32 +#undef DEF_PACKED32 +#endif + +#ifdef __SELF_DEF_ENC_SUBINSN +#undef __SELF_DEF_ENC_SUBINSN +#undef DEF_ENC_SUBINSN +#endif + +#ifdef __SELF_DEF_EXT_ENC +#undef __SELF_DEF_EXT_ENC +#undef DEF_EXT_ENC +#endif diff --git a/target/hexagon/imported/encode_pp.def b/target/hexagon/imported/encode_pp.def new file mode 100644 index 0000000000..c21cb730af --- /dev/null +++ b/target/hexagon/imported/encode_pp.def @@ -0,0 +1,2110 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Encodings for 32 bit instructions + * + */ + + + + +DEF_CLASS32("---- ---- -------- PP------ --------",ALL_PP) +DEF_FIELD32("---- ---- -------- !!------ --------",Parse,"Packet/Loop parse bits") +DEF_FIELD32("!!!! ---- -------- PP------ --------",ICLASS,"Instruction Class") + +#define ICLASS_EXTENDER "0000" +#define ICLASS_CJ "0001" +#define ICLASS_NCJ "0010" +#define ICLASS_V4LDST "0011" +#define ICLASS_V2LDST "0100" +#define ICLASS_J "0101" +#define ICLASS_CR "0110" +#define ICLASS_ALU2op "0111" +#define ICLASS_S2op "1000" +#define ICLASS_LD "1001" +#define ICLASS_ST "1010" +#define ICLASS_ADDI "1011" +#define ICLASS_S3op "1100" +#define ICLASS_ALU64 "1101" +#define ICLASS_M "1110" +#define ICLASS_ALU3op "1111" + + + +/*******************************/ +/* */ +/* */ +/* V4 Immediate Payload */ +/* */ +/* */ +/*******************************/ + +DEF_CLASS32(ICLASS_EXTENDER" ---- -------- PP------ --------",EXTENDER) +DEF_ENC32(A4_ext, ICLASS_EXTENDER "iiii iiiiiiii PPiiiiii iiiiiiii") + + + +/*******************************/ +/* */ +/* */ +/* V2 PREDICATED LD/ST */ +/* */ +/* */ +/*******************************/ + +DEF_CLASS32(ICLASS_V2LDST" ---- -------- PP------ --------",V2LDST) +DEF_CLASS32(ICLASS_V2LDST" ---1 -------- PP------ --------",V2LD) +DEF_CLASS32(ICLASS_V2LDST" ---0 -------- PP------ --------",V2ST) +DEF_CLASS32(ICLASS_V2LDST" 0--1 -------- PP------ --------",PLD) +DEF_CLASS32(ICLASS_V2LDST" 0--0 -------- PP------ --------",PST) +DEF_CLASS32(ICLASS_V2LDST" 1--1 -------- PP------ --------",GPLD) +DEF_CLASS32(ICLASS_V2LDST" 1--0 -------- PP------ --------",GPST) + +DEF_FIELD32(ICLASS_V2LDST" 0!-- -------- PP------ --------",PMEM_Sense,"Sense") +DEF_FIELD32(ICLASS_V2LDST" 0-!- -------- PP------ --------",PMEM_PredNew,"PredNew") +DEF_FIELD32(ICLASS_V2LDST" ---1 !!------ PP------ --------",PMEML_Type,"Type") +DEF_FIELD32(ICLASS_V2LDST" ---1 --!----- PP------ --------",PMEML_UN,"Unsigned") +DEF_FIELD32(ICLASS_V2LDST" ---0 !!!----- PP------ --------",PMEMS_Type,"Type") + +#define STD_PLD_IOENC(TAG,OPC) \ +DEF_ENC32(L2_pload##TAG##t_io, ICLASS_V2LDST" 0001 "OPC" sssss PP0ttiii iiiddddd")\ +DEF_ENC32(L2_pload##TAG##f_io, ICLASS_V2LDST" 0101 "OPC" sssss PP0ttiii iiiddddd")\ +DEF_ENC32(L2_pload##TAG##tnew_io,ICLASS_V2LDST" 0011 "OPC" sssss PP0ttiii iiiddddd")\ +DEF_ENC32(L2_pload##TAG##fnew_io,ICLASS_V2LDST" 0111 "OPC" sssss PP0ttiii iiiddddd") + +STD_PLD_IOENC(rb, "000") +STD_PLD_IOENC(rub, "001") +STD_PLD_IOENC(rh, "010") +STD_PLD_IOENC(ruh, "011") +STD_PLD_IOENC(ri, "100") +STD_PLD_IOENC(rd, "110") /* note dest reg field LSB=0, 1 is reserved */ + + + +#define STD_PST_IOENC(TAG,OPC,SRC) \ +DEF_ENC32(S2_pstore##TAG##t_io, ICLASS_V2LDST" 0000 "OPC" sssss PPi"SRC" iiiii0vv")\ +DEF_ENC32(S2_pstore##TAG##f_io, ICLASS_V2LDST" 0100 "OPC" sssss PPi"SRC" iiiii0vv")\ +DEF_ENC32(S4_pstore##TAG##tnew_io,ICLASS_V2LDST" 0010 "OPC" sssss PPi"SRC" iiiii0vv")\ +DEF_ENC32(S4_pstore##TAG##fnew_io,ICLASS_V2LDST" 0110 "OPC" sssss PPi"SRC" iiiii0vv") + +STD_PST_IOENC(rb, "000","ttttt") +STD_PST_IOENC(rh, "010","ttttt") +STD_PST_IOENC(rf, "011","ttttt") +STD_PST_IOENC(ri, "100","ttttt") +STD_PST_IOENC(rd, "110","ttttt") +STD_PST_IOENC(rbnew, "101","00ttt") +STD_PST_IOENC(rhnew, "101","01ttt") +STD_PST_IOENC(rinew, "101","10ttt") + + + + + +/*******************************/ +/* */ +/* */ +/* V2 GP-RELATIVE LD/ST */ +/* */ +/* */ +/*******************************/ +#define STD_LD_GP(TAG,OPC) \ +DEF_ENC32(L2_load##TAG##gp, ICLASS_V2LDST" 1ii1 "OPC" iiiii PPiiiiii iiiddddd") + +STD_LD_GP(rb, "000") +STD_LD_GP(rub, "001") +STD_LD_GP(rh, "010") +STD_LD_GP(ruh, "011") +STD_LD_GP(ri, "100") +STD_LD_GP(rd, "110") /* note dest reg field LSB=0, 1 is reserved */ + +#define STD_ST_GP(TAG,OPC,SRC) \ +DEF_ENC32(S2_store##TAG##gp, ICLASS_V2LDST" 1ii0 "OPC" iiiii PPi"SRC" iiiiiiii") + +STD_ST_GP(rb, "000","ttttt") +STD_ST_GP(rh, "010","ttttt") +STD_ST_GP(rf, "011","ttttt") +STD_ST_GP(ri, "100","ttttt") +STD_ST_GP(rd, "110","ttttt") +STD_ST_GP(rbnew,"101","00ttt") +STD_ST_GP(rhnew,"101","01ttt") +STD_ST_GP(rinew,"101","10ttt") + + + + + +/*******************************/ +/* */ +/* */ +/* V4LDST */ +/* */ +/* */ +/*******************************/ + + +DEF_CLASS32(ICLASS_V4LDST" ---- -------- PP------ --------",V4LDST) +DEF_CLASS32(ICLASS_V4LDST" 0--- -------- PP------ --------",Pred_RplusR) +DEF_CLASS32(ICLASS_V4LDST" 100- -------- PP------ --------",Pred_StoreImmed) +DEF_CLASS32(ICLASS_V4LDST" 101- -------- PP------ --------",RplusR) +DEF_CLASS32(ICLASS_V4LDST" 110- -------- PP------ --------",StoreImmed) +DEF_CLASS32(ICLASS_V4LDST" 111- -------- PP------ --------",MemOp) + + + + +/*******************************/ +/* Pred (R+R) */ +/*******************************/ + +#define STD_PLD_RRENC(TAG,OPC) \ +DEF_ENC32(L4_pload##TAG##t_rr, ICLASS_V4LDST" 00 00 "OPC" sssss PPittttt ivvddddd")\ +DEF_ENC32(L4_pload##TAG##f_rr, ICLASS_V4LDST" 00 01 "OPC" sssss PPittttt ivvddddd")\ +DEF_ENC32(L4_pload##TAG##tnew_rr,ICLASS_V4LDST" 00 10 "OPC" sssss PPittttt ivvddddd")\ +DEF_ENC32(L4_pload##TAG##fnew_rr,ICLASS_V4LDST" 00 11 "OPC" sssss PPittttt ivvddddd") + +STD_PLD_RRENC(rb, "000") +STD_PLD_RRENC(rub, "001") +STD_PLD_RRENC(rh, "010") +STD_PLD_RRENC(ruh, "011") +STD_PLD_RRENC(ri, "100") +STD_PLD_RRENC(rd, "110") + +#define STD_PST_RRENC(TAG,OPC,SRC) \ +DEF_ENC32(S4_pstore##TAG##t_rr, ICLASS_V4LDST" 01 00 "OPC" sssss PPiuuuuu ivv"SRC)\ +DEF_ENC32(S4_pstore##TAG##f_rr, ICLASS_V4LDST" 01 01 "OPC" sssss PPiuuuuu ivv"SRC)\ +DEF_ENC32(S4_pstore##TAG##tnew_rr,ICLASS_V4LDST" 01 10 "OPC" sssss PPiuuuuu ivv"SRC)\ +DEF_ENC32(S4_pstore##TAG##fnew_rr,ICLASS_V4LDST" 01 11 "OPC" sssss PPiuuuuu ivv"SRC) + +STD_PST_RRENC(rb, "000","ttttt") +STD_PST_RRENC(rh, "010","ttttt") +STD_PST_RRENC(rf, "011","ttttt") +STD_PST_RRENC(ri, "100","ttttt") +STD_PST_RRENC(rd, "110","ttttt") +STD_PST_RRENC(rbnew, "101","00ttt") +STD_PST_RRENC(rhnew, "101","01ttt") +STD_PST_RRENC(rinew, "101","10ttt") + + + +/*******************************/ +/* Pred Store immediates */ +/*******************************/ + +#define V4_PSTI(TAG,OPC) \ +DEF_ENC32(S4_storei##TAG##t_io, ICLASS_V4LDST" 100 00 "OPC" sssss PPIiiiii ivvIIIII")\ +DEF_ENC32(S4_storei##TAG##f_io, ICLASS_V4LDST" 100 01 "OPC" sssss PPIiiiii ivvIIIII")\ +DEF_ENC32(S4_storei##TAG##tnew_io, ICLASS_V4LDST" 100 10 "OPC" sssss PPIiiiii ivvIIIII")\ +DEF_ENC32(S4_storei##TAG##fnew_io, ICLASS_V4LDST" 100 11 "OPC" sssss PPIiiiii ivvIIIII") + +V4_PSTI(rb, "00") +V4_PSTI(rh, "01") +V4_PSTI(ri, "10") + + + +/*******************************/ +/* (R+R) */ +/*******************************/ + +#define STD_LD_RRENC(TAG,OPC) \ +DEF_ENC32(L4_load##TAG##_rr, ICLASS_V4LDST" 1010 "OPC" sssss PPittttt i--ddddd") + +STD_LD_RRENC(rb, "000") +STD_LD_RRENC(rub, "001") +STD_LD_RRENC(rh, "010") +STD_LD_RRENC(ruh, "011") +STD_LD_RRENC(ri, "100") +STD_LD_RRENC(rd, "110") + +#define STD_ST_RRENC(TAG,OPC,SRC) \ +DEF_ENC32(S4_store##TAG##_rr, ICLASS_V4LDST" 1011 "OPC" sssss PPiuuuuu i--"SRC) + +STD_ST_RRENC(rb, "000","ttttt") +STD_ST_RRENC(rh, "010","ttttt") +STD_ST_RRENC(rf, "011","ttttt") +STD_ST_RRENC(ri, "100","ttttt") +STD_ST_RRENC(rd, "110","ttttt") +STD_ST_RRENC(rbnew, "101","00ttt") +STD_ST_RRENC(rhnew, "101","01ttt") +STD_ST_RRENC(rinew, "101","10ttt") + + + + +/*******************************/ +/* Store immediates */ +/*******************************/ + +#define V4_STI(TAG,OPC) \ +DEF_ENC32(S4_storei##TAG##_io, ICLASS_V4LDST" 110 -- "OPC" sssss PPIiiiii iIIIIIII") + + +V4_STI(rb, "00") +V4_STI(rh, "01") +V4_STI(ri, "10") + + +/*******************************/ +/* Memops */ +/*******************************/ + +#define MEMOPENC(TAG,OPC) \ +DEF_ENC32(L4_add_##TAG##_io, ICLASS_V4LDST" 111 0- " OPC "sssss PP0iiiii i00ttttt")\ +DEF_ENC32(L4_sub_##TAG##_io, ICLASS_V4LDST" 111 0- " OPC "sssss PP0iiiii i01ttttt")\ +DEF_ENC32(L4_and_##TAG##_io, ICLASS_V4LDST" 111 0- " OPC "sssss PP0iiiii i10ttttt")\ +DEF_ENC32(L4_or_##TAG##_io, ICLASS_V4LDST" 111 0- " OPC "sssss PP0iiiii i11ttttt")\ +\ +DEF_ENC32(L4_iadd_##TAG##_io, ICLASS_V4LDST" 111 1- " OPC "sssss PP0iiiii i00IIIII")\ +DEF_ENC32(L4_isub_##TAG##_io, ICLASS_V4LDST" 111 1- " OPC "sssss PP0iiiii i01IIIII")\ +DEF_ENC32(L4_iand_##TAG##_io, ICLASS_V4LDST" 111 1- " OPC "sssss PP0iiiii i10IIIII")\ +DEF_ENC32(L4_ior_##TAG##_io, ICLASS_V4LDST" 111 1- " OPC "sssss PP0iiiii i11IIIII") + + + +MEMOPENC(memopw,"10") +MEMOPENC(memoph,"01") +MEMOPENC(memopb,"00") + + + + +/*******************************/ +/* */ +/* */ +/* LOAD */ +/* */ +/* */ +/*******************************/ +DEF_CLASS32(ICLASS_LD" ---- -------- PP------ --------",LD) + + +DEF_CLASS32(ICLASS_LD" 0--- -------- PP------ --------",LD_ADDR_ROFFSET) +DEF_CLASS32(ICLASS_LD" 101- -------- PP00---- --------",LD_ADDR_POST_IMMED) +DEF_CLASS32(ICLASS_LD" 101- -------- PP01---- --------",LD_ADDR_ABS_UPDATE_V4) +DEF_CLASS32(ICLASS_LD" 101- -------- PP1----- --------",LD_ADDR_POST_IMMED_PRED_V2) +DEF_CLASS32(ICLASS_LD" 110- -------- PP-0---- 0-------",LD_ADDR_POST_REG) +DEF_CLASS32(ICLASS_LD" 110- -------- PP-1---- --------",LD_ADDR_ABS_PLUS_REG_V4) +DEF_CLASS32(ICLASS_LD" 100- -------- PP----1- --------",LD_ADDR_POST_CREG_V2) +DEF_CLASS32(ICLASS_LD" 111- -------- PP------ 1-------",LD_ADDR_PRED_ABS_V4) + +DEF_FIELD32(ICLASS_LD" !!!- -------- PP------ --------",LD_Amode,"Amode") +DEF_FIELD32(ICLASS_LD" ---! !!------ PP------ --------",LD_Type,"Type") +DEF_FIELD32(ICLASS_LD" ---- --!----- PP------ --------",LD_UN,"Unsigned") + +#define STD_LD_ENC(TAG,OPC) \ +DEF_ENC32(L2_load##TAG##_io, ICLASS_LD" 0 ii "OPC" sssss PPiiiiii iiiddddd")\ +DEF_ENC32(L2_load##TAG##_pi, ICLASS_LD" 1 01 "OPC" xxxxx PP00---i iiiddddd")\ +DEF_ENC32(L4_load##TAG##_ap, ICLASS_LD" 1 01 "OPC" eeeee PP01IIII -IIddddd")\ +DEF_ENC32(L2_load##TAG##_pr, ICLASS_LD" 1 10 "OPC" xxxxx PPu0---- 0--ddddd")\ +DEF_ENC32(L4_load##TAG##_ur, ICLASS_LD" 1 10 "OPC" ttttt PPi1IIII iIIddddd")\ + + +#define STD_LDX_ENC(TAG,OPC) \ +DEF_ENC32(L2_load##TAG##_io, ICLASS_LD" 0 ii "OPC" sssss PPiiiiii iiiyyyyy")\ +DEF_ENC32(L2_load##TAG##_pi, ICLASS_LD" 1 01 "OPC" xxxxx PP00---i iiiyyyyy")\ +DEF_ENC32(L4_load##TAG##_ap, ICLASS_LD" 1 01 "OPC" eeeee PP01IIII -IIyyyyy")\ +DEF_ENC32(L2_load##TAG##_pr, ICLASS_LD" 1 10 "OPC" xxxxx PPu0---- 0--yyyyy")\ +DEF_ENC32(L4_load##TAG##_ur, ICLASS_LD" 1 10 "OPC" ttttt PPi1IIII iIIyyyyy")\ + + +#define STD_PLD_ENC(TAG,OPC) \ +DEF_ENC32(L2_pload##TAG##t_pi, ICLASS_LD" 1 01 "OPC" xxxxx PP100tti iiiddddd")\ +DEF_ENC32(L2_pload##TAG##f_pi, ICLASS_LD" 1 01 "OPC" xxxxx PP101tti iiiddddd")\ +DEF_ENC32(L2_pload##TAG##tnew_pi, ICLASS_LD" 1 01 "OPC" xxxxx PP110tti iiiddddd")\ +DEF_ENC32(L2_pload##TAG##fnew_pi, ICLASS_LD" 1 01 "OPC" xxxxx PP111tti iiiddddd")\ +DEF_ENC32(L4_pload##TAG##t_abs, ICLASS_LD" 1 11 "OPC" iiiii PP100tti 1--ddddd")\ +DEF_ENC32(L4_pload##TAG##f_abs, ICLASS_LD" 1 11 "OPC" iiiii PP101tti 1--ddddd")\ +DEF_ENC32(L4_pload##TAG##tnew_abs,ICLASS_LD" 1 11 "OPC" iiiii PP110tti 1--ddddd")\ +DEF_ENC32(L4_pload##TAG##fnew_abs,ICLASS_LD" 1 11 "OPC" iiiii PP111tti 1--ddddd") + + +/* 0 000 misc: dealloc,loadw_locked,dcfetch */ +STD_LD_ENC(rb, "1 000") +STD_LD_ENC(rub, "1 001") +STD_LD_ENC(rh, "1 010") +STD_LD_ENC(ruh, "1 011") +STD_LD_ENC(ri, "1 100") +STD_LD_ENC(rd, "1 110") /* note dest reg field LSB=0, 1 is reserved */ + +STD_PLD_ENC(rb, "1 000") +STD_PLD_ENC(rub, "1 001") +STD_PLD_ENC(rh, "1 010") +STD_PLD_ENC(ruh, "1 011") +STD_PLD_ENC(ri, "1 100") +STD_PLD_ENC(rd, "1 110") /* note dest reg field LSB=0, 1 is reserved */ + + +DEF_CLASS32( ICLASS_LD" 0--0 000----- PP------ --------",LD_MISC) +DEF_ANTICLASS32(ICLASS_LD" 0--0 000----- PP------ --------",LD_ADDR_ROFFSET) +DEF_ANTICLASS32(ICLASS_LD" 1010 000----- PP------ --------",LD_ADDR_POST_IMMED) +DEF_ANTICLASS32(ICLASS_LD" 1100 000----- PP------ --------",LD_ADDR_POST_REG) +DEF_ANTICLASS32(ICLASS_LD" 1110 000----- PP------ --------",LD_ADDR_POST_REG) + +DEF_ENC32(L2_deallocframe, ICLASS_LD" 000 0 000 sssss PP0----- ---ddddd") +DEF_ENC32(L4_return, ICLASS_LD" 011 0 000 sssss PP0000-- ---ddddd") +DEF_ENC32(L4_return_t, ICLASS_LD" 011 0 000 sssss PP0100vv ---ddddd") +DEF_ENC32(L4_return_f, ICLASS_LD" 011 0 000 sssss PP1100vv ---ddddd") +DEF_ENC32(L4_return_tnew_pt, ICLASS_LD" 011 0 000 sssss PP0110vv ---ddddd") +DEF_ENC32(L4_return_fnew_pt, ICLASS_LD" 011 0 000 sssss PP1110vv ---ddddd") +DEF_ENC32(L4_return_tnew_pnt, ICLASS_LD" 011 0 000 sssss PP0010vv ---ddddd") +DEF_ENC32(L4_return_fnew_pnt, ICLASS_LD" 011 0 000 sssss PP1010vv ---ddddd") + +DEF_ENC32(L2_loadw_locked,ICLASS_LD" 001 0 000 sssss PP00---- -00ddddd") + + + + + + +DEF_ENC32(L4_loadd_locked,ICLASS_LD" 001 0 000 sssss PP01---- -00ddddd") +DEF_EXT_SPACE(EXTRACTW, ICLASS_LD" 001 0 000 iiiii PP0iiiii -01iiiii") +DEF_ENC32(Y2_dcfetchbo, ICLASS_LD" 010 0 000 sssss PP0--iii iiiiiiii") + + + + + + + + +/*******************************/ +/* */ +/* */ +/* STORE */ +/* */ +/* */ +/*******************************/ + +DEF_CLASS32(ICLASS_ST" ---- -------- PP------ --------",ST) + +DEF_FIELD32(ICLASS_ST" !!!- -------- PP------ --------",ST_Amode,"Amode") +DEF_FIELD32(ICLASS_ST" ---! !!------ PP------ --------",ST_Type,"Type") +DEF_FIELD32(ICLASS_ST" ---- --!----- PP------ --------",ST_UN,"Unsigned") + +DEF_CLASS32(ICLASS_ST" 0--1 -------- PP------ --------",ST_ADDR_ROFFSET) +DEF_CLASS32(ICLASS_ST" 1011 -------- PP0----- 0-----0-",ST_ADDR_POST_IMMED) +DEF_CLASS32(ICLASS_ST" 1011 -------- PP0----- 1-------",ST_ADDR_ABS_UPDATE_V4) +DEF_CLASS32(ICLASS_ST" 1011 -------- PP1----- --------",ST_ADDR_POST_IMMED_PRED_V2) +DEF_CLASS32(ICLASS_ST" 1111 -------- PP------ 1-------",ST_ADDR_PRED_ABS_V4) +DEF_CLASS32(ICLASS_ST" 1101 -------- PP------ 0-------",ST_ADDR_POST_REG) +DEF_CLASS32(ICLASS_ST" 1101 -------- PP------ 1-------",ST_ADDR_ABS_PLUS_REG_V4) +DEF_CLASS32(ICLASS_ST" 1001 -------- PP------ ------1-",ST_ADDR_POST_CREG_V2) +DEF_CLASS32(ICLASS_ST" 0--0 1------- PP------ --------",ST_MISC_STORELIKE) +DEF_CLASS32(ICLASS_ST" 1--0 0------- PP------ --------",ST_MISC_BUSOP) +DEF_CLASS32(ICLASS_ST" 0--0 0------- PP------ --------",ST_MISC_CACHEOP) + + +#define STD_ST_ENC(TAG,OPC,SRC) \ +DEF_ENC32(S2_store##TAG##_io, ICLASS_ST" 0 ii "OPC" sssss PPi"SRC" iiiiiiii")\ +DEF_ENC32(S2_store##TAG##_pi, ICLASS_ST" 1 01 "OPC" xxxxx PP0"SRC" 0iiii-0-")\ +DEF_ENC32(S4_store##TAG##_ap, ICLASS_ST" 1 01 "OPC" eeeee PP0"SRC" 1-IIIIII")\ +DEF_ENC32(S2_store##TAG##_pr, ICLASS_ST" 1 10 "OPC" xxxxx PPu"SRC" 0-------")\ +DEF_ENC32(S4_store##TAG##_ur, ICLASS_ST" 1 10 "OPC" uuuuu PPi"SRC" 1iIIIIII")\ + + +#define STD_PST_ENC(TAG,OPC,SRC) \ +DEF_ENC32(S2_pstore##TAG##t_pi, ICLASS_ST" 1 01 "OPC" xxxxx PP1"SRC" 0iiii0vv")\ +DEF_ENC32(S2_pstore##TAG##f_pi, ICLASS_ST" 1 01 "OPC" xxxxx PP1"SRC" 0iiii1vv")\ +DEF_ENC32(S2_pstore##TAG##tnew_pi, ICLASS_ST" 1 01 "OPC" xxxxx PP1"SRC" 1iiii0vv")\ +DEF_ENC32(S2_pstore##TAG##fnew_pi, ICLASS_ST" 1 01 "OPC" xxxxx PP1"SRC" 1iiii1vv")\ +DEF_ENC32(S4_pstore##TAG##t_abs, ICLASS_ST" 1 11 "OPC" ---ii PP0"SRC" 1iiii0vv")\ +DEF_ENC32(S4_pstore##TAG##f_abs, ICLASS_ST" 1 11 "OPC" ---ii PP0"SRC" 1iiii1vv")\ +DEF_ENC32(S4_pstore##TAG##tnew_abs,ICLASS_ST" 1 11 "OPC" ---ii PP1"SRC" 1iiii0vv")\ +DEF_ENC32(S4_pstore##TAG##fnew_abs,ICLASS_ST" 1 11 "OPC" ---ii PP1"SRC" 1iiii1vv") + + +/* 0 0-- Store Misc */ +/* 0 1xx Available */ +STD_ST_ENC(rb, "1 000","ttttt") +STD_ST_ENC(rh, "1 010","ttttt") +STD_ST_ENC(rf, "1 011","ttttt") +STD_ST_ENC(ri, "1 100","ttttt") +STD_ST_ENC(rd, "1 110","ttttt") +STD_ST_ENC(rbnew, "1 101","00ttt") +STD_ST_ENC(rhnew, "1 101","01ttt") +STD_ST_ENC(rinew, "1 101","10ttt") + +STD_PST_ENC(rb, "1 000","ttttt") +STD_PST_ENC(rh, "1 010","ttttt") +STD_PST_ENC(rf, "1 011","ttttt") +STD_PST_ENC(ri, "1 100","ttttt") +STD_PST_ENC(rd, "1 110","ttttt") +STD_PST_ENC(rbnew, "1 101","00ttt") +STD_PST_ENC(rhnew, "1 101","01ttt") +STD_PST_ENC(rinew, "1 101","10ttt") + + + +/* User */ +/* xx - st_misc */ +/* */ +/* x bus/cache */ +/* x store/cache */ +DEF_ENC32(S2_allocframe, ICLASS_ST" 000 01 00xxxxx PP000iii iiiiiiii") +DEF_ENC32(S2_storew_locked,ICLASS_ST" 000 01 01sssss PP-ttttt ------dd") +DEF_ENC32(S4_stored_locked,ICLASS_ST" 000 01 11sssss PP0ttttt ------dd") +DEF_ENC32(Y2_dczeroa, ICLASS_ST" 000 01 10sssss PP0----- --------") + + +DEF_ENC32(Y2_barrier, ICLASS_ST" 100 00 00----- PP------ 000-----") +DEF_ENC32(Y2_syncht, ICLASS_ST" 100 00 10----- PP------ --------") + + + +DEF_ENC32(Y2_dccleana, ICLASS_ST" 000 00 00sssss PP------ --------") +DEF_ENC32(Y2_dcinva, ICLASS_ST" 000 00 01sssss PP------ --------") +DEF_ENC32(Y2_dccleaninva, ICLASS_ST" 000 00 10sssss PP------ --------") + +/*******************************/ +/* */ +/* */ +/* JUMP */ +/* */ +/* */ +/*******************************/ + +DEF_CLASS32(ICLASS_J" ---- -------- PP------ --------",J) +DEF_CLASS32(ICLASS_J" 0--- -------- PP------ --------",JUMPR_MISC) +DEF_CLASS32(ICLASS_J" 10-- -------- PP------ --------",UCJUMP) +DEF_CLASS32(ICLASS_J" 110- -------- PP------ --------",CJUMP) +DEF_FIELD32(ICLASS_J" 110- -------- PP--!--- --------",J_DN,"Dot-new") +DEF_FIELD32(ICLASS_J" 110- -------- PP-!---- --------",J_PT,"Predict-taken") + + + +DEF_FIELDROW_DESC32(ICLASS_J" 0000 -------- PP------ --------","[#0] PC=(Rs), R31=return") +DEF_ENC32(J2_callr, ICLASS_J" 0000 101sssss PP------ --------") + +DEF_FIELDROW_DESC32(ICLASS_J" 0001 -------- PP------ --------","[#1] if (Pu) PC=(Rs), R31=return") +DEF_ENC32(J2_callrt, ICLASS_J" 0001 000sssss PP----uu --------") +DEF_ENC32(J2_callrf, ICLASS_J" 0001 001sssss PP----uu --------") + +DEF_FIELDROW_DESC32(ICLASS_J" 0010 -------- PP------ --------","[#2] PC=(Rs); ") +DEF_ENC32(J2_jumpr, ICLASS_J" 0010 100sssss PP------ --------") +DEF_ENC32(J4_hintjumpr, ICLASS_J" 0010 101sssss PP------ --------") + +DEF_FIELDROW_DESC32(ICLASS_J" 0011 -------- PP------ --------","[#3] if (Pu) PC=(Rs) ") +DEF_ENC32(J2_jumprt, ICLASS_J" 0011 010sssss PP-00-uu --------") +DEF_ENC32(J2_jumprf, ICLASS_J" 0011 011sssss PP-00-uu --------") +DEF_ENC32(J2_jumprtpt, ICLASS_J" 0011 010sssss PP-10-uu --------") +DEF_ENC32(J2_jumprfpt, ICLASS_J" 0011 011sssss PP-10-uu --------") +DEF_ENC32(J2_jumprtnew, ICLASS_J" 0011 010sssss PP-01-uu --------") +DEF_ENC32(J2_jumprfnew, ICLASS_J" 0011 011sssss PP-01-uu --------") +DEF_ENC32(J2_jumprtnewpt, ICLASS_J" 0011 010sssss PP-11-uu --------") +DEF_ENC32(J2_jumprfnewpt, ICLASS_J" 0011 011sssss PP-11-uu --------") + +DEF_FIELDROW_DESC32(ICLASS_J" 0100 -------- PP------ --------","[#4] (#u8) ") +DEF_ENC32(J2_trap0, ICLASS_J" 0100 00------ PP-iiiii ---iii--") +DEF_ENC32(J2_pause, ICLASS_J" 0100 01------ PP-iiiii ---iii--") + +DEF_FIELDROW_DESC32(ICLASS_J" 0110 -------- PP------ --------","[#6] icop(Rs) ") +DEF_ENC32(Y2_icinva, ICLASS_J" 0110 110sssss PP000--- --------") + +DEF_FIELDROW_DESC32(ICLASS_J" 0111 -------- PP------ --------","[#7] () ") +DEF_ENC32(Y2_isync, ICLASS_J" 0111 11000000 PP0---00 00000010") + +/* JUMP */ +DEF_FIELDROW_DESC32(ICLASS_J" 100- -------- PP------ --------","[#8,9] PC=(#r22)") +DEF_ENC32(J2_jump, ICLASS_J" 100i iiiiiiii PPiiiiii iiiiiii-") + +DEF_FIELDROW_DESC32(ICLASS_J" 101- -------- PP------ --------","[#10,11] PC=(#r22), R31=return") +DEF_ENC32(J2_call, ICLASS_J" 101i iiiiiiii PPiiiiii iiiiiii0") + +DEF_FIELDROW_DESC32(ICLASS_J" 1100 -------- PP------ --------","[#12] if (Pu) PC=(#r15)") +DEF_ENC32(J2_jumpt, ICLASS_J" 1100 ii0iiiii PPi00-uu iiiiiii-") +DEF_ENC32(J2_jumpf, ICLASS_J" 1100 ii1iiiii PPi00-uu iiiiiii-") +DEF_ENC32(J2_jumptpt, ICLASS_J" 1100 ii0iiiii PPi10-uu iiiiiii-") +DEF_ENC32(J2_jumpfpt, ICLASS_J" 1100 ii1iiiii PPi10-uu iiiiiii-") +DEF_ENC32(J2_jumptnew, ICLASS_J" 1100 ii0iiiii PPi01-uu iiiiiii-") +DEF_ENC32(J2_jumpfnew, ICLASS_J" 1100 ii1iiiii PPi01-uu iiiiiii-") +DEF_ENC32(J2_jumptnewpt,ICLASS_J" 1100 ii0iiiii PPi11-uu iiiiiii-") +DEF_ENC32(J2_jumpfnewpt,ICLASS_J" 1100 ii1iiiii PPi11-uu iiiiiii-") + +DEF_FIELDROW_DESC32(ICLASS_J" 1101 -------- PP------ --------","[#13] if (Pu) PC=(#r15), R31=return") +DEF_ENC32(J2_callt, ICLASS_J" 1101 ii0iiiii PPi-0-uu iiiiiii-") +DEF_ENC32(J2_callf, ICLASS_J" 1101 ii1iiiii PPi-0-uu iiiiiii-") + + + + + + + +/*******************************/ +/* */ +/* V4 */ +/* COMPOUND COMPARE-JUMPS */ +/* */ +/* */ +/*******************************/ + + +/* EJP: this has to match what we have in htmldocs.py... so I will call it CJ, we can change it */ +DEF_CLASS32(ICLASS_CJ" 0--- -------- PP------ --------",CJ) + +DEF_FIELDROW_DESC32(ICLASS_CJ" 00-- -------- -------- --------","[#0-3] pd=cmp.xx(R,#u5) ; if ([!]p0.new) jump:[h] #s9:2 ") +DEF_FIELDROW_DESC32(ICLASS_CJ" 010- -------- -------- --------","[#4,5] pd=cmp.eq(R,R) ; if ([!]p0.new) jump:[h] #s9:2 ") +DEF_FIELDROW_DESC32(ICLASS_CJ" 0110 -------- -------- --------","[#6] Rd=#u6 ; jump #s9:2 ") +DEF_FIELDROW_DESC32(ICLASS_CJ" 0111 -------- -------- --------","[#7] Rd=Rs ; jump #s9:2 ") + + +#define CMPJMPI_ENC(TAG,OPC) \ +DEF_ENC32(TAG##i_tp0_jump_t, ICLASS_CJ" 00 0 "OPC" 0iissss PP1IIIII iiiiiii-") \ +DEF_ENC32(TAG##i_fp0_jump_t, ICLASS_CJ" 00 0 "OPC" 1iissss PP1IIIII iiiiiii-") \ +DEF_ENC32(TAG##i_tp0_jump_nt, ICLASS_CJ" 00 0 "OPC" 0iissss PP0IIIII iiiiiii-") \ +DEF_ENC32(TAG##i_fp0_jump_nt, ICLASS_CJ" 00 0 "OPC" 1iissss PP0IIIII iiiiiii-") \ +\ +DEF_ENC32(TAG##i_tp1_jump_t, ICLASS_CJ" 00 1 "OPC" 0iissss PP1IIIII iiiiiii-") \ +DEF_ENC32(TAG##i_fp1_jump_t, ICLASS_CJ" 00 1 "OPC" 1iissss PP1IIIII iiiiiii-") \ +DEF_ENC32(TAG##i_tp1_jump_nt, ICLASS_CJ" 00 1 "OPC" 0iissss PP0IIIII iiiiiii-") \ +DEF_ENC32(TAG##i_fp1_jump_nt, ICLASS_CJ" 00 1 "OPC" 1iissss PP0IIIII iiiiiii-") + +CMPJMPI_ENC(J4_cmpeq,"00") +CMPJMPI_ENC(J4_cmpgt,"01") +CMPJMPI_ENC(J4_cmpgtu,"10") + + +#define CMPJMP1I_ENC(TAG,OPC) \ +DEF_ENC32(TAG##_tp0_jump_t, ICLASS_CJ" 00 0 11 0iissss PP1---"OPC" iiiiiii-") \ +DEF_ENC32(TAG##_fp0_jump_t, ICLASS_CJ" 00 0 11 1iissss PP1---"OPC" iiiiiii-") \ +DEF_ENC32(TAG##_tp0_jump_nt, ICLASS_CJ" 00 0 11 0iissss PP0---"OPC" iiiiiii-") \ +DEF_ENC32(TAG##_fp0_jump_nt, ICLASS_CJ" 00 0 11 1iissss PP0---"OPC" iiiiiii-") \ +\ +DEF_ENC32(TAG##_tp1_jump_t, ICLASS_CJ" 00 1 11 0iissss PP1---"OPC" iiiiiii-") \ +DEF_ENC32(TAG##_fp1_jump_t, ICLASS_CJ" 00 1 11 1iissss PP1---"OPC" iiiiiii-") \ +DEF_ENC32(TAG##_tp1_jump_nt, ICLASS_CJ" 00 1 11 0iissss PP0---"OPC" iiiiiii-") \ +DEF_ENC32(TAG##_fp1_jump_nt, ICLASS_CJ" 00 1 11 1iissss PP0---"OPC" iiiiiii-") + +CMPJMP1I_ENC(J4_cmpeqn1,"00") +CMPJMP1I_ENC(J4_cmpgtn1,"01") +CMPJMP1I_ENC(J4_tstbit0,"11") + + + +#define CMPJMPR_ENC(TAG,OPC) \ +DEF_ENC32(TAG##_tp0_jump_t, ICLASS_CJ" 01 0 "OPC" 0iissss PP10tttt iiiiiii-") \ +DEF_ENC32(TAG##_fp0_jump_t, ICLASS_CJ" 01 0 "OPC" 1iissss PP10tttt iiiiiii-") \ +DEF_ENC32(TAG##_tp0_jump_nt, ICLASS_CJ" 01 0 "OPC" 0iissss PP00tttt iiiiiii-") \ +DEF_ENC32(TAG##_fp0_jump_nt, ICLASS_CJ" 01 0 "OPC" 1iissss PP00tttt iiiiiii-") \ +\ +DEF_ENC32(TAG##_tp1_jump_t, ICLASS_CJ" 01 0 "OPC" 0iissss PP11tttt iiiiiii-") \ +DEF_ENC32(TAG##_fp1_jump_t, ICLASS_CJ" 01 0 "OPC" 1iissss PP11tttt iiiiiii-") \ +DEF_ENC32(TAG##_tp1_jump_nt, ICLASS_CJ" 01 0 "OPC" 0iissss PP01tttt iiiiiii-") \ +DEF_ENC32(TAG##_fp1_jump_nt, ICLASS_CJ" 01 0 "OPC" 1iissss PP01tttt iiiiiii-") + +CMPJMPR_ENC(J4_cmpeq,"00") +CMPJMPR_ENC(J4_cmpgt,"01") +CMPJMPR_ENC(J4_cmpgtu,"10") + + +DEF_ENC32(J4_jumpseti, ICLASS_CJ" 0110 --iidddd PPIIIIII iiiiiii-") +DEF_ENC32(J4_jumpsetr, ICLASS_CJ" 0111 --iissss PP--dddd iiiiiii-") + + +DEF_EXT_SPACE(EXT_CJ, ICLASS_CJ"1 iii iiiiiiii PPiiiiii iiiiiiii") + + + +DEF_CLASS32(ICLASS_NCJ" 0--- -------- PP------ --------",NCJ) +DEF_FIELDROW_DESC32(ICLASS_NCJ" 00-- -------- -------- --------","[#0-3] if (cmp.xx(R.new,R)) jump:[h] #s9:2 ") +DEF_FIELDROW_DESC32(ICLASS_NCJ" 01-- -------- -------- --------","[#4-7] if (cmp.xx(R.new,#U5)) jump:[h] #s9:2 ") + +#define OPRJMP_ENC(TAG,OPC) \ +DEF_ENC32(TAG##_t_jumpnv_t, ICLASS_NCJ" 00 "OPC" 0ii-sss PP1ttttt iiiiiii-") \ +DEF_ENC32(TAG##_f_jumpnv_t, ICLASS_NCJ" 00 "OPC" 1ii-sss PP1ttttt iiiiiii-") \ +DEF_ENC32(TAG##_t_jumpnv_nt, ICLASS_NCJ" 00 "OPC" 0ii-sss PP0ttttt iiiiiii-") \ +DEF_ENC32(TAG##_f_jumpnv_nt, ICLASS_NCJ" 00 "OPC" 1ii-sss PP0ttttt iiiiiii-") + +OPRJMP_ENC(J4_cmpeq, "000") +OPRJMP_ENC(J4_cmpgt, "001") +OPRJMP_ENC(J4_cmpgtu, "010") +OPRJMP_ENC(J4_cmplt, "011") +OPRJMP_ENC(J4_cmpltu, "100") + + +#define OPIJMP_ENC(TAG,OPC) \ +DEF_ENC32(TAG##_t_jumpnv_t, ICLASS_NCJ" 01 "OPC" 0ii-sss PP1IIIII iiiiiii-") \ +DEF_ENC32(TAG##_f_jumpnv_t, ICLASS_NCJ" 01 "OPC" 1ii-sss PP1IIIII iiiiiii-") \ +DEF_ENC32(TAG##_t_jumpnv_nt, ICLASS_NCJ" 01 "OPC" 0ii-sss PP0IIIII iiiiiii-") \ +DEF_ENC32(TAG##_f_jumpnv_nt, ICLASS_NCJ" 01 "OPC" 1ii-sss PP0IIIII iiiiiii-") + +OPIJMP_ENC(J4_cmpeqi, "000") +OPIJMP_ENC(J4_cmpgti, "001") +OPIJMP_ENC(J4_cmpgtui, "010") + + +#define OPI1JMP_ENC(TAG,OPC) \ +DEF_ENC32(TAG##_t_jumpnv_t, ICLASS_NCJ" 01 "OPC" 0ii-sss PP1----- iiiiiii-") \ +DEF_ENC32(TAG##_f_jumpnv_t, ICLASS_NCJ" 01 "OPC" 1ii-sss PP1----- iiiiiii-") \ +DEF_ENC32(TAG##_t_jumpnv_nt, ICLASS_NCJ" 01 "OPC" 0ii-sss PP0----- iiiiiii-") \ +DEF_ENC32(TAG##_f_jumpnv_nt, ICLASS_NCJ" 01 "OPC" 1ii-sss PP0----- iiiiiii-") + +OPI1JMP_ENC(J4_cmpeqn1, "100") +OPI1JMP_ENC(J4_cmpgtn1, "101") +OPI1JMP_ENC(J4_tstbit0, "011") + + +DEF_EXT_SPACE(EXT_NCJ, ICLASS_NCJ"1 iii iiiiiiii PPiiiiii iiiiiiii") + + + +/*******************************/ +/* */ +/* */ +/* CR */ +/* */ +/* */ +/*******************************/ + + + +DEF_CLASS32(ICLASS_CR" ---- -------- PP------ --------",CR) +DEF_CLASS32(ICLASS_CR" -0-- -------- PP------ --------",CRUSER) +DEF_CLASS32(ICLASS_CR" -1-- -------- PP------ --------",CRSUPER) + +DEF_FIELD32(ICLASS_CR" -!-- -------- PP------ --------",CR_sm,"Supervisor mode only") + +/* User CR ops */ + +DEF_FIELDROW_DESC32( ICLASS_CR" 0000 -------- PP------ --------","[#0] (Rs,#r8)") +DEF_ENC32(J2_loop0r, ICLASS_CR" 0000 000sssss PP-iiiii ---ii---") +DEF_ENC32(J2_loop1r, ICLASS_CR" 0000 001sssss PP-iiiii ---ii---") +DEF_ENC32(J2_ploop1sr, ICLASS_CR" 0000 101sssss PP-iiiii ---ii---") +DEF_ENC32(J2_ploop2sr, ICLASS_CR" 0000 110sssss PP-iiiii ---ii---") +DEF_ENC32(J2_ploop3sr, ICLASS_CR" 0000 111sssss PP-iiiii ---ii---") + +DEF_FIELDROW_DESC32( ICLASS_CR" 0001 -------- PP------ --------","[#1] (Rs,#r13)") +DEF_ENC32(J2_jumprz, ICLASS_CR" 0001 00isssss PPi0iiii iiiiiii-") +DEF_ENC32(J2_jumprzpt, ICLASS_CR" 0001 00isssss PPi1iiii iiiiiii-") +DEF_ENC32(J2_jumprnz, ICLASS_CR" 0001 10isssss PPi0iiii iiiiiii-") +DEF_ENC32(J2_jumprnzpt, ICLASS_CR" 0001 10isssss PPi1iiii iiiiiii-") + +DEF_ENC32(J2_jumprgtez, ICLASS_CR" 0001 01isssss PPi0iiii iiiiiii-") +DEF_ENC32(J2_jumprgtezpt,ICLASS_CR" 0001 01isssss PPi1iiii iiiiiii-") +DEF_ENC32(J2_jumprltez, ICLASS_CR" 0001 11isssss PPi0iiii iiiiiii-") +DEF_ENC32(J2_jumprltezpt,ICLASS_CR" 0001 11isssss PPi1iiii iiiiiii-") + +DEF_FIELDROW_DESC32( ICLASS_CR" 0010 -------- PP------ --------","[#2] Cd=Rs ") +DEF_ENC32(A2_tfrrcr, ICLASS_CR" 0010 001sssss PP------ ---ddddd") + +DEF_FIELDROW_DESC32( ICLASS_CR" 0011 -------- PP------ --------","[#3] Cdd=Rss ") +DEF_ENC32(A4_tfrpcp, ICLASS_CR" 0011 001sssss PP------ ---ddddd") + +DEF_FIELDROW_DESC32( ICLASS_CR" 1000 -------- PP------ --------","[#8] Rdd=Css ") +DEF_ENC32(A4_tfrcpp, ICLASS_CR" 1000 000sssss PP------ ---ddddd") + +DEF_FIELDROW_DESC32( ICLASS_CR" 1001 -------- PP------ --------","[#9] (#r8,#U10)") +DEF_ENC32(J2_ploop1si, ICLASS_CR" 1001 101IIIII PP-iiiii IIIii-II") +DEF_ENC32(J2_ploop2si, ICLASS_CR" 1001 110IIIII PP-iiiii IIIii-II") +DEF_ENC32(J2_ploop3si, ICLASS_CR" 1001 111IIIII PP-iiiii IIIii-II") +DEF_ENC32(J2_loop0i, ICLASS_CR" 1001 000IIIII PP-iiiii IIIii-II") +DEF_ENC32(J2_loop1i, ICLASS_CR" 1001 001IIIII PP-iiiii IIIii-II") + +DEF_FIELDROW_DESC32( ICLASS_CR" 1010 -------- PP------ --------","[#10] Rd=Cs ") +DEF_ENC32(A2_tfrcrr, ICLASS_CR" 1010 000sssss PP------ ---ddddd") +DEF_ENC32(C4_addipc, ICLASS_CR" 1010 01001001 PP-iiiii i--ddddd") + + +DEF_FIELDROW_DESC32( ICLASS_CR" 1011 -------- PP0----- --------","[#11] Pd=(Ps,Pt,Pu)") +DEF_ENC32(C2_and, ICLASS_CR" 1011 0000--ss PP0---tt ------dd") +DEF_ENC32(C2_or, ICLASS_CR" 1011 0010--ss PP0---tt ------dd") +DEF_ENC32(C2_xor, ICLASS_CR" 1011 0100--ss PP0---tt ------dd") +DEF_ENC32(C2_andn, ICLASS_CR" 1011 0110--ss PP0---tt ------dd") +DEF_ENC32(C2_any8, ICLASS_CR" 1011 1000--ss PP0----- ------dd") +DEF_ENC32(C2_all8, ICLASS_CR" 1011 1010--ss PP0----- ------dd") +DEF_ENC32(C2_not, ICLASS_CR" 1011 1100--ss PP0----- ------dd") +DEF_ENC32(C2_orn, ICLASS_CR" 1011 1110--ss PP0---tt ------dd") + +DEF_ENC32(C4_and_and, ICLASS_CR" 1011 0001--ss PP0---tt uu----dd") +DEF_ENC32(C4_and_or, ICLASS_CR" 1011 0011--ss PP0---tt uu----dd") +DEF_ENC32(C4_or_and, ICLASS_CR" 1011 0101--ss PP0---tt uu----dd") +DEF_ENC32(C4_or_or, ICLASS_CR" 1011 0111--ss PP0---tt uu----dd") +DEF_ENC32(C4_and_andn, ICLASS_CR" 1011 1001--ss PP0---tt uu----dd") +DEF_ENC32(C4_and_orn, ICLASS_CR" 1011 1011--ss PP0---tt uu----dd") +DEF_ENC32(C4_or_andn, ICLASS_CR" 1011 1101--ss PP0---tt uu----dd") +DEF_ENC32(C4_or_orn, ICLASS_CR" 1011 1111--ss PP0---tt uu----dd") + +DEF_ENC32(C4_fastcorner9, ICLASS_CR"1011 0000--ss PP1---tt 1--1--dd") +DEF_ENC32(C4_fastcorner9_not, ICLASS_CR"1011 0001--ss PP1---tt 1--1--dd") + + + +/*******************************/ +/* */ +/* */ +/* M */ +/* */ +/* */ +/*******************************/ + + +DEF_CLASS32(ICLASS_M" ---- -------- PP------ --------",M) +DEF_FIELD32(ICLASS_M" !!!! -------- PP------ --------",M_RegType,"Register Type") +DEF_FIELD32(ICLASS_M" ---- !!!----- PP------ --------",M_MajOp,"Major Opcode") +DEF_FIELD32(ICLASS_M" ---- -------- PP------ !!!-----",M_MinOp,"Minor Opcode") + + + +#define SP_MPY(TAG,REGTYPE,DSTCHARS,SAT,RND,UNS)\ +DEF_ENC32(TAG##_ll_s0, ICLASS_M REGTYPE "0" UNS RND"sssss PP-ttttt "SAT"00" DSTCHARS)\ +DEF_ENC32(TAG##_lh_s0, ICLASS_M REGTYPE "0" UNS RND"sssss PP-ttttt "SAT"01" DSTCHARS)\ +DEF_ENC32(TAG##_hl_s0, ICLASS_M REGTYPE "0" UNS RND"sssss PP-ttttt "SAT"10" DSTCHARS)\ +DEF_ENC32(TAG##_hh_s0, ICLASS_M REGTYPE "0" UNS RND"sssss PP-ttttt "SAT"11" DSTCHARS)\ +DEF_ENC32(TAG##_ll_s1, ICLASS_M REGTYPE "1" UNS RND"sssss PP-ttttt "SAT"00" DSTCHARS)\ +DEF_ENC32(TAG##_lh_s1, ICLASS_M REGTYPE "1" UNS RND"sssss PP-ttttt "SAT"01" DSTCHARS)\ +DEF_ENC32(TAG##_hl_s1, ICLASS_M REGTYPE "1" UNS RND"sssss PP-ttttt "SAT"10" DSTCHARS)\ +DEF_ENC32(TAG##_hh_s1, ICLASS_M REGTYPE "1" UNS RND"sssss PP-ttttt "SAT"11" DSTCHARS) + +/* Double precision */ +#define MPY_ENC(TAG,REGTYPE,DSTCHARS,SAT,RNDNAC,UNS,SHFT,VMIN2)\ +DEF_ENC32(TAG, ICLASS_M REGTYPE SHFT UNS RNDNAC"sssss PP0ttttt "SAT VMIN2 DSTCHARS) + +#define MPYI_ENC(TAG,REGTYPE,DSTCHARS,RNDNAC,UNS,SHFT)\ +DEF_ENC32(TAG, ICLASS_M REGTYPE SHFT UNS RNDNAC"sssss PP0iiiii iii" DSTCHARS) + + +DEF_FIELDROW_DESC32(ICLASS_M" 0000 -------- PP------ --------","[#0] Rd=(Rs,#u8)") +MPYI_ENC(M2_mpysip, "0000","ddddd","-","-","0" ) +MPYI_ENC(M2_mpysin, "0000","ddddd","-","-","1" ) + + +DEF_FIELDROW_DESC32(ICLASS_M" 0001 -------- PP------ --------","[#1] Rx=(Rs,#u8)") +MPYI_ENC(M2_macsip, "0001","xxxxx","-","-","0" ) +MPYI_ENC(M2_macsin, "0001","xxxxx","-","-","1" ) + + +DEF_FIELDROW_DESC32(ICLASS_M" 0010 -------- PP------ --------","[#2] Rx=(Rs,#s8)") +MPYI_ENC(M2_accii, "0010","xxxxx","-","-","0" ) +MPYI_ENC(M2_naccii, "0010","xxxxx","-","-","1" ) + + +DEF_FIELDROW_DESC32(ICLASS_M" 0011 -------- PP------ --------","[#3] Ry=(Ru,(Rs,Ry)) ") +DEF_ENC32(M4_mpyrr_addr,ICLASS_M" 0011 000sssss PP-yyyyy ---uuuuu") + + +DEF_FIELDROW_DESC32(ICLASS_M" 0100 -------- PP------ --------","[#4] Rdd=(Rs,Rt)") +DEF_FIELD32(ICLASS_M" 0100 -------- PP------ --!-----",Ma_tH,"Rt is High") /*Rt high */ +DEF_FIELD32(ICLASS_M" 0100 -------- PP------ -!------",Ma_sH,"Rs is High") /* Rs high */ +SP_MPY(M2_mpyd, "0100","ddddd","-","0","0") +SP_MPY(M2_mpyd_rnd, "0100","ddddd","-","1","0") +SP_MPY(M2_mpyud, "0100","ddddd","-","0","1") + + +DEF_FIELDROW_DESC32(ICLASS_M" 0101 -------- PP------ --------","[#5] Rdd=(Rs,Rt)") +MPY_ENC(M2_dpmpyss_s0, "0101","ddddd","0","0","0","0","00") +MPY_ENC(M2_dpmpyuu_s0, "0101","ddddd","0","0","1","0","00") +MPY_ENC(M2_vmpy2s_s0, "0101","ddddd","1","0","0","0","01") +MPY_ENC(M2_vmpy2s_s1, "0101","ddddd","1","0","0","1","01") +MPY_ENC(M2_cmpyi_s0, "0101","ddddd","0","0","0","0","01") +MPY_ENC(M2_cmpyr_s0, "0101","ddddd","0","0","0","0","10") +MPY_ENC(M2_cmpys_s0, "0101","ddddd","1","0","0","0","10") +MPY_ENC(M2_cmpys_s1, "0101","ddddd","1","0","0","1","10") +MPY_ENC(M2_cmpysc_s0, "0101","ddddd","1","0","1","0","10") +MPY_ENC(M2_cmpysc_s1, "0101","ddddd","1","0","1","1","10") +MPY_ENC(M2_vmpy2su_s0, "0101","ddddd","1","0","0","0","11") +MPY_ENC(M2_vmpy2su_s1, "0101","ddddd","1","0","0","1","11") +MPY_ENC(M4_pmpyw, "0101","ddddd","1","0","1","0","11") +MPY_ENC(M4_vpmpyh, "0101","ddddd","1","0","1","1","11") +MPY_ENC(M5_vmpybuu, "0101","ddddd","0","0","0","1","01") +MPY_ENC(M5_vmpybsu, "0101","ddddd","0","0","1","0","01") + + + + +DEF_FIELDROW_DESC32(ICLASS_M" 0110 -------- PP------ --------","[#6] Rxx=(Rs,Rt)") +DEF_FIELD32(ICLASS_M" 0110 -------- PP------ --!-----",Mb_tH,"Rt is High") /*Rt high */ +DEF_FIELD32(ICLASS_M" 0110 -------- PP------ -!------",Mb_sH,"Rs is High") /* Rs high */ +SP_MPY(M2_mpyd_acc, "0110","xxxxx","0","0","0") +SP_MPY(M2_mpyud_acc, "0110","xxxxx","0","0","1") +SP_MPY(M2_mpyd_nac, "0110","xxxxx","0","1","0") +SP_MPY(M2_mpyud_nac, "0110","xxxxx","0","1","1") + + +DEF_FIELDROW_DESC32(ICLASS_M" 0111 -------- PP------ --------","[#7] Rxx=(Rs,Rt)") +MPY_ENC(M2_dpmpyss_acc_s0, "0111","xxxxx","0","0","0","0","00") +MPY_ENC(M2_dpmpyss_nac_s0, "0111","xxxxx","0","1","0","0","00") +MPY_ENC(M2_dpmpyuu_acc_s0, "0111","xxxxx","0","0","1","0","00") +MPY_ENC(M2_dpmpyuu_nac_s0, "0111","xxxxx","0","1","1","0","00") +MPY_ENC(M2_vmac2s_s0, "0111","xxxxx","1","0","0","0","01") +MPY_ENC(M2_vmac2s_s1, "0111","xxxxx","1","0","0","1","01") +MPY_ENC(M2_cmaci_s0, "0111","xxxxx","0","0","0","0","01") +MPY_ENC(M2_cmacr_s0, "0111","xxxxx","0","0","0","0","10") +MPY_ENC(M2_cmacs_s0, "0111","xxxxx","1","0","0","0","10") +MPY_ENC(M2_cmacs_s1, "0111","xxxxx","1","0","0","1","10") +MPY_ENC(M2_cmacsc_s0, "0111","xxxxx","1","0","1","0","10") +MPY_ENC(M2_cmacsc_s1, "0111","xxxxx","1","0","1","1","10") +MPY_ENC(M2_vmac2, "0111","xxxxx","0","1","0","0","01") +MPY_ENC(M2_cnacs_s0, "0111","xxxxx","1","0","0","0","11") +MPY_ENC(M2_cnacs_s1, "0111","xxxxx","1","0","0","1","11") +MPY_ENC(M2_cnacsc_s0, "0111","xxxxx","1","0","1","0","11") +MPY_ENC(M2_cnacsc_s1, "0111","xxxxx","1","0","1","1","11") +MPY_ENC(M2_vmac2su_s0, "0111","xxxxx","1","1","1","0","01") +MPY_ENC(M2_vmac2su_s1, "0111","xxxxx","1","1","1","1","01") +MPY_ENC(M4_pmpyw_acc, "0111","xxxxx","1","1","0","0","11") +MPY_ENC(M4_vpmpyh_acc, "0111","xxxxx","1","1","0","1","11") +MPY_ENC(M5_vmacbuu, "0111","xxxxx","0","0","0","1","01") +MPY_ENC(M5_vmacbsu, "0111","xxxxx","0","0","1","1","01") + + + + + +DEF_FIELDROW_DESC32(ICLASS_M" 1000 -------- PP------ --------","[#8] Rdd=(Rss,Rtt)") +MPY_ENC(M2_vrcmpyi_s0, "1000","ddddd","0","0","0","0","00") +MPY_ENC(M2_vdmpys_s0, "1000","ddddd","1","0","0","0","00") +MPY_ENC(M2_vdmpys_s1, "1000","ddddd","1","0","0","1","00") +MPY_ENC(M2_vrcmpyi_s0c, "1000","ddddd","0","0","1","0","00") +MPY_ENC(M2_vabsdiffw, "1000","ddddd","0","1","0","0","00") +MPY_ENC(M6_vabsdiffub, "1000","ddddd","0","1","0","1","00") +MPY_ENC(M2_vabsdiffh, "1000","ddddd","0","1","1","0","00") +MPY_ENC(M6_vabsdiffb, "1000","ddddd","0","1","1","1","00") +MPY_ENC(M2_vrcmpys_s1_h, "1000","ddddd","1","1","0","1","00") +MPY_ENC(M2_vrcmpys_s1_l, "1000","ddddd","1","1","1","1","00") +MPY_ENC(M2_vrcmpyr_s0c, "1000","ddddd","0","1","1","0","01") +MPY_ENC(M2_vrcmpyr_s0, "1000","ddddd","0","0","0","0","01") +MPY_ENC(A2_vraddub, "1000","ddddd","0","0","1","0","01") +MPY_ENC(M2_mmpyl_s0, "1000","ddddd","1","0","0","0","01") +MPY_ENC(M2_mmpyl_s1, "1000","ddddd","1","0","0","1","01") +MPY_ENC(M2_mmpyl_rs0, "1000","ddddd","1","1","0","0","01") +MPY_ENC(M2_mmpyl_rs1, "1000","ddddd","1","1","0","1","01") +MPY_ENC(M2_mmpyul_s0, "1000","ddddd","1","0","1","0","01") +MPY_ENC(M2_mmpyul_s1, "1000","ddddd","1","0","1","1","01") +MPY_ENC(M2_mmpyul_rs0, "1000","ddddd","1","1","1","0","01") +MPY_ENC(M2_mmpyul_rs1, "1000","ddddd","1","1","1","1","01") +MPY_ENC(M2_vrmpy_s0, "1000","ddddd","0","0","0","0","10") +MPY_ENC(A2_vrsadub, "1000","ddddd","0","0","1","0","10") +MPY_ENC(M2_vmpy2es_s0, "1000","ddddd","1","0","0","0","10") +MPY_ENC(M2_vmpy2es_s1, "1000","ddddd","1","0","0","1","10") +MPY_ENC(M2_vcmpy_s0_sat_i, "1000","ddddd","1","0","1","0","10") +MPY_ENC(M2_vcmpy_s0_sat_r, "1000","ddddd","1","1","0","0","10") +MPY_ENC(M2_vcmpy_s1_sat_i, "1000","ddddd","1","0","1","1","10") +MPY_ENC(M2_vcmpy_s1_sat_r, "1000","ddddd","1","1","0","1","10") + +MPY_ENC(M2_mmpyh_s0, "1000","ddddd","1","0","0","0","11") +MPY_ENC(M2_mmpyh_s1, "1000","ddddd","1","0","0","1","11") +MPY_ENC(M2_mmpyh_rs0, "1000","ddddd","1","1","0","0","11") +MPY_ENC(M2_mmpyh_rs1, "1000","ddddd","1","1","0","1","11") +MPY_ENC(M2_mmpyuh_s0, "1000","ddddd","1","0","1","0","11") +MPY_ENC(M2_mmpyuh_s1, "1000","ddddd","1","0","1","1","11") +MPY_ENC(M2_mmpyuh_rs0, "1000","ddddd","1","1","1","0","11") +MPY_ENC(M2_mmpyuh_rs1, "1000","ddddd","1","1","1","1","11") + +MPY_ENC(M4_vrmpyeh_s0, "1000","ddddd","1","0","1","0","00") +MPY_ENC(M4_vrmpyeh_s1, "1000","ddddd","1","0","1","1","00") +MPY_ENC(M4_vrmpyoh_s0, "1000","ddddd","0","1","0","0","10") +MPY_ENC(M4_vrmpyoh_s1, "1000","ddddd","0","1","0","1","10") +MPY_ENC(M5_vrmpybuu, "1000","ddddd","0","0","0","1","01") +MPY_ENC(M5_vrmpybsu, "1000","ddddd","0","0","1","1","01") +MPY_ENC(M5_vdmpybsu, "1000","ddddd","0","1","0","1","01") + +MPY_ENC(F2_dfadd, "1000","ddddd","0","0","0","0","11") +MPY_ENC(F2_dfsub, "1000","ddddd","0","0","0","1","11") +MPY_ENC(F2_dfmpyfix, "1000","ddddd","0","0","1","0","11") +MPY_ENC(F2_dfmin, "1000","ddddd","0","0","1","1","11") +MPY_ENC(F2_dfmax, "1000","ddddd","0","1","0","0","11") +MPY_ENC(F2_dfmpyll, "1000","ddddd","0","1","0","1","11") +#ifdef ADD_DP_OPS +MPY_ENC(F2_dfdivcheat, "1000","ddddd","0","0","0","1","00") + +MPY_ENC(F2_dffixupn, "1000","ddddd","0","1","0","1","11") +MPY_ENC(F2_dffixupd, "1000","ddddd","0","1","1","0","11") +MPY_ENC(F2_dfrecipa, "1000","ddddd","0","1","1","1","ee") +#endif + +MPY_ENC(M7_dcmpyrw, "1000","ddddd","0","0","0","1","10") +MPY_ENC(M7_dcmpyrwc, "1000","ddddd","0","0","1","1","10") +MPY_ENC(M7_dcmpyiw, "1000","ddddd","0","1","1","0","10") +MPY_ENC(M7_dcmpyiwc, "1000","ddddd","0","1","1","1","10") + + + +DEF_FIELDROW_DESC32(ICLASS_M" 1001 -------- PP------ --------","[#9] Rd=(Rss,Rtt)") +MPY_ENC(M2_vdmpyrs_s0, "1001","ddddd","0","0","0","0","00") +MPY_ENC(M2_vdmpyrs_s1, "1001","ddddd","0","0","0","1","00") + +MPY_ENC(M7_wcmpyrw, "1001","ddddd","0","0","1","0","00") +MPY_ENC(M7_wcmpyrw_rnd, "1001","ddddd","0","0","1","1","00") +MPY_ENC(M7_wcmpyiw, "1001","ddddd","0","1","0","0","00") +MPY_ENC(M7_wcmpyiw_rnd, "1001","ddddd","0","1","0","1","00") + +MPY_ENC(M7_wcmpyrwc, "1001","ddddd","0","1","1","0","00") +MPY_ENC(M7_wcmpyrwc_rnd, "1001","ddddd","0","1","1","1","00") +MPY_ENC(M7_wcmpyiwc, "1001","ddddd","1","0","0","0","00") +MPY_ENC(M7_wcmpyiwc_rnd, "1001","ddddd","1","0","0","1","00") + + + +MPY_ENC(M2_vradduh, "1001","ddddd","-","-","-","0","01") +MPY_ENC(M2_vrcmpys_s1rp_h, "1001","ddddd","1","1","-","1","10") +MPY_ENC(M2_vrcmpys_s1rp_l, "1001","ddddd","1","1","-","1","11") +MPY_ENC(M2_vraddh, "1001","ddddd","1","1","-","0","11") + + +DEF_FIELDROW_DESC32(ICLASS_M" 1010 -------- PP------ --------","[#10] Rxx=(Rss,Rtt)") +MPY_ENC(M2_vrcmaci_s0, "1010","xxxxx","0","0","0","0","00") +MPY_ENC(M2_vdmacs_s0, "1010","xxxxx","1","0","0","0","00") +MPY_ENC(M2_vdmacs_s1, "1010","xxxxx","1","0","0","1","00") +MPY_ENC(M2_vrcmaci_s0c, "1010","xxxxx","0","0","1","0","00") +MPY_ENC(M2_vcmac_s0_sat_i, "1010","xxxxx","1","0","1","0","00") +MPY_ENC(M2_vcmac_s0_sat_r, "1010","xxxxx","1","1","0","0","00") +MPY_ENC(M2_vrcmpys_acc_s1_h, "1010","xxxxx","1","1","0","1","00") +MPY_ENC(M2_vrcmpys_acc_s1_l, "1010","xxxxx","1","1","1","1","00") +MPY_ENC(M2_vrcmacr_s0, "1010","xxxxx","0","0","0","0","01") +MPY_ENC(A2_vraddub_acc, "1010","xxxxx","0","0","1","0","01") +MPY_ENC(M2_mmacls_s0, "1010","xxxxx","1","0","0","0","01") +MPY_ENC(M2_mmacls_s1, "1010","xxxxx","1","0","0","1","01") +MPY_ENC(M2_mmacls_rs0, "1010","xxxxx","1","1","0","0","01") +MPY_ENC(M2_mmacls_rs1, "1010","xxxxx","1","1","0","1","01") +MPY_ENC(M2_mmaculs_s0, "1010","xxxxx","1","0","1","0","01") +MPY_ENC(M2_mmaculs_s1, "1010","xxxxx","1","0","1","1","01") +MPY_ENC(M2_mmaculs_rs0, "1010","xxxxx","1","1","1","0","01") +MPY_ENC(M2_mmaculs_rs1, "1010","xxxxx","1","1","1","1","01") +MPY_ENC(M2_vrcmacr_s0c, "1010","xxxxx","0","1","1","0","01") +MPY_ENC(M2_vrmac_s0, "1010","xxxxx","0","0","0","0","10") +MPY_ENC(A2_vrsadub_acc, "1010","xxxxx","0","0","1","0","10") +MPY_ENC(M2_vmac2es_s0, "1010","xxxxx","1","0","0","0","10") +MPY_ENC(M2_vmac2es_s1, "1010","xxxxx","1","0","0","1","10") +MPY_ENC(M2_vmac2es, "1010","xxxxx","0","1","0","0","10") +MPY_ENC(M2_mmachs_s0, "1010","xxxxx","1","0","0","0","11") +MPY_ENC(M2_mmachs_s1, "1010","xxxxx","1","0","0","1","11") +MPY_ENC(M2_mmachs_rs0, "1010","xxxxx","1","1","0","0","11") +MPY_ENC(M2_mmachs_rs1, "1010","xxxxx","1","1","0","1","11") +MPY_ENC(M2_mmacuhs_s0, "1010","xxxxx","1","0","1","0","11") +MPY_ENC(M2_mmacuhs_s1, "1010","xxxxx","1","0","1","1","11") +MPY_ENC(M2_mmacuhs_rs0, "1010","xxxxx","1","1","1","0","11") +MPY_ENC(M2_mmacuhs_rs1, "1010","xxxxx","1","1","1","1","11") +MPY_ENC(M4_vrmpyeh_acc_s0, "1010","xxxxx","1","1","0","0","10") +MPY_ENC(M4_vrmpyeh_acc_s1, "1010","xxxxx","1","1","0","1","10") +MPY_ENC(M4_vrmpyoh_acc_s0, "1010","xxxxx","1","1","1","0","10") +MPY_ENC(M4_vrmpyoh_acc_s1, "1010","xxxxx","1","1","1","1","10") +MPY_ENC(M5_vrmacbuu, "1010","xxxxx","0","0","0","1","01") +MPY_ENC(M5_vrmacbsu, "1010","xxxxx","0","0","1","1","01") +MPY_ENC(M5_vdmacbsu, "1010","xxxxx","0","1","0","0","01") + +MPY_ENC(F2_dfmpylh, "1010","xxxxx","0","0","0","0","11") +MPY_ENC(F2_dfmpyhh, "1010","xxxxx","0","0","0","1","11") +#ifdef ADD_DP_OPS +MPY_ENC(F2_dfmpyhh, "1010","xxxxx","0","0","1","0","11") +MPY_ENC(F2_dffma, "1010","xxxxx","0","0","0","0","11") +MPY_ENC(F2_dffms, "1010","xxxxx","0","0","0","1","11") + +MPY_ENC(F2_dffma_lib, "1010","xxxxx","0","0","1","0","11") +MPY_ENC(F2_dffms_lib, "1010","xxxxx","0","0","1","1","11") +MPY_ENC(F2_dffma_sc, "1010","xxxxx","0","1","1","1","uu") +#endif + + +MPY_ENC(M7_dcmpyrw_acc, "1010","xxxxx","0","0","0","1","10") +MPY_ENC(M7_dcmpyrwc_acc, "1010","xxxxx","0","0","1","1","10") +MPY_ENC(M7_dcmpyiw_acc, "1010","xxxxx","0","1","1","0","10") +MPY_ENC(M7_dcmpyiwc_acc, "1010","xxxxx","1","0","1","0","10") + + + + +/* +*/ + +DEF_FIELDROW_DESC32(ICLASS_M" 1011 -------- PP------ --------","[#11] Reserved") +MPY_ENC(F2_sfadd, "1011","ddddd","0","0","0","0","00") +MPY_ENC(F2_sfsub, "1011","ddddd","0","0","0","0","01") +MPY_ENC(F2_sfmax, "1011","ddddd","0","0","0","1","00") +MPY_ENC(F2_sfmin, "1011","ddddd","0","0","0","1","01") +MPY_ENC(F2_sfmpy, "1011","ddddd","0","0","1","0","00") +MPY_ENC(F2_sffixupn, "1011","ddddd","0","0","1","1","00") +MPY_ENC(F2_sffixupd, "1011","ddddd","0","0","1","1","01") + +DEF_FIELDROW_DESC32(ICLASS_M" 1100 -------- PP------ --------","[#12] Rd=(Rs,Rt)") +DEF_FIELD32(ICLASS_M" 1100 -------- PP------ --!-----",Mc_tH,"Rt is High") /*Rt high */ +DEF_FIELD32(ICLASS_M" 1100 -------- PP------ -!------",Mc_sH,"Rs is High") /* Rs high */ +SP_MPY(M2_mpy, "1100","ddddd","0","0","0") +SP_MPY(M2_mpy_sat, "1100","ddddd","1","0","0") +SP_MPY(M2_mpy_rnd, "1100","ddddd","0","1","0") +SP_MPY(M2_mpy_sat_rnd, "1100","ddddd","1","1","0") +SP_MPY(M2_mpyu, "1100","ddddd","0","0","1") + +DEF_FIELDROW_DESC32(ICLASS_M" 1101 -------- PP------ --------","[#13] Rd=(Rs,Rt)") +/* EJP: same as mpyi MPY_ENC(M2_mpyui, "1101","ddddd","0","0","1","0","00") */ +MPY_ENC(M2_mpyi, "1101","ddddd","0","0","0","0","00") +MPY_ENC(M2_mpy_up, "1101","ddddd","0","0","0","0","01") +MPY_ENC(M2_mpyu_up, "1101","ddddd","0","0","1","0","01") +MPY_ENC(M2_dpmpyss_rnd_s0, "1101","ddddd","0","1","0","0","01") +MPY_ENC(M2_cmpyrs_s0, "1101","ddddd","1","1","0","0","10") +MPY_ENC(M2_cmpyrs_s1, "1101","ddddd","1","1","0","1","10") +MPY_ENC(M2_cmpyrsc_s0, "1101","ddddd","1","1","1","0","10") +MPY_ENC(M2_cmpyrsc_s1, "1101","ddddd","1","1","1","1","10") +MPY_ENC(M2_vmpy2s_s0pack, "1101","ddddd","1","1","0","0","11") +MPY_ENC(M2_vmpy2s_s1pack, "1101","ddddd","1","1","0","1","11") +MPY_ENC(M2_hmmpyh_rs1, "1101","ddddd","1","1","0","1","00") +MPY_ENC(M2_hmmpyl_rs1, "1101","ddddd","1","1","1","1","00") + +MPY_ENC(M2_hmmpyh_s1, "1101","ddddd","0","1","0","1","00") +MPY_ENC(M2_hmmpyl_s1, "1101","ddddd","0","1","0","1","01") +MPY_ENC(M2_mpy_up_s1, "1101","ddddd","0","1","0","1","10") +MPY_ENC(M2_mpy_up_s1_sat, "1101","ddddd","0","1","1","1","00") +MPY_ENC(M2_mpysu_up, "1101","ddddd","0","1","1","0","01") + + +DEF_FIELDROW_DESC32(ICLASS_M" 1110 -------- PP------ --------","[#14] Rx=(Rs,Rt)") +DEF_FIELD32(ICLASS_M" 1110 -------- PP------ --!-----",Md_tH,"Rt is High") /*Rt high */ +DEF_FIELD32(ICLASS_M" 1110 -------- PP------ -!------",Md_sH,"Rs is High") /* Rs high */ +SP_MPY(M2_mpyu_acc, "1110","xxxxx","0","0","1") +SP_MPY(M2_mpy_acc, "1110","xxxxx","0","0","0") +SP_MPY(M2_mpy_acc_sat, "1110","xxxxx","1","0","0") +SP_MPY(M2_mpyu_nac, "1110","xxxxx","0","1","1") +SP_MPY(M2_mpy_nac, "1110","xxxxx","0","1","0") +SP_MPY(M2_mpy_nac_sat, "1110","xxxxx","1","1","0") + + +DEF_FIELDROW_DESC32(ICLASS_M" 1111 -------- PP------ --------","[#15] Rx=(Rs,Rt)") +MPY_ENC(M2_maci, "1111","xxxxx","0","0","0","0","00") +MPY_ENC(M2_mnaci, "1111","xxxxx","0","0","0","1","00") +MPY_ENC(M2_acci, "1111","xxxxx","0","0","0","0","01") +MPY_ENC(M2_nacci, "1111","xxxxx","0","0","0","1","01") +MPY_ENC(M2_xor_xacc, "1111","xxxxx","0","0","0","1","11") +MPY_ENC(M2_subacc, "1111","xxxxx","0","0","0","0","11") + +MPY_ENC(M4_mac_up_s1_sat, "1111","xxxxx","0","1","1","0","00") +MPY_ENC(M4_nac_up_s1_sat, "1111","xxxxx","0","1","1","0","01") + +MPY_ENC(M4_and_and, "1111","xxxxx","0","0","1","0","00") +MPY_ENC(M4_and_or, "1111","xxxxx","0","0","1","0","01") +MPY_ENC(M4_and_xor, "1111","xxxxx","0","0","1","0","10") +MPY_ENC(M4_or_and, "1111","xxxxx","0","0","1","0","11") +MPY_ENC(M4_or_or, "1111","xxxxx","0","0","1","1","00") +MPY_ENC(M4_or_xor, "1111","xxxxx","0","0","1","1","01") +MPY_ENC(M4_xor_and, "1111","xxxxx","0","0","1","1","10") +MPY_ENC(M4_xor_or, "1111","xxxxx","0","0","1","1","11") + +MPY_ENC(M4_or_andn, "1111","xxxxx","0","1","0","0","00") +MPY_ENC(M4_and_andn, "1111","xxxxx","0","1","0","0","01") +MPY_ENC(M4_xor_andn, "1111","xxxxx","0","1","0","0","10") + +MPY_ENC(F2_sffma, "1111","xxxxx","1","0","0","0","00") +MPY_ENC(F2_sffms, "1111","xxxxx","1","0","0","0","01") + +MPY_ENC(F2_sffma_lib, "1111","xxxxx","1","0","0","0","10") +MPY_ENC(F2_sffms_lib, "1111","xxxxx","1","0","0","0","11") + +MPY_ENC(F2_sffma_sc, "1111","xxxxx","1","1","1","0","uu") + + +/*******************************/ +/* */ +/* */ +/* ALU32_2op */ +/* */ +/* */ +/*******************************/ +DEF_CLASS32(ICLASS_ADDI" ---- -------- PP------ --------",ALU32_ADDI) + +DEF_CLASS32(ICLASS_ALU2op" ---- -------- PP------ --------",ALU32_2op) +DEF_FIELD32(ICLASS_ALU2op" !--- -------- PP------ --------",A2_Rs,"No Rs read") +DEF_FIELD32(ICLASS_ALU2op" -!!! -------- PP------ --------",A2_MajOp,"Major Opcode") +DEF_FIELD32(ICLASS_ALU2op" ---- !!!----- PP------ --------",A2_MinOp,"Minor Opcode") + +DEF_FIELD32(ICLASS_ALU3op" -!!! -------- PP------ --------",A3_MajOp,"Major Opcode") +DEF_FIELD32(ICLASS_ALU3op" ---- !!!----- PP------ --------",A3_MinOp,"Minor Opcode") +DEF_CLASS32(ICLASS_ALU3op" ---- -------- PP------ --------",ALU32_3op) +DEF_FIELD32(ICLASS_ALU3op" !--- -------- PP------ --------",A3_P,"Predicated") +DEF_FIELD32(ICLASS_ALU3op" ---- -------- PP!----- --------",A3_DN,"Dot-new") +DEF_FIELD32(ICLASS_ALU3op" ---- -------- PP------ !-------",A3_PS,"Predicate sense") + + +/*************************/ +/* Our good friend addi */ +/*************************/ +DEF_ENC32(A2_addi, ICLASS_ADDI" iiii iiisssss PPiiiiii iiiddddd") + + +/*******************************/ +/* Standard ALU32 insns */ +/*******************************/ + +#define ALU32_IRR_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS)\ +DEF_ENC32(TAG, ICLASS_ALU2op" "MAJ4" "MIN3"sssss PP"SMOD1"iiiii "VMIN3 DSTCHARS) + +#define ALU32_RR_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS)\ +DEF_ENC32(TAG, ICLASS_ALU2op" "MAJ4" "MIN3"sssss PP"SMOD1"----- "VMIN3 DSTCHARS) + +#define CONDA32_RR_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS)\ +DEF_ENC32(TAG##t, ICLASS_ALU2op" "MAJ4" "MIN3"sssss PP"SMOD1"-00uu "VMIN3 DSTCHARS)\ +DEF_ENC32(TAG##f, ICLASS_ALU2op" "MAJ4" "MIN3"sssss PP"SMOD1"-10uu "VMIN3 DSTCHARS)\ +DEF_ENC32(TAG##tnew,ICLASS_ALU2op" "MAJ4" "MIN3"sssss PP"SMOD1"-01uu "VMIN3 DSTCHARS)\ +DEF_ENC32(TAG##fnew,ICLASS_ALU2op" "MAJ4" "MIN3"sssss PP"SMOD1"-11uu "VMIN3 DSTCHARS) + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 0000 -------- PP------ --------","[#0] (Pu) Rd=(Rs)") +DEF_FIELD32( ICLASS_ALU2op" 0000 -------- PP!----- --------",A32a_C,"Conditional") +DEF_FIELD32( ICLASS_ALU2op" 0000 -------- PP--!--- --------",A32a_S,"Predicate sense") +DEF_FIELD32( ICLASS_ALU2op" 0000 -------- PP---!-- --------",A32a_dn,"Dot-new") + +ALU32_RR_ENC(A2_aslh, "0000","000","0","---","ddddd") +ALU32_RR_ENC(A2_asrh, "0000","001","0","---","ddddd") +ALU32_RR_ENC(A2_tfr, "0000","011","0","---","ddddd") +ALU32_RR_ENC(A2_sxtb, "0000","101","0","---","ddddd") +ALU32_RR_ENC(A2_zxth, "0000","110","0","---","ddddd") +ALU32_RR_ENC(A2_sxth, "0000","111","0","---","ddddd") + +CONDA32_RR_ENC(A4_paslh, "0000","000","1","---","ddddd") +CONDA32_RR_ENC(A4_pasrh, "0000","001","1","---","ddddd") +CONDA32_RR_ENC(A4_pzxtb, "0000","100","1","---","ddddd") +CONDA32_RR_ENC(A4_psxtb, "0000","101","1","---","ddddd") +CONDA32_RR_ENC(A4_pzxth, "0000","110","1","---","ddddd") +CONDA32_RR_ENC(A4_psxth, "0000","111","1","---","ddddd") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 0001 -------- PP------ --------","[#1] Rx=(#u16)") +DEF_ENC32(A2_tfril, ICLASS_ALU2op" 0001 ii1xxxxx PPiiiiii iiiiiiii") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 0010 -------- PP------ --------","[#2] Rx=(#u16)") +DEF_ENC32(A2_tfrih, ICLASS_ALU2op" 0010 ii1xxxxx PPiiiiii iiiiiiii") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 0011 -------- PP------ --------","[#3] Rd=(Pu,Rs,#s8)") +DEF_ENC32(C2_muxir, ICLASS_ALU2op" 0011 0uusssss PP0iiiii iiiddddd") +DEF_ENC32(C2_muxri, ICLASS_ALU2op" 0011 1uusssss PP0iiiii iiiddddd") + +DEF_ENC32(A4_combineri, ICLASS_ALU2op" 0011 -00sssss PP1iiiii iiiddddd") /* Rdd = (Rs,#s8) */ +DEF_ENC32(A4_combineir, ICLASS_ALU2op" 0011 -01sssss PP1iiiii iiiddddd") /* Rdd = (Rs,#s8) */ +DEF_ENC32(A4_rcmpeqi, ICLASS_ALU2op" 0011 -10sssss PP1iiiii iiiddddd") /* Rd = (Rs,#s8) */ +DEF_ENC32(A4_rcmpneqi, ICLASS_ALU2op" 0011 -11sssss PP1iiiii iiiddddd") /* Rd = (Rs,#s8) */ + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 0100 -------- PP------ --------","[#4] (Pu) Rd=(Rs,#s8)") +DEF_FIELD32( ICLASS_ALU2op" 0100 -------- PP!----- --------",A32a_DN,"Dot-new") +DEF_FIELD32( ICLASS_ALU2op" 0100 !------- PP------ --------",A32a_PS,"Predicate sense") +DEF_ENC32(A2_paddit, ICLASS_ALU2op" 0100 0uusssss PP0iiiii iiiddddd") +DEF_ENC32(A2_padditnew, ICLASS_ALU2op" 0100 0uusssss PP1iiiii iiiddddd") +DEF_ENC32(A2_paddif, ICLASS_ALU2op" 0100 1uusssss PP0iiiii iiiddddd") +DEF_ENC32(A2_paddifnew, ICLASS_ALU2op" 0100 1uusssss PP1iiiii iiiddddd") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 0101 -------- PP------ --------","[#5] Pd=(Rs,#s10)") +DEF_ENC32(C2_cmpeqi, ICLASS_ALU2op" 0101 00isssss PPiiiiii iii000dd") +DEF_ENC32(C2_cmpgti, ICLASS_ALU2op" 0101 01isssss PPiiiiii iii000dd") +DEF_ENC32(C2_cmpgtui, ICLASS_ALU2op" 0101 100sssss PPiiiiii iii000dd") + +DEF_ENC32(C4_cmpneqi, ICLASS_ALU2op" 0101 00isssss PPiiiiii iii100dd") +DEF_ENC32(C4_cmpltei, ICLASS_ALU2op" 0101 01isssss PPiiiiii iii100dd") +DEF_ENC32(C4_cmplteui, ICLASS_ALU2op" 0101 100sssss PPiiiiii iii100dd") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 0110 -------- PP------ --------","[#6] Rd=(Rs,#s10)") +ALU32_IRR_ENC(A2_andir, "0110","00i","i","iii","ddddd") +ALU32_IRR_ENC(A2_subri, "0110","01i","i","iii","ddddd") +ALU32_IRR_ENC(A2_orir, "0110","10i","i","iii","ddddd") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 0111 -------- PP------ --------","[#7] Reserved") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 1000 -------- PP------ --------","[#8] Rd=#s16") +DEF_ENC32(A2_tfrsi, ICLASS_ALU2op" 1000 ii-iiiii PPiiiiii iiiddddd") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 1001 -------- PP------ --------","[#9] Reserved") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 101- -------- PP------ --------","[#10,#11] Rd=(Pu,#s8,#S8)") +DEF_ENC32(C2_muxii, ICLASS_ALU2op" 101u uIIIIIII PPIiiiii iiiddddd") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 1100 -------- PP------ --------","[#12] Rdd=(#s8,#S8)") +DEF_ENC32(A2_combineii, ICLASS_ALU2op" 1100 0IIIIIII PPIiiiii iiiddddd") +DEF_ENC32(A4_combineii, ICLASS_ALU2op" 1100 1--IIIII PPIiiiii iiiddddd") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 1101 -------- PP------ --------","[#13] Reserved") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 1110 -------- PP------ --------","[#14] (Pu) Rd=#s12") +DEF_FIELD32( ICLASS_ALU2op" 1110 ---0---- PP!----- --------",A32c_DN,"Dot-new") +DEF_FIELD32( ICLASS_ALU2op" 1110 !--0---- PP------ --------",A32c_PS,"Predicate sense") +DEF_ENC32(C2_cmovenewit,ICLASS_ALU2op" 1110 0uu0iiii PP1iiiii iiiddddd") +DEF_ENC32(C2_cmovenewif,ICLASS_ALU2op" 1110 1uu0iiii PP1iiiii iiiddddd") +DEF_ENC32(C2_cmoveit, ICLASS_ALU2op" 1110 0uu0iiii PP0iiiii iiiddddd") +DEF_ENC32(C2_cmoveif, ICLASS_ALU2op" 1110 1uu0iiii PP0iiiii iiiddddd") + + +DEF_FIELDROW_DESC32( ICLASS_ALU2op" 1111 -------- PP------ --------","[#15] nop") +DEF_ENC32(A2_nop, ICLASS_ALU2op" 1111 -------- PP------ --------") + + + + + + + + + + + + +/*******************************/ +/* */ +/* */ +/* ALU32_3op */ +/* */ +/* */ +/*******************************/ + + +#define V2A32_RRR_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS)\ +DEF_ENC32(TAG, ICLASS_ALU3op" "MAJ4" "MIN3"sssss PP"SMOD1"ttttt "VMIN3 DSTCHARS) + +#define V2A32_RR_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS)\ +DEF_ENC32(TAG, ICLASS_ALU3op" "MAJ4" "MIN3"sssss PP"SMOD1"----- "VMIN3 DSTCHARS) + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 0000 -------- PP------ --------","[#0] Reserved") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 0001 -------- PP------ --------","[#1] Rd=(Rs,Rt)") +V2A32_RRR_ENC(A2_and, "0001","000","-","---","ddddd") +V2A32_RRR_ENC(A2_or, "0001","001","-","---","ddddd") +V2A32_RRR_ENC(A2_xor, "0001","011","-","---","ddddd") +V2A32_RRR_ENC(A4_andn, "0001","100","-","---","ddddd") +V2A32_RRR_ENC(A4_orn, "0001","101","-","---","ddddd") + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 0010 -------- PP------ --------","[#2] Pd=(Rs,Rt)") +V2A32_RRR_ENC(C2_cmpeq, "0010","-00","-","---","000dd") +V2A32_RRR_ENC(C2_cmpgt, "0010","-10","-","---","000dd") +V2A32_RRR_ENC(C2_cmpgtu, "0010","-11","-","---","000dd") + +V2A32_RRR_ENC(C4_cmpneq, "0010","-00","-","---","100dd") +V2A32_RRR_ENC(C4_cmplte, "0010","-10","-","---","100dd") +V2A32_RRR_ENC(C4_cmplteu, "0010","-11","-","---","100dd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 0011 -------- PP------ --------","[#3] Rd=(Rs,Rt)") +V2A32_RRR_ENC(A2_add, "0011","000","-","---","ddddd") +V2A32_RRR_ENC(A2_sub, "0011","001","-","---","ddddd") +V2A32_RRR_ENC(A2_combine_hh, "0011","100","-","---","ddddd") +V2A32_RRR_ENC(A2_combine_hl, "0011","101","-","---","ddddd") +V2A32_RRR_ENC(A2_combine_lh, "0011","110","-","---","ddddd") +V2A32_RRR_ENC(A2_combine_ll, "0011","111","-","---","ddddd") +V2A32_RRR_ENC(A4_rcmpeq, "0011","010","-","---","ddddd") +V2A32_RRR_ENC(A4_rcmpneq, "0011","011","-","---","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 0100 -------- PP------ --------","[#4] Rd=(Pu,Rs,Rt)") +V2A32_RRR_ENC(C2_mux, "0100","---","-","-uu","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 0101 -------- PP------ --------","[#5] Rdd=(Rs,Rt)") +V2A32_RRR_ENC(A2_combinew, "0101","0--","-","---","ddddd") +V2A32_RRR_ENC(S2_packhl, "0101","1--","-","---","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 0110 -------- PP------ --------","[#6] Rd=(Rs,Rt)") +V2A32_RRR_ENC(A2_svaddh, "0110","000","-","---","ddddd") +V2A32_RRR_ENC(A2_svaddhs, "0110","001","-","---","ddddd") +V2A32_RRR_ENC(A2_svadduhs, "0110","011","-","---","ddddd") +V2A32_RRR_ENC(A2_svsubh, "0110","100","-","---","ddddd") +V2A32_RRR_ENC(A2_svsubhs, "0110","101","-","---","ddddd") +V2A32_RRR_ENC(A2_svsubuhs, "0110","111","-","---","ddddd") +V2A32_RRR_ENC(A2_addsat, "0110","010","-","---","ddddd") +V2A32_RRR_ENC(A2_subsat, "0110","110","-","---","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 0111 -------- PP------ --------","[#7] Rd=(Rs,Rt)") +V2A32_RRR_ENC(A2_svavgh, "0111","-00","-","---","ddddd") +V2A32_RRR_ENC(A2_svavghs, "0111","-01","-","---","ddddd") +V2A32_RRR_ENC(A2_svnavgh, "0111","-11","-","---","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 1000 -------- PP------ --------","[#8] Reserved") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 1001 -------- PP------ --------","[#9] (Pu) Rd=(Rs,Rt)") +V2A32_RRR_ENC(A2_pandt, "1001","-00","0","0uu","ddddd") +V2A32_RRR_ENC(A2_pandtnew, "1001","-00","1","0uu","ddddd") +V2A32_RRR_ENC(A2_pandf, "1001","-00","0","1uu","ddddd") +V2A32_RRR_ENC(A2_pandfnew, "1001","-00","1","1uu","ddddd") +V2A32_RRR_ENC(A2_port, "1001","-01","0","0uu","ddddd") +V2A32_RRR_ENC(A2_portnew, "1001","-01","1","0uu","ddddd") +V2A32_RRR_ENC(A2_porf, "1001","-01","0","1uu","ddddd") +V2A32_RRR_ENC(A2_porfnew, "1001","-01","1","1uu","ddddd") +V2A32_RRR_ENC(A2_pxort, "1001","-11","0","0uu","ddddd") +V2A32_RRR_ENC(A2_pxortnew, "1001","-11","1","0uu","ddddd") +V2A32_RRR_ENC(A2_pxorf, "1001","-11","0","1uu","ddddd") +V2A32_RRR_ENC(A2_pxorfnew, "1001","-11","1","1uu","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 1010 -------- PP------ --------","[#10] Reserved") + + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 1011 -------- PP------ --------","[#11] (Pu) Rd=(Rs,Rt)") +V2A32_RRR_ENC(A2_paddt, "1011","0-0","0","0uu","ddddd") +V2A32_RRR_ENC(A2_paddtnew, "1011","0-0","1","0uu","ddddd") +V2A32_RRR_ENC(A2_paddf, "1011","0-0","0","1uu","ddddd") +V2A32_RRR_ENC(A2_paddfnew, "1011","0-0","1","1uu","ddddd") +V2A32_RRR_ENC(A2_psubt, "1011","0-1","0","0uu","ddddd") +V2A32_RRR_ENC(A2_psubtnew, "1011","0-1","1","0uu","ddddd") +V2A32_RRR_ENC(A2_psubf, "1011","0-1","0","1uu","ddddd") +V2A32_RRR_ENC(A2_psubfnew, "1011","0-1","1","1uu","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 1100 -------- PP------ --------","[#12] Reserved") + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 1101 -------- PP------ --------","[#13] (Pu) Rdd=(Rs,Rt)") +V2A32_RRR_ENC(C2_ccombinewnewt, "1101","000","1","0uu","ddddd") +V2A32_RRR_ENC(C2_ccombinewnewf, "1101","000","1","1uu","ddddd") +V2A32_RRR_ENC(C2_ccombinewt, "1101","000","0","0uu","ddddd") +V2A32_RRR_ENC(C2_ccombinewf, "1101","000","0","1uu","ddddd") + + + + + + +DEF_FIELDROW_DESC32(ICLASS_ALU3op" 1110 -------- PP------ --------","[#14] Reserved") + + + + + + + + + +/*******************************/ +/* */ +/* */ +/* S */ +/* */ +/* */ +/*******************************/ + +DEF_CLASS32(ICLASS_S2op" ---- -------- PP------ --------",S_2op) +DEF_FIELD32(ICLASS_S2op" !!!! -------- PP------ --------",STYPEB_RegType,"Register Type") +DEF_FIELD32(ICLASS_S2op" ---- !!------ PP------ --------",S2_MajOp,"Major Opcode") +DEF_FIELD32(ICLASS_S2op" ---- -------- PP------ !!!-----",S2_MinOp,"Minor Opcode") + +DEF_CLASS32(ICLASS_S3op" ---- -------- PP------ --------",S_3op) +DEF_FIELD32(ICLASS_S3op" !!!! -------- PP------ --------",STYPEA_RegType,"Register Type") +DEF_FIELD32(ICLASS_S3op" ---- !!------ PP------ --------",S3_Maj,"Major Opcode") +DEF_FIELD32(ICLASS_S3op" ---- -------- PP------ !!------",S3_Min,"Minor Opcode") + + +#define SH_RRR_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS) \ +DEF_ENC32(TAG,ICLASS_S3op" "MAJ4" "MIN3"sssss PP"SMOD1"ttttt "VMIN3 DSTCHARS) + +#define SH_RRRiENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS) \ +DEF_ENC32(TAG,ICLASS_S3op" "MAJ4" "MIN3"iiiii PP"SMOD1"ttttt "VMIN3 DSTCHARS) + +#define SH_RRR_ENCX(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS) \ +DEF_ENC32(TAG,ICLASS_S3op" "MAJ4" "MIN3"sssss PP"SMOD1"xxxxx "VMIN3 DSTCHARS) + +#define SH3_RR_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS) \ +DEF_ENC32(TAG,ICLASS_S3op" "MAJ4" "MIN3"sssss PP"SMOD1"----- "VMIN3 DSTCHARS) + +#define SH_PPP_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS) \ +DEF_ENC32(TAG,ICLASS_S3op" "MAJ4" "MIN3"---ss PP"SMOD1"---tt "VMIN3 DSTCHARS) + +#define SH2_RR_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS) \ +DEF_ENC32(TAG,ICLASS_S2op" "MAJ4" "MIN3"sssss PP"SMOD1"----- "VMIN3 DSTCHARS) + +#define SH2_PPP_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS) \ +DEF_ENC32(TAG,ICLASS_S2op" "MAJ4" "MIN3"---ss PP"SMOD1"---tt "VMIN3 DSTCHARS) + +#define SH_RRI4_ENC(TAG,MAJ4,MIN3,VMIN3,DSTCHARS) \ +DEF_ENC32(TAG,ICLASS_S2op" "MAJ4" "MIN3 "sssss PP00iiii " VMIN3 DSTCHARS) + +#define SH_RRI5_ENC(TAG,MAJ4,MIN3,VMIN3,DSTCHARS) \ +DEF_ENC32(TAG,ICLASS_S2op" "MAJ4" "MIN3 "sssss PP0iiiii " VMIN3 DSTCHARS) + +#define SH_RRI6_ENC(TAG,MAJ4,MIN3,VMIN3,DSTCHARS) \ +DEF_ENC32(TAG,ICLASS_S2op" "MAJ4" "MIN3 "sssss PPiiiiii " VMIN3 DSTCHARS) + +#define RSHIFTTYPES(TAGEND,MAJ4,MIN3,SMOD1,DMOD1,DSTCHARS) \ +SH_RRR_ENC(S2_asr_r_##TAGEND,MAJ4,MIN3,SMOD1,"00"DMOD1,DSTCHARS) \ +SH_RRR_ENC(S2_lsr_r_##TAGEND,MAJ4,MIN3,SMOD1,"01"DMOD1,DSTCHARS) \ +SH_RRR_ENC(S2_asl_r_##TAGEND,MAJ4,MIN3,SMOD1,"10"DMOD1,DSTCHARS) \ +SH_RRR_ENC(S2_lsl_r_##TAGEND,MAJ4,MIN3,SMOD1,"11"DMOD1,DSTCHARS) + + +#define I5SHIFTTYPES(TAGEND,MAJ4,MIN3,SMOD1,DSTCHARS) \ +SH_RRI5_ENC(S2_asr_i_##TAGEND,MAJ4,MIN3,SMOD1 "00",DSTCHARS) \ +SH_RRI5_ENC(S2_lsr_i_##TAGEND,MAJ4,MIN3,SMOD1 "01",DSTCHARS) \ +SH_RRI5_ENC(S2_asl_i_##TAGEND,MAJ4,MIN3,SMOD1 "10",DSTCHARS) \ +SH_RRI5_ENC(S6_rol_i_##TAGEND,MAJ4,MIN3,SMOD1 "11",DSTCHARS) + +#define I5SHIFTTYPES_NOROL(TAGEND,MAJ4,MIN3,SMOD1,DSTCHARS) \ +SH_RRI5_ENC(S2_asr_i_##TAGEND,MAJ4,MIN3,SMOD1 "00",DSTCHARS) \ +SH_RRI5_ENC(S2_lsr_i_##TAGEND,MAJ4,MIN3,SMOD1 "01",DSTCHARS) \ +SH_RRI5_ENC(S2_asl_i_##TAGEND,MAJ4,MIN3,SMOD1 "10",DSTCHARS) + +#define I5SHIFTTYPES_NOASR(TAGEND,MAJ4,MIN3,SMOD1,DSTCHARS) \ +SH_RRI5_ENC(S2_lsr_i_##TAGEND,MAJ4,MIN3,SMOD1 "01",DSTCHARS) \ +SH_RRI5_ENC(S2_asl_i_##TAGEND,MAJ4,MIN3,SMOD1 "10",DSTCHARS) \ +SH_RRI5_ENC(S6_rol_i_##TAGEND,MAJ4,MIN3,SMOD1 "11",DSTCHARS) + +#define I4SHIFTTYPES(TAGEND,MAJ4,MIN3,SMOD1,DSTCHARS) \ +SH_RRI4_ENC(S2_asr_i_##TAGEND,MAJ4,MIN3,SMOD1 "00",DSTCHARS) \ +SH_RRI4_ENC(S2_lsr_i_##TAGEND,MAJ4,MIN3,SMOD1 "01",DSTCHARS) \ +SH_RRI4_ENC(S2_asl_i_##TAGEND,MAJ4,MIN3,SMOD1 "10",DSTCHARS) + +#define I5ASHIFTTYPES(TAGEND,MAJ4,MIN3,SMOD1,DSTCHARS) \ +SH_RRI5_ENC(S2_asl_i_##TAGEND,MAJ4,MIN3,SMOD1 "10",DSTCHARS) + +#define I4ASHIFTTYPES(TAGEND,MAJ4,MIN3,SMOD1,DSTCHARS) \ +SH_RRI4_ENC(S2_asl_i_##TAGEND,MAJ4,MIN3,SMOD1 "10",DSTCHARS) + +#define I6SHIFTTYPES(TAGEND,MAJ4,MIN3,SMOD1,DSTCHARS) \ +SH_RRI6_ENC(S2_asr_i_##TAGEND,MAJ4,MIN3,SMOD1 "00",DSTCHARS) \ +SH_RRI6_ENC(S2_lsr_i_##TAGEND,MAJ4,MIN3,SMOD1 "01",DSTCHARS) \ +SH_RRI6_ENC(S2_asl_i_##TAGEND,MAJ4,MIN3,SMOD1 "10",DSTCHARS) \ +SH_RRI6_ENC(S6_rol_i_##TAGEND,MAJ4,MIN3,SMOD1 "11",DSTCHARS) \ + +#define I6SHIFTTYPES_NOASR(TAGEND,MAJ4,MIN3,SMOD1,DSTCHARS) \ +SH_RRI6_ENC(S2_lsr_i_##TAGEND,MAJ4,MIN3,SMOD1 "01",DSTCHARS) \ +SH_RRI6_ENC(S2_asl_i_##TAGEND,MAJ4,MIN3,SMOD1 "10",DSTCHARS) \ +SH_RRI6_ENC(S6_rol_i_##TAGEND,MAJ4,MIN3,SMOD1 "11",DSTCHARS) + + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 0000 -------- PP------ --------","[#0] Rdd=(Rss,#u6)") +/* EJP: there is actually quite a bit of space here, look at the reserved bits */ +I6SHIFTTYPES(p, "0000","000","0","ddddd") +I5SHIFTTYPES_NOROL(vw, "0000","010","0","ddddd") +I4SHIFTTYPES(vh, "0000","100","0","ddddd") + + + +/* False assume an immediate */ +SH2_RR_ENC(S2_vsathub_nopack, "0000","000","-","1 00","ddddd") +SH2_RR_ENC(S2_vsatwuh_nopack, "0000","000","-","1 01","ddddd") +SH2_RR_ENC(S2_vsatwh_nopack, "0000","000","-","1 10","ddddd") +SH2_RR_ENC(S2_vsathb_nopack, "0000","000","-","1 11","ddddd") + +SH_RRI4_ENC(S5_vasrhrnd, "0000","001", "0 00","ddddd") + +SH2_RR_ENC(A2_vabsh, "0000","010","-","1 00","ddddd") +SH2_RR_ENC(A2_vabshsat, "0000","010","-","1 01","ddddd") +SH2_RR_ENC(A2_vabsw, "0000","010","-","1 10","ddddd") +SH2_RR_ENC(A2_vabswsat, "0000","010","-","1 11","ddddd") + +SH2_RR_ENC(A2_notp, "0000","100","-","1 00","ddddd") +SH2_RR_ENC(A2_negp, "0000","100","-","1 01","ddddd") +SH2_RR_ENC(A2_absp, "0000","100","-","1 10","ddddd") +SH2_RR_ENC(A2_vconj, "0000","100","-","1 11","ddddd") + +SH2_RR_ENC(S2_deinterleave, "0000","110","-","1 00","ddddd") +SH2_RR_ENC(S2_interleave, "0000","110","-","1 01","ddddd") +SH2_RR_ENC(S2_brevp, "0000","110","-","1 10","ddddd") +SH_RRI6_ENC(S2_asr_i_p_rnd, "0000","110", "1 11","ddddd") + +SH2_RR_ENC(F2_conv_df2d, "0000","111","0","0 00","ddddd") +SH2_RR_ENC(F2_conv_df2ud, "0000","111","0","0 01","ddddd") +SH2_RR_ENC(F2_conv_ud2df, "0000","111","0","0 10","ddddd") +SH2_RR_ENC(F2_conv_d2df, "0000","111","0","0 11","ddddd") +#ifdef ADD_DP_OPS +SH2_RR_ENC(F2_dffixupr, "0000","111","0","1 00","ddddd") +SH2_RR_ENC(F2_dfsqrtcheat, "0000","111","0","1 01","ddddd") +#endif +SH2_RR_ENC(F2_conv_df2d_chop, "0000","111","0","1 10","ddddd") +SH2_RR_ENC(F2_conv_df2ud_chop,"0000","111","0","1 11","ddddd") +#ifdef ADD_DP_OPS +SH2_RR_ENC(F2_dfinvsqrta, "0000","111","1","0 ee","ddddd") +#endif + + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 0001 -------- PP------ --------","[#1] Rdd=(Rss,#u6,#U6)") +DEF_ENC32(S2_extractup,ICLASS_S2op" 0001 IIIsssss PPiiiiii IIIddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 0010 -------- PP------ --------","[#2] Rxx=(Rss,#u6)") +I6SHIFTTYPES(p_nac, "0010","00-","0","xxxxx") +I6SHIFTTYPES(p_acc, "0010","00-","1","xxxxx") +I6SHIFTTYPES(p_and, "0010","01-","0","xxxxx") +I6SHIFTTYPES(p_or, "0010","01-","1","xxxxx") +I6SHIFTTYPES_NOASR(p_xacc, "0010","10-","0","xxxxx") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 0011 -------- PP------ --------","[#3] Rxx=(Rss,#u6,#U6)") +DEF_ENC32(S2_insertp,ICLASS_S2op" 0011 IIIsssss PPiiiiii IIIxxxxx") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 0100 -------- PP------ --------","[#4] Rdd=(Rs)") +SH2_RR_ENC(S2_vsxtbh, "0100","00-","-","00-","ddddd") +SH2_RR_ENC(S2_vzxtbh, "0100","00-","-","01-","ddddd") +SH2_RR_ENC(S2_vsxthw, "0100","00-","-","10-","ddddd") +SH2_RR_ENC(S2_vzxthw, "0100","00-","-","11-","ddddd") +SH2_RR_ENC(A2_sxtw, "0100","01-","-","00-","ddddd") +SH2_RR_ENC(S2_vsplatrh, "0100","01-","-","01-","ddddd") +SH2_RR_ENC(S6_vsplatrbp, "0100","01-","-","10-","ddddd") + +SH2_RR_ENC(F2_conv_sf2df, "0100","1--","-","000","ddddd") +SH2_RR_ENC(F2_conv_uw2df, "0100","1--","-","001","ddddd") +SH2_RR_ENC(F2_conv_w2df, "0100","1--","-","010","ddddd") +SH2_RR_ENC(F2_conv_sf2ud, "0100","1--","-","011","ddddd") +SH2_RR_ENC(F2_conv_sf2d, "0100","1--","-","100","ddddd") +SH2_RR_ENC(F2_conv_sf2ud_chop, "0100","1--","-","101","ddddd") +SH2_RR_ENC(F2_conv_sf2d_chop, "0100","1--","-","110","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 0101 -------- PP------ --------","[#5] Pd=(Rs,#u6)") +DEF_ENC32(S2_tstbit_i,ICLASS_S2op" 0101 000sssss PP0iiiii ------dd") +DEF_ENC32(C2_tfrrp, ICLASS_S2op" 0101 010sssss PP------ ------dd") +DEF_ENC32(C2_bitsclri,ICLASS_S2op" 0101 100sssss PPiiiiii ------dd") +DEF_ENC32(S4_ntstbit_i,ICLASS_S2op"0101 001sssss PP0iiiii ------dd") +DEF_ENC32(C4_nbitsclri,ICLASS_S2op"0101 101sssss PPiiiiii ------dd") +DEF_ENC32(F2_sfclass, ICLASS_S2op"0101 111sssss PP0iiiii ------dd") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 0110 -------- PP------ --------","[#6] Rdd=(Pt)") +DEF_ENC32(C2_mask, ICLASS_S2op" 0110 --- ----- PP----tt --- ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 0111 -------- PP------ --------","[#7] Rx=(Rs,#u4,#S6)") +DEF_ENC32(S2_tableidxb,ICLASS_S2op" 0111 00isssss PPIIIIII iiixxxxx") +DEF_ENC32(S2_tableidxh,ICLASS_S2op" 0111 01isssss PPIIIIII iiixxxxx") +DEF_ENC32(S2_tableidxw,ICLASS_S2op" 0111 10isssss PPIIIIII iiixxxxx") +DEF_ENC32(S2_tableidxd,ICLASS_S2op" 0111 11isssss PPIIIIII iiixxxxx") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 1000 -------- PP------ --------","[#8] Rd=(Rss,#u6)") +SH2_RR_ENC(S2_vsathub, "1000","000","-","000","ddddd") +SH2_RR_ENC(S2_vsatwh, "1000","000","-","010","ddddd") +SH2_RR_ENC(S2_vsatwuh, "1000","000","-","100","ddddd") +SH2_RR_ENC(S2_vsathb, "1000","000","-","110","ddddd") +SH2_RR_ENC(S2_clbp, "1000","010","-","000","ddddd") +SH2_RR_ENC(S2_cl0p, "1000","010","-","010","ddddd") +SH2_RR_ENC(S2_cl1p, "1000","010","-","100","ddddd") +SH2_RR_ENC(S2_ct0p, "1000","111","-","010","ddddd") +SH2_RR_ENC(S2_ct1p, "1000","111","-","100","ddddd") +SH2_RR_ENC(S2_vtrunohb, "1000","100","-","000","ddddd") +SH2_RR_ENC(S2_vtrunehb, "1000","100","-","010","ddddd") +SH2_RR_ENC(S2_vrndpackwh, "1000","100","-","100","ddddd") +SH2_RR_ENC(S2_vrndpackwhs, "1000","100","-","110","ddddd") +SH2_RR_ENC(A2_sat, "1000","110","-","000","ddddd") +SH2_RR_ENC(A2_roundsat, "1000","110","-","001","ddddd") +SH_RRI5_ENC(S2_asr_i_svw_trun, "1000","110", "010","ddddd") +SH_RRI5_ENC(A4_bitspliti, "1000","110", "100","ddddd") + +SH_RRI5_ENC(A7_clip, "1000","110", "101","ddddd") +SH_RRI5_ENC(A7_vclip, "1000","110", "110","ddddd") + + +SH2_RR_ENC(S4_clbpnorm, "1000","011","-","000","ddddd") +SH_RRI6_ENC(S4_clbpaddi, "1000","011", "010","ddddd") +SH2_RR_ENC(S5_popcountp, "1000","011","-","011","ddddd") + +SH_RRI4_ENC(S5_asrhub_rnd_sat, "1000","011", "100","ddddd") +SH_RRI4_ENC(S5_asrhub_sat, "1000","011", "101","ddddd") + +SH2_RR_ENC(F2_conv_df2sf, "1000","000","-","001","ddddd") +SH2_RR_ENC(F2_conv_ud2sf, "1000","001","-","001","ddddd") +SH2_RR_ENC(F2_conv_d2sf, "1000","010","-","001","ddddd") +SH2_RR_ENC(F2_conv_df2uw, "1000","011","-","001","ddddd") +SH2_RR_ENC(F2_conv_df2w, "1000","100","-","001","ddddd") +SH2_RR_ENC(F2_conv_df2uw_chop, "1000","101","-","001","ddddd") +SH2_RR_ENC(F2_conv_df2w_chop, "1000","111","-","001","ddddd") + + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 1001 -------- PP------ --------","[#9] Rd=(Ps,Pt)") +DEF_ENC32(C2_vitpack, ICLASS_S2op" 1001 -00 ---ss PP----tt --- ddddd") +DEF_ENC32(C2_tfrpr, ICLASS_S2op" 1001 -1- ---ss PP------ --- ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 1010 -------- PP------ --------","[#10] Rdd=(Rss,#u6,#U6)") +DEF_ENC32(S4_extractp,ICLASS_S2op" 1010 IIIsssss PPiiiiii IIIddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 1011 -------- PP------ --------","[#11] Rd=(Rs)") +SH2_RR_ENC(F2_conv_uw2sf, "1011","001","-","000","ddddd") +SH2_RR_ENC(F2_conv_w2sf, "1011","010","-","000","ddddd") +SH2_RR_ENC(F2_conv_sf2uw, "1011","011","-","000","ddddd") +SH2_RR_ENC(F2_conv_sf2w, "1011","100","-","000","ddddd") +SH2_RR_ENC(F2_conv_sf2uw_chop, "1011","011","-","001","ddddd") +SH2_RR_ENC(F2_conv_sf2w_chop, "1011","100","-","001","ddddd") +SH2_RR_ENC(F2_sffixupr, "1011","101","-","000","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 1100 -------- PP------ --------","[#12] Rd=(Rs,#u6)") +I5SHIFTTYPES(r, "1100","000", "0 ","ddddd") +SH_RRI5_ENC(S2_asl_i_r_sat, "1100","010", "010","ddddd") +SH_RRI5_ENC(S2_asr_i_r_rnd, "1100","010", "000","ddddd") + +SH2_RR_ENC(S2_svsathb, "1100","10-","-", "00-","ddddd") +SH2_RR_ENC(S2_svsathub, "1100","10-","-", "01-","ddddd") + +SH_RRI5_ENC(A4_cround_ri, "1100","111", "00-","ddddd") +SH_RRI6_ENC(A7_croundd_ri, "1100","111", "01-","ddddd") +SH_RRI5_ENC(A4_round_ri, "1100","111", "10-","ddddd") +SH_RRI5_ENC(A4_round_ri_sat, "1100","111", "11-","ddddd") + +DEF_ENC32(S2_setbit_i, ICLASS_S2op" 1100 110sssss PP0iiiii 000ddddd") +DEF_ENC32(S2_clrbit_i, ICLASS_S2op" 1100 110sssss PP0iiiii 001ddddd") +DEF_ENC32(S2_togglebit_i,ICLASS_S2op" 1100 110sssss PP0iiiii 010ddddd") + +DEF_ENC32(S4_clbaddi ,ICLASS_S2op" 1100 001sssss PPiiiiii 000ddddd") + + + +/* False read #u6 */ +SH2_RR_ENC(S2_clb, "1100","000","-","1 00","ddddd") +SH2_RR_ENC(S2_cl0, "1100","000","-","1 01","ddddd") +SH2_RR_ENC(S2_cl1, "1100","000","-","1 10","ddddd") +SH2_RR_ENC(S2_clbnorm, "1100","000","-","1 11","ddddd") +SH2_RR_ENC(S2_ct0, "1100","010","-","1 00","ddddd") +SH2_RR_ENC(S2_ct1, "1100","010","-","1 01","ddddd") +SH2_RR_ENC(S2_brev, "1100","010","-","1 10","ddddd") +SH2_RR_ENC(S2_vsplatrb, "1100","010","-","1 11","ddddd") +SH2_RR_ENC(A2_abs, "1100","100","-","1 00","ddddd") +SH2_RR_ENC(A2_abssat, "1100","100","-","1 01","ddddd") +SH2_RR_ENC(A2_negsat, "1100","100","-","1 10","ddddd") +SH2_RR_ENC(A2_swiz, "1100","100","-","1 11","ddddd") +SH2_RR_ENC(A2_sath, "1100","110","-","1 00","ddddd") +SH2_RR_ENC(A2_satuh, "1100","110","-","1 01","ddddd") +SH2_RR_ENC(A2_satub, "1100","110","-","1 10","ddddd") +SH2_RR_ENC(A2_satb, "1100","110","-","1 11","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 1101 -------- PP------ --------","[#13] Rd=(Rs,#u6,#U6)") +DEF_ENC32(S2_extractu, ICLASS_S2op" 1101 0IIsssss PP0iiiii IIIddddd") +DEF_ENC32(S4_extract, ICLASS_S2op" 1101 1IIsssss PP0iiiii IIIddddd") +DEF_ENC32(S2_mask, ICLASS_S2op" 1101 0II----- PP1iiiii IIIddddd") + + + + + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 1110 -------- PP------ --------","[#14] Rx=(Rs,#u6)") +I5SHIFTTYPES(r_nac, "1110","00-","0","xxxxx") +I5SHIFTTYPES(r_acc, "1110","00-","1","xxxxx") +I5SHIFTTYPES(r_and, "1110","01-","0","xxxxx") +I5SHIFTTYPES(r_or, "1110","01-","1","xxxxx") +I5SHIFTTYPES_NOASR(r_xacc,"1110","10-","0","xxxxx") + + +DEF_FIELDROW_DESC32(ICLASS_S2op" 1111 -------- PP------ --------","[#15] Rs=(Rs,#u6,#U6)") +DEF_ENC32(S2_insert, ICLASS_S2op" 1111 0IIsssss PP0iiiii IIIxxxxx") + + + + + +/*************************/ +/* S_3_operand */ +/*************************/ + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 0000 -------- PP------ --------","[#0] Rdd=(Rss,Rtt,#u3)") +SH_RRR_ENC(S2_valignib, "0000","0--","-","iii","ddddd") +SH_RRR_ENC(S2_vspliceib, "0000","1--","-","iii","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 0001 -------- PP------ --------","[#1] Rdd=(Rss,Rtt)") +SH_RRR_ENC(S2_extractup_rp, "0001","00-","-","00-","ddddd") +SH_RRR_ENC(S2_shuffeb, "0001","00-","-","01-","ddddd") +SH_RRR_ENC(S2_shuffob, "0001","00-","-","10-","ddddd") +SH_RRR_ENC(S2_shuffeh, "0001","00-","-","11-","ddddd") + +SH_RRR_ENC(S2_shuffoh, "0001","10-","-","000","ddddd") +SH_RRR_ENC(S2_vtrunewh, "0001","10-","-","010","ddddd") +SH_RRR_ENC(S6_vtrunehb_ppp, "0001","10-","-","011","ddddd") +SH_RRR_ENC(S2_vtrunowh, "0001","10-","-","100","ddddd") +SH_RRR_ENC(S6_vtrunohb_ppp, "0001","10-","-","101","ddddd") +SH_RRR_ENC(S2_lfsp, "0001","10-","-","110","ddddd") + +SH_RRR_ENC(S4_vxaddsubw, "0001","01-","-","000","ddddd") +SH_RRR_ENC(A5_vaddhubs, "0001","01-","-","001","ddddd") +SH_RRR_ENC(S4_vxsubaddw, "0001","01-","-","010","ddddd") +SH_RRR_ENC(S4_vxaddsubh, "0001","01-","-","100","ddddd") +SH_RRR_ENC(S4_vxsubaddh, "0001","01-","-","110","ddddd") + +SH_RRR_ENC(S4_vxaddsubhr, "0001","11-","-","00-","ddddd") +SH_RRR_ENC(S4_vxsubaddhr, "0001","11-","-","01-","ddddd") +SH_RRR_ENC(S4_extractp_rp, "0001","11-","-","10-","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 0010 -------- PP------ --------","[#2] Rdd=(Rss,Rtt,Pu)") +SH_RRR_ENC(S2_valignrb, "0010","0--","-","-uu","ddddd") +SH_RRR_ENC(S2_vsplicerb, "0010","100","-","-uu","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 0011 -------- PP------ --------","[#3] Rdd=(Rss,Rt)") +RSHIFTTYPES(vw, "0011","00-","-","-","ddddd") +RSHIFTTYPES(vh, "0011","01-","-","-","ddddd") +RSHIFTTYPES(p, "0011","10-","-","-","ddddd") +SH_RRR_ENC(S2_vcrotate, "0011","11-","-","00-","ddddd") +SH_RRR_ENC(S2_vcnegh, "0011","11-","-","01-","ddddd") +SH_RRR_ENC(S4_vrcrotate, "0011","11-","i","11i","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 0100 -------- PP------ --------","[#4] Rd=(Rs,Rt,#u3)") +DEF_ENC32(S2_addasl_rrri, ICLASS_S3op" 0100 000 sssss PP0ttttt iiiddddd") + + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 0101 -------- PP------ --------","[#5] Rd=(Rss,Rt)") +SH_RRR_ENC(S2_asr_r_svw_trun, "0101","---","-","010","ddddd") +SH_RRR_ENC(M4_cmpyi_wh, "0101","---","-","100","ddddd") +SH_RRR_ENC(M4_cmpyr_wh, "0101","---","-","110","ddddd") +SH_RRR_ENC(M4_cmpyi_whc, "0101","---","-","101","ddddd") +SH_RRR_ENC(M4_cmpyr_whc, "0101","---","-","111","ddddd") + +DEF_FIELDROW_DESC32(ICLASS_S3op" 0110 -------- PP------ --------","[#6] Rd=(Rs,Rt)") +SH_RRR_ENC(S2_asr_r_r_sat, "0110","00-","-","00-","ddddd") \ +SH_RRR_ENC(S2_asl_r_r_sat, "0110","00-","-","10-","ddddd") + +RSHIFTTYPES(r, "0110","01-","-","-","ddddd") + +SH_RRR_ENC(S2_setbit_r, "0110","10-","-","00-","ddddd") +SH_RRR_ENC(S2_clrbit_r, "0110","10-","-","01-","ddddd") +SH_RRR_ENC(S2_togglebit_r, "0110","10-","-","10-","ddddd") +SH_RRRiENC(S4_lsli, "0110","10-","-","11i","ddddd") + +SH_RRR_ENC(A4_cround_rr, "0110","11-","-","00-","ddddd") +SH_RRR_ENC(A7_croundd_rr, "0110","11-","-","01-","ddddd") +SH_RRR_ENC(A4_round_rr, "0110","11-","-","10-","ddddd") +SH_RRR_ENC(A4_round_rr_sat, "0110","11-","-","11-","ddddd") + + + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 0111 -------- PP------ --------","[#7] Pd=(Rs,Rt)") +SH_RRR_ENC(S2_tstbit_r, "0111","000","-","---","---dd") +SH_RRR_ENC(C2_bitsset, "0111","010","-","---","---dd") +SH_RRR_ENC(C2_bitsclr, "0111","100","-","---","---dd") +SH_RRR_ENC(A4_cmpheq, "0111","110","-","011","---dd") +SH_RRR_ENC(A4_cmphgt, "0111","110","-","100","---dd") +SH_RRR_ENC(A4_cmphgtu, "0111","110","-","101","---dd") +SH_RRR_ENC(A4_cmpbeq, "0111","110","-","110","---dd") +SH_RRR_ENC(A4_cmpbgtu, "0111","110","-","111","---dd") +SH_RRR_ENC(A4_cmpbgt, "0111","110","-","010","---dd") +SH_RRR_ENC(S4_ntstbit_r, "0111","001","-","---","---dd") +SH_RRR_ENC(C4_nbitsset, "0111","011","-","---","---dd") +SH_RRR_ENC(C4_nbitsclr, "0111","101","-","---","---dd") + +SH_RRR_ENC(F2_sfcmpge, "0111","111","-","000","---dd") +SH_RRR_ENC(F2_sfcmpuo, "0111","111","-","001","---dd") +SH_RRR_ENC(F2_sfcmpeq, "0111","111","-","011","---dd") +SH_RRR_ENC(F2_sfcmpgt, "0111","111","-","100","---dd") + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 1000 -------- PP------ --------","[#8] Rx=(Rs,Rtt)") +SH_RRR_ENC(S2_insert_rp, "1000","---","-","---","xxxxx") + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 1001 -------- PP------ --------","[#9] Rd=(Rs,Rtt)") +SH_RRR_ENC(S2_extractu_rp, "1001","00-","-","00-","ddddd") +SH_RRR_ENC(S4_extract_rp, "1001","00-","-","01-","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 1010 -------- PP------ --------","[#10] Rxx=(Rss,Rtt)") +SH_RRR_ENC(S2_insertp_rp, "1010","0--","0","---","xxxxx") +SH_RRR_ENC(M4_xor_xacc, "1010","10-","0","000","xxxxx") + +DEF_FIELDROW_DESC32(ICLASS_S3op" 1011 -------- PP------ --------","[#11] Rxx=(Rss,Rt)") +RSHIFTTYPES(p_or, "1011","000","-","-","xxxxx") +RSHIFTTYPES(p_and, "1011","010","-","-","xxxxx") +RSHIFTTYPES(p_nac, "1011","100","-","-","xxxxx") +RSHIFTTYPES(p_acc, "1011","110","-","-","xxxxx") +RSHIFTTYPES(p_xor, "1011","011","-","-","xxxxx") + +SH_RRR_ENCX(A4_vrmaxh, "1011","001","0","001","uuuuu") +SH_RRR_ENCX(A4_vrmaxuh, "1011","001","1","001","uuuuu") +SH_RRR_ENCX(A4_vrmaxw, "1011","001","0","010","uuuuu") +SH_RRR_ENCX(A4_vrmaxuw, "1011","001","1","010","uuuuu") + +SH_RRR_ENCX(A4_vrminh, "1011","001","0","101","uuuuu") +SH_RRR_ENCX(A4_vrminuh, "1011","001","1","101","uuuuu") +SH_RRR_ENCX(A4_vrminw, "1011","001","0","110","uuuuu") +SH_RRR_ENCX(A4_vrminuw, "1011","001","1","110","uuuuu") + +SH_RRR_ENC(S2_vrcnegh, "1011","001","1","111","xxxxx") + +SH_RRR_ENC(S4_vrcrotate_acc, "1011","101","i","--i","xxxxx") + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 1100 -------- PP------ --------","[#12] Rx=(Rs,Rt)") +RSHIFTTYPES(r_or, "1100","00-","-","-","xxxxx") +RSHIFTTYPES(r_and, "1100","01-","-","-","xxxxx") +RSHIFTTYPES(r_nac, "1100","10-","-","-","xxxxx") +RSHIFTTYPES(r_acc, "1100","11-","-","-","xxxxx") + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 1101 -------- PP------ --------","[#13] Reserved") +DEF_FIELDROW_DESC32(ICLASS_S3op" 1110 -------- PP------ --------","[#14] Reserved") + + +DEF_FIELDROW_DESC32(ICLASS_S3op" 1111 -------- PP------ --------","[#14] User Instruction") + + + + + + + + + + + + + +/*******************************/ +/* */ +/* */ +/* ALU64 */ +/* */ +/* */ +/*******************************/ +DEF_CLASS32(ICLASS_ALU64" ---- -------- PP------ --------",ALU64) +DEF_FIELD32(ICLASS_ALU64" !!!! -------- PP------ --------",ALU64_RegType,"Register Type") +DEF_FIELD32(ICLASS_ALU64" 0--- !!!----- PP------ --------",A_MajOp,"Major Opcode") +DEF_FIELD32(ICLASS_ALU64" 0--- -------- PP------ !!!-----",A_MinOp,"Minor Opcode") +DEF_FIELD32(ICLASS_ALU64" 11-- -------- PP------ ---!!!!!",A_MajOp,"Major Opcode") + + + +#define ALU64_RRR_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS)\ +DEF_ENC32(TAG, ICLASS_ALU64" "MAJ4" "MIN3"sssss PP"SMOD1"ttttt "VMIN3 DSTCHARS) + +#define LEGACY_ALU64_RRR_ENC(TAG,MAJ4,MIN3,SMOD1,VMIN3,DSTCHARS)\ +LEGACY_DEF_ENC32(TAG, ICLASS_ALU64" "MAJ4" "MIN3"sssss PP"SMOD1"ttttt "VMIN3 DSTCHARS) + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 0000 -------- PP------ --------","[#0] Rd=(Rss,Rtt)") +ALU64_RRR_ENC(S2_parityp, "0000","---","-","---","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 0001 -------- PP------ --------","[#1] Rdd=(Pu,Rss,Rtt)") +ALU64_RRR_ENC(C2_vmux, "0001","---","-","-uu","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 0010 -------- PP------ --------","[#2] Pd=(Rss,Rtt)") +ALU64_RRR_ENC(A2_vcmpweq, "0010","0--","0","000","---dd") +ALU64_RRR_ENC(A2_vcmpwgt, "0010","0--","0","001","---dd") +ALU64_RRR_ENC(A2_vcmpwgtu, "0010","0--","0","010","---dd") +ALU64_RRR_ENC(A2_vcmpheq, "0010","0--","0","011","---dd") +ALU64_RRR_ENC(A2_vcmphgt, "0010","0--","0","100","---dd") +ALU64_RRR_ENC(A2_vcmphgtu, "0010","0--","0","101","---dd") +ALU64_RRR_ENC(A2_vcmpbeq, "0010","0--","0","110","---dd") +ALU64_RRR_ENC(A2_vcmpbgtu, "0010","0--","0","111","---dd") + +ALU64_RRR_ENC(A4_vcmpbeq_any, "0010","0--","1","000","---dd") +ALU64_RRR_ENC(A6_vcmpbeq_notany, "0010","0--","1","001","---dd") +ALU64_RRR_ENC(A4_vcmpbgt, "0010","0--","1","010","---dd") +ALU64_RRR_ENC(A4_tlbmatch, "0010","0--","1","011","---dd") +ALU64_RRR_ENC(A4_boundscheck_lo, "0010","0--","1","100","---dd") +ALU64_RRR_ENC(A4_boundscheck_hi, "0010","0--","1","101","---dd") + +ALU64_RRR_ENC(C2_cmpeqp, "0010","100","-","000","---dd") +ALU64_RRR_ENC(C2_cmpgtp, "0010","100","-","010","---dd") +ALU64_RRR_ENC(C2_cmpgtup, "0010","100","-","100","---dd") + +ALU64_RRR_ENC(F2_dfcmpeq, "0010","111","-","000","---dd") +ALU64_RRR_ENC(F2_dfcmpgt, "0010","111","-","001","---dd") +ALU64_RRR_ENC(F2_dfcmpge, "0010","111","-","010","---dd") +ALU64_RRR_ENC(F2_dfcmpuo, "0010","111","-","011","---dd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 0011 -------- PP------ --------","[#3] Rdd=(Rss,Rtt)") +ALU64_RRR_ENC(A2_vaddub, "0011","000","-","000","ddddd") +ALU64_RRR_ENC(A2_vaddubs, "0011","000","-","001","ddddd") +ALU64_RRR_ENC(A2_vaddh, "0011","000","-","010","ddddd") +ALU64_RRR_ENC(A2_vaddhs, "0011","000","-","011","ddddd") +ALU64_RRR_ENC(A2_vadduhs, "0011","000","-","100","ddddd") +ALU64_RRR_ENC(A2_vaddw, "0011","000","-","101","ddddd") +ALU64_RRR_ENC(A2_vaddws, "0011","000","-","110","ddddd") +ALU64_RRR_ENC(A2_addp, "0011","000","-","111","ddddd") + +ALU64_RRR_ENC(A2_vsubub, "0011","001","-","000","ddddd") +ALU64_RRR_ENC(A2_vsububs, "0011","001","-","001","ddddd") +ALU64_RRR_ENC(A2_vsubh, "0011","001","-","010","ddddd") +ALU64_RRR_ENC(A2_vsubhs, "0011","001","-","011","ddddd") +ALU64_RRR_ENC(A2_vsubuhs, "0011","001","-","100","ddddd") +ALU64_RRR_ENC(A2_vsubw, "0011","001","-","101","ddddd") +ALU64_RRR_ENC(A2_vsubws, "0011","001","-","110","ddddd") +ALU64_RRR_ENC(A2_subp, "0011","001","-","111","ddddd") + +ALU64_RRR_ENC(A2_vavgub, "0011","010","-","000","ddddd") +ALU64_RRR_ENC(A2_vavgubr, "0011","010","-","001","ddddd") +ALU64_RRR_ENC(A2_vavgh, "0011","010","-","010","ddddd") +ALU64_RRR_ENC(A2_vavghr, "0011","010","-","011","ddddd") +ALU64_RRR_ENC(A2_vavghcr, "0011","010","-","100","ddddd") +ALU64_RRR_ENC(A2_vavguh, "0011","010","-","101","ddddd") +ALU64_RRR_ENC(A2_vavguhr, "0011","010","-","11-","ddddd") + +ALU64_RRR_ENC(A2_vavgw, "0011","011","-","000","ddddd") +ALU64_RRR_ENC(A2_vavgwr, "0011","011","-","001","ddddd") +ALU64_RRR_ENC(A2_vavgwcr, "0011","011","-","010","ddddd") +ALU64_RRR_ENC(A2_vavguw, "0011","011","-","011","ddddd") +ALU64_RRR_ENC(A2_vavguwr, "0011","011","-","100","ddddd") +ALU64_RRR_ENC(A2_addpsat, "0011","011","-","101","ddddd") +ALU64_RRR_ENC(A2_addspl, "0011","011","-","110","ddddd") +ALU64_RRR_ENC(A2_addsph, "0011","011","-","111","ddddd") + +ALU64_RRR_ENC(A2_vnavgh, "0011","100","-","000","ddddd") +ALU64_RRR_ENC(A2_vnavghr, "0011","100","-","001","ddddd") +ALU64_RRR_ENC(A2_vnavghcr, "0011","100","-","010","ddddd") +ALU64_RRR_ENC(A2_vnavgw, "0011","100","-","011","ddddd") +ALU64_RRR_ENC(A2_vnavgwr, "0011","100","-","10-","ddddd") +ALU64_RRR_ENC(A2_vnavgwcr, "0011","100","-","11-","ddddd") + +ALU64_RRR_ENC(A2_vminub, "0011","101","-","000","ddddd") +ALU64_RRR_ENC(A2_vminh, "0011","101","-","001","ddddd") +ALU64_RRR_ENC(A2_vminuh, "0011","101","-","010","ddddd") +ALU64_RRR_ENC(A2_vminw, "0011","101","-","011","ddddd") +ALU64_RRR_ENC(A2_vminuw, "0011","101","-","100","ddddd") +ALU64_RRR_ENC(A2_vmaxuw, "0011","101","-","101","ddddd") +ALU64_RRR_ENC(A2_minp, "0011","101","-","110","ddddd") +ALU64_RRR_ENC(A2_minup, "0011","101","-","111","ddddd") + +ALU64_RRR_ENC(A2_vmaxub, "0011","110","-","000","ddddd") +ALU64_RRR_ENC(A2_vmaxh, "0011","110","-","001","ddddd") +ALU64_RRR_ENC(A2_vmaxuh, "0011","110","-","010","ddddd") +ALU64_RRR_ENC(A2_vmaxw, "0011","110","-","011","ddddd") +ALU64_RRR_ENC(A2_maxp, "0011","110","-","100","ddddd") +ALU64_RRR_ENC(A2_maxup, "0011","110","-","101","ddddd") +ALU64_RRR_ENC(A2_vmaxb, "0011","110","-","110","ddddd") +ALU64_RRR_ENC(A2_vminb, "0011","110","-","111","ddddd") + +ALU64_RRR_ENC(A2_andp, "0011","111","-","000","ddddd") +ALU64_RRR_ENC(A2_orp, "0011","111","-","010","ddddd") +ALU64_RRR_ENC(A2_xorp, "0011","111","-","100","ddddd") +ALU64_RRR_ENC(A4_andnp, "0011","111","-","001","ddddd") +ALU64_RRR_ENC(A4_ornp, "0011","111","-","011","ddddd") + +ALU64_RRR_ENC(A4_modwrapu, "0011","111","-","111","ddddd") + + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 0100 -------- PP------ --------","[#4] Rdd=(Rs,Rt)") +LEGACY_ALU64_RRR_ENC(S2_packhl, "0100","--0","-","---","ddddd") +ALU64_RRR_ENC(A4_bitsplit, "0100","--1","-","---","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 0101 -------- PP------ --------","[#5] Rd=(Rs,Rt)") +ALU64_RRR_ENC(A2_addh_l16_ll, "0101","000","-","00-","ddddd") +ALU64_RRR_ENC(A2_addh_l16_hl, "0101","000","-","01-","ddddd") +ALU64_RRR_ENC(A2_addh_l16_sat_ll,"0101","000","-","10-","ddddd") +ALU64_RRR_ENC(A2_addh_l16_sat_hl,"0101","000","-","11-","ddddd") + +ALU64_RRR_ENC(A2_subh_l16_ll, "0101","001","-","00-","ddddd") +ALU64_RRR_ENC(A2_subh_l16_hl, "0101","001","-","01-","ddddd") +ALU64_RRR_ENC(A2_subh_l16_sat_ll,"0101","001","-","10-","ddddd") +ALU64_RRR_ENC(A2_subh_l16_sat_hl,"0101","001","-","11-","ddddd") + +ALU64_RRR_ENC(A2_addh_h16_ll, "0101","010","-","000","ddddd") +ALU64_RRR_ENC(A2_addh_h16_lh, "0101","010","-","001","ddddd") +ALU64_RRR_ENC(A2_addh_h16_hl, "0101","010","-","010","ddddd") +ALU64_RRR_ENC(A2_addh_h16_hh, "0101","010","-","011","ddddd") +ALU64_RRR_ENC(A2_addh_h16_sat_ll,"0101","010","-","100","ddddd") +ALU64_RRR_ENC(A2_addh_h16_sat_lh,"0101","010","-","101","ddddd") +ALU64_RRR_ENC(A2_addh_h16_sat_hl,"0101","010","-","110","ddddd") +ALU64_RRR_ENC(A2_addh_h16_sat_hh,"0101","010","-","111","ddddd") + +ALU64_RRR_ENC(A2_subh_h16_ll, "0101","011","-","000","ddddd") +ALU64_RRR_ENC(A2_subh_h16_lh, "0101","011","-","001","ddddd") +ALU64_RRR_ENC(A2_subh_h16_hl, "0101","011","-","010","ddddd") +ALU64_RRR_ENC(A2_subh_h16_hh, "0101","011","-","011","ddddd") +ALU64_RRR_ENC(A2_subh_h16_sat_ll,"0101","011","-","100","ddddd") +ALU64_RRR_ENC(A2_subh_h16_sat_lh,"0101","011","-","101","ddddd") +ALU64_RRR_ENC(A2_subh_h16_sat_hl,"0101","011","-","110","ddddd") +ALU64_RRR_ENC(A2_subh_h16_sat_hh,"0101","011","-","111","ddddd") + +LEGACY_ALU64_RRR_ENC(A2_addsat, "0101","100","-","0--","ddddd") +LEGACY_ALU64_RRR_ENC(A2_subsat, "0101","100","-","1--","ddddd") + +ALU64_RRR_ENC(A2_min, "0101","101","-","0--","ddddd") +ALU64_RRR_ENC(A2_minu, "0101","101","-","1--","ddddd") + +ALU64_RRR_ENC(A2_max, "0101","110","-","0--","ddddd") +ALU64_RRR_ENC(A2_maxu, "0101","110","-","1--","ddddd") + +ALU64_RRR_ENC(S4_parity, "0101","111","-","---","ddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 0110 -------- PP------ --------","[#6] Rd=#u10 ") +DEF_ENC32(F2_sfimm_p, ICLASS_ALU64" 0110 00i ----- PPiiiiii iiiddddd") +DEF_ENC32(F2_sfimm_n, ICLASS_ALU64" 0110 01i ----- PPiiiiii iiiddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 0111 -------- PP------ --------","[#7] Rd=(Rs,Rt,#u6)") +DEF_ENC32(M4_mpyrr_addi, ICLASS_ALU64" 0111 0ii sssss PPittttt iiiddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 1000 -------- PP------ --------","[#8] Rd=(Rs,#u6,#U6)") +DEF_ENC32(M4_mpyri_addi, ICLASS_ALU64" 1000 Iii sssss PPiddddd iiiIIIII") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 1001 -------- PP------ --------","[#9] Rdd=#u10 ") +DEF_ENC32(F2_dfimm_p, ICLASS_ALU64" 1001 00i ----- PPiiiiii iiiddddd") +DEF_ENC32(F2_dfimm_n, ICLASS_ALU64" 1001 01i ----- PPiiiiii iiiddddd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 1010 -------- PP------ --------","[#10] Rx=(Rs,Rx,#s10)") +DEF_ENC32(S4_or_andix, ICLASS_ALU64" 1010 01i xxxxx PPiiiiii iiiuuuuu") +DEF_ENC32(S4_or_andi, ICLASS_ALU64" 1010 00i sssss PPiiiiii iiixxxxx") +DEF_ENC32(S4_or_ori, ICLASS_ALU64" 1010 10i sssss PPiiiiii iiixxxxx") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 1011 -------- PP------ --------","[#11] Rd=(Rs,Rd,#s6)") +DEF_ENC32(S4_addaddi, ICLASS_ALU64" 1011 0ii sssss PPiddddd iiiuuuuu") +DEF_ENC32(S4_subaddi, ICLASS_ALU64" 1011 1ii sssss PPiddddd iiiuuuuu") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 1100 -------- PP------ --------","[#12] Pd=(Rss,#s8)") +DEF_ENC32(A4_vcmpbeqi, ICLASS_ALU64"1100 000sssss PP-iiiii iii00-dd") +DEF_ENC32(A4_vcmpbgti, ICLASS_ALU64"1100 001sssss PP-iiiii iii00-dd") +DEF_ENC32(A4_vcmpbgtui, ICLASS_ALU64"1100 010sssss PP-0iiii iii00-dd") +DEF_ENC32(A4_vcmpheqi, ICLASS_ALU64"1100 000sssss PP-iiiii iii01-dd") +DEF_ENC32(A4_vcmphgti, ICLASS_ALU64"1100 001sssss PP-iiiii iii01-dd") +DEF_ENC32(A4_vcmphgtui, ICLASS_ALU64"1100 010sssss PP-0iiii iii01-dd") +DEF_ENC32(A4_vcmpweqi, ICLASS_ALU64"1100 000sssss PP-iiiii iii10-dd") +DEF_ENC32(A4_vcmpwgti, ICLASS_ALU64"1100 001sssss PP-iiiii iii10-dd") +DEF_ENC32(A4_vcmpwgtui, ICLASS_ALU64"1100 010sssss PP-0iiii iii10-dd") + +DEF_ENC32(F2_dfclass, ICLASS_ALU64"1100 100sssss PP-000ii iii10-dd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 1101 -------- PP------ --------","[#13] Pd=(Rs,#s8)") +DEF_ENC32(A4_cmpbeqi, ICLASS_ALU64"1101 -00sssss PP-iiiii iii00-dd") +DEF_ENC32(A4_cmpbgti, ICLASS_ALU64"1101 -01sssss PP-iiiii iii00-dd") +DEF_ENC32(A4_cmpbgtui, ICLASS_ALU64"1101 -10sssss PP-0iiii iii00-dd") +DEF_ENC32(A4_cmpheqi, ICLASS_ALU64"1101 -00sssss PP-iiiii iii01-dd") +DEF_ENC32(A4_cmphgti, ICLASS_ALU64"1101 -01sssss PP-iiiii iii01-dd") +DEF_ENC32(A4_cmphgtui, ICLASS_ALU64"1101 -10sssss PP-0iiii iii01-dd") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 1110 -------- PP------ --------","[#14] Rx=(#u9,op(Rx,#u5))") + +#define OP_OPI_RI(TAG,OPB)\ +DEF_ENC32(S4_andi_##TAG##_ri,ICLASS_ALU64" 1110 iiixxxxx PPiIIIII iii"OPB"i00-")\ +DEF_ENC32(S4_ori_##TAG##_ri, ICLASS_ALU64" 1110 iiixxxxx PPiIIIII iii"OPB"i01-")\ +DEF_ENC32(S4_addi_##TAG##_ri,ICLASS_ALU64" 1110 iiixxxxx PPiIIIII iii"OPB"i10-")\ +DEF_ENC32(S4_subi_##TAG##_ri,ICLASS_ALU64" 1110 iiixxxxx PPiIIIII iii"OPB"i11-") + +OP_OPI_RI(asl,"0") +OP_OPI_RI(lsr,"1") + + +DEF_FIELDROW_DESC32(ICLASS_ALU64" 1111 -------- PP------ --------","[#15] Rd=(Rs,Ru,#u6:2)") +DEF_ENC32(M4_mpyri_addr_u2, ICLASS_ALU64" 1111 0ii sssss PPiddddd iiiuuuuu") +DEF_ENC32(M4_mpyri_addr, ICLASS_ALU64" 1111 1ii sssss PPiddddd iiiuuuuu") diff --git a/target/hexagon/imported/encode_subinsn.def b/target/hexagon/imported/encode_subinsn.def new file mode 100644 index 0000000000..742fb50efb --- /dev/null +++ b/target/hexagon/imported/encode_subinsn.def @@ -0,0 +1,149 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + + +/* DEF_ENC_SUBINSN(TAG, CLASS, ENCSTR) */ + + + + +/*********************/ +/* Ld1-type subinsns */ +/*********************/ +DEF_ENC_SUBINSN(SL1_loadri_io, SUBINSN_L1, "0iiiissssdddd") +DEF_ENC_SUBINSN(SL1_loadrub_io, SUBINSN_L1, "1iiiissssdddd") + +/*********************/ +/* St1-type subinsns */ +/*********************/ +DEF_ENC_SUBINSN(SS1_storew_io, SUBINSN_S1, "0ii iisssstttt") +DEF_ENC_SUBINSN(SS1_storeb_io, SUBINSN_S1, "1ii iisssstttt") + + +/*********************/ +/* Ld2-type subinsns */ +/*********************/ +DEF_ENC_SUBINSN(SL2_loadrh_io, SUBINSN_L2, "00i iissssdddd") +DEF_ENC_SUBINSN(SL2_loadruh_io, SUBINSN_L2, "01i iissssdddd") +DEF_ENC_SUBINSN(SL2_loadrb_io, SUBINSN_L2, "10i iissssdddd") +DEF_ENC_SUBINSN(SL2_loadri_sp, SUBINSN_L2, "111 0iiiiidddd") +DEF_ENC_SUBINSN(SL2_loadrd_sp, SUBINSN_L2, "111 10iiiiiddd") + +DEF_ENC_SUBINSN(SL2_deallocframe,SUBINSN_L2, "111 1100---0--") + +DEF_ENC_SUBINSN(SL2_return, SUBINSN_L2, "111 1101---0--") +DEF_ENC_SUBINSN(SL2_return_t, SUBINSN_L2, "111 1101---100") +DEF_ENC_SUBINSN(SL2_return_f, SUBINSN_L2, "111 1101---101") +DEF_ENC_SUBINSN(SL2_return_tnew, SUBINSN_L2, "111 1101---110") +DEF_ENC_SUBINSN(SL2_return_fnew, SUBINSN_L2, "111 1101---111") + +DEF_ENC_SUBINSN(SL2_jumpr31, SUBINSN_L2, "111 1111---0--") +DEF_ENC_SUBINSN(SL2_jumpr31_t, SUBINSN_L2, "111 1111---100") +DEF_ENC_SUBINSN(SL2_jumpr31_f, SUBINSN_L2, "111 1111---101") +DEF_ENC_SUBINSN(SL2_jumpr31_tnew,SUBINSN_L2, "111 1111---110") +DEF_ENC_SUBINSN(SL2_jumpr31_fnew,SUBINSN_L2, "111 1111---111") + + +/*********************/ +/* St2-type subinsns */ +/*********************/ +DEF_ENC_SUBINSN(SS2_storeh_io, SUBINSN_S2, "00i iisssstttt") +DEF_ENC_SUBINSN(SS2_storew_sp, SUBINSN_S2, "010 0iiiiitttt") +DEF_ENC_SUBINSN(SS2_stored_sp, SUBINSN_S2, "010 1iiiiiittt") + +DEF_ENC_SUBINSN(SS2_storewi0, SUBINSN_S2, "100 00ssssiiii") +DEF_ENC_SUBINSN(SS2_storewi1, SUBINSN_S2, "100 01ssssiiii") +DEF_ENC_SUBINSN(SS2_storebi0, SUBINSN_S2, "100 10ssssiiii") +DEF_ENC_SUBINSN(SS2_storebi1, SUBINSN_S2, "100 11ssssiiii") + +DEF_ENC_SUBINSN(SS2_allocframe, SUBINSN_S2, "111 0iiiii----") + + + +/*******************/ +/* A-type subinsns */ +/*******************/ +DEF_ENC_SUBINSN(SA1_addi, SUBINSN_A, "00i iiiiiixxxx") +DEF_ENC_SUBINSN(SA1_seti, SUBINSN_A, "010 iiiiiidddd") +DEF_ENC_SUBINSN(SA1_addsp, SUBINSN_A, "011 iiiiiidddd") + +DEF_ENC_SUBINSN(SA1_tfr, SUBINSN_A, "100 00ssssdddd") +DEF_ENC_SUBINSN(SA1_inc, SUBINSN_A, "100 01ssssdddd") +DEF_ENC_SUBINSN(SA1_and1, SUBINSN_A, "100 10ssssdddd") +DEF_ENC_SUBINSN(SA1_dec, SUBINSN_A, "100 11ssssdddd") + +DEF_ENC_SUBINSN(SA1_sxth, SUBINSN_A, "101 00ssssdddd") +DEF_ENC_SUBINSN(SA1_sxtb, SUBINSN_A, "101 01ssssdddd") +DEF_ENC_SUBINSN(SA1_zxth, SUBINSN_A, "101 10ssssdddd") +DEF_ENC_SUBINSN(SA1_zxtb, SUBINSN_A, "101 11ssssdddd") + + +DEF_ENC_SUBINSN(SA1_addrx, SUBINSN_A, "110 00ssssxxxx") +DEF_ENC_SUBINSN(SA1_cmpeqi, SUBINSN_A, "110 01ssss--ii") +DEF_ENC_SUBINSN(SA1_setin1, SUBINSN_A, "110 1--0--dddd") +DEF_ENC_SUBINSN(SA1_clrtnew, SUBINSN_A, "110 1--100dddd") +DEF_ENC_SUBINSN(SA1_clrfnew, SUBINSN_A, "110 1--101dddd") +DEF_ENC_SUBINSN(SA1_clrt, SUBINSN_A, "110 1--110dddd") +DEF_ENC_SUBINSN(SA1_clrf, SUBINSN_A, "110 1--111dddd") + + +DEF_ENC_SUBINSN(SA1_combine0i, SUBINSN_A, "111 -0-ii00ddd") +DEF_ENC_SUBINSN(SA1_combine1i, SUBINSN_A, "111 -0-ii01ddd") +DEF_ENC_SUBINSN(SA1_combine2i, SUBINSN_A, "111 -0-ii10ddd") +DEF_ENC_SUBINSN(SA1_combine3i, SUBINSN_A, "111 -0-ii11ddd") +DEF_ENC_SUBINSN(SA1_combinezr, SUBINSN_A, "111 -1ssss0ddd") +DEF_ENC_SUBINSN(SA1_combinerz, SUBINSN_A, "111 -1ssss1ddd") + + + + +/* maybe R=cmpeq ? */ + + +/* Add a group of NCJ: if (R.new==#0) jump:hint #r9 */ +/* Add a group of NCJ: if (R.new!=#0) jump:hint #r9 */ +/* NCJ goes with LD1, LD2 */ + + + + +DEF_FIELD32("---! !!!! !!!!!!!! EE------ --------",SUBFIELD_B_SLOT1,"B: Slot1 Instruction") +DEF_FIELD32("---- ---- -------- EE-!!!!! !!!!!!!!",SUBFIELD_A_SLOT0,"A: Slot0 Instruction") + + +/* DEF_PACKED32(TAG, CLASSA, CLASSB, ENCSTR) */ + +DEF_PACKED32(P2_PACKED_L1_L1, SUBINSN_L1, SUBINSN_L1, "000B BBBB BBBB BBBB EE0A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_L1_L2, SUBINSN_L2, SUBINSN_L1, "000B BBBB BBBB BBBB EE1A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_L2_L2, SUBINSN_L2, SUBINSN_L2, "001B BBBB BBBB BBBB EE0A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_A_A, SUBINSN_A, SUBINSN_A, "001B BBBB BBBB BBBB EE1A AAAA AAAA AAAA") + +DEF_PACKED32(P2_PACKED_L1_A, SUBINSN_L1, SUBINSN_A, "010B BBBB BBBB BBBB EE0A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_L2_A, SUBINSN_L2, SUBINSN_A, "010B BBBB BBBB BBBB EE1A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_S1_A, SUBINSN_S1, SUBINSN_A, "011B BBBB BBBB BBBB EE0A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_S2_A, SUBINSN_S2, SUBINSN_A, "011B BBBB BBBB BBBB EE1A AAAA AAAA AAAA") + +DEF_PACKED32(P2_PACKED_S1_L1, SUBINSN_S1, SUBINSN_L1, "100B BBBB BBBB BBBB EE0A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_S1_L2, SUBINSN_S1, SUBINSN_L2, "100B BBBB BBBB BBBB EE1A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_S1_S1, SUBINSN_S1, SUBINSN_S1, "101B BBBB BBBB BBBB EE0A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_S1_S2, SUBINSN_S2, SUBINSN_S1, "101B BBBB BBBB BBBB EE1A AAAA AAAA AAAA") + +DEF_PACKED32(P2_PACKED_S2_L1, SUBINSN_S2, SUBINSN_L1, "110B BBBB BBBB BBBB EE0A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_S2_L2, SUBINSN_S2, SUBINSN_L2, "110B BBBB BBBB BBBB EE1A AAAA AAAA AAAA") +DEF_PACKED32(P2_PACKED_S2_S2, SUBINSN_S2, SUBINSN_S2, "111B BBBB BBBB BBBB EE0A AAAA AAAA AAAA") + +DEF_PACKED32(P2_PACKED_RESERVED, SUBINSN_INVALID, SUBINSN_INVALID, "111B BBBB BBBB BBBB EE1A AAAA AAAA AAAA") diff --git a/target/hexagon/imported/float.idef b/target/hexagon/imported/float.idef new file mode 100644 index 0000000000..76cecfebf5 --- /dev/null +++ b/target/hexagon/imported/float.idef @@ -0,0 +1,312 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Floating-Point Instructions + */ + +/*************************************/ +/* Scalar FP */ +/*************************************/ +Q6INSN(F2_sfadd,"Rd32=sfadd(Rs32,Rt32)",ATTRIBS(), +"Floating-Point Add", +{ RdV=fUNFLOAT(fFLOAT(RsV)+fFLOAT(RtV));}) + +Q6INSN(F2_sfsub,"Rd32=sfsub(Rs32,Rt32)",ATTRIBS(), +"Floating-Point Subtract", +{ RdV=fUNFLOAT(fFLOAT(RsV)-fFLOAT(RtV));}) + +Q6INSN(F2_sfmpy,"Rd32=sfmpy(Rs32,Rt32)",ATTRIBS(), +"Floating-Point Multiply", +{ RdV=fUNFLOAT(fSFMPY(fFLOAT(RsV),fFLOAT(RtV)));}) + +Q6INSN(F2_sffma,"Rx32+=sfmpy(Rs32,Rt32)",ATTRIBS(), +"Floating-Point Fused Multiply Add", +{ RxV=fUNFLOAT(fFMAF(fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV)));}) + +Q6INSN(F2_sffma_sc,"Rx32+=sfmpy(Rs32,Rt32,Pu4):scale",ATTRIBS(), +"Floating-Point Fused Multiply Add w/ Additional Scaling (2**Pu)", +{ + fHIDE(size4s_t tmp;) + fCHECKSFNAN3(RxV,RxV,RsV,RtV); + tmp=fUNFLOAT(fFMAFX(fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV),PuV)); + if (!((fFLOAT(RxV) == 0.0) && fISZEROPROD(fFLOAT(RsV),fFLOAT(RtV)))) RxV = tmp; +}) + +Q6INSN(F2_sffms,"Rx32-=sfmpy(Rs32,Rt32)",ATTRIBS(), +"Floating-Point Fused Multiply Add", +{ RxV=fUNFLOAT(fFMAF(-fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV))); }) + +Q6INSN(F2_sffma_lib,"Rx32+=sfmpy(Rs32,Rt32):lib",ATTRIBS(), +"Floating-Point Fused Multiply Add for Library Routines", +{ fFPSETROUND_NEAREST(); fHIDE(int infinp; int infminusinf; size4s_t tmp;) + infminusinf = ((isinf(fFLOAT(RxV))) && + (fISINFPROD(fFLOAT(RsV),fFLOAT(RtV))) && + (fGETBIT(31,RsV ^ RxV ^ RtV) != 0)); + infinp = (isinf(fFLOAT(RxV))) || (isinf(fFLOAT(RtV))) || (isinf(fFLOAT(RsV))); + fCHECKSFNAN3(RxV,RxV,RsV,RtV); + tmp=fUNFLOAT(fFMAF(fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV))); + if (!((fFLOAT(RxV) == 0.0) && fISZEROPROD(fFLOAT(RsV),fFLOAT(RtV)))) RxV = tmp; + fFPCANCELFLAGS(); + if (isinf(fFLOAT(RxV)) && !infinp) RxV = RxV - 1; + if (infminusinf) RxV = 0; +}) + +Q6INSN(F2_sffms_lib,"Rx32-=sfmpy(Rs32,Rt32):lib",ATTRIBS(), +"Floating-Point Fused Multiply Add for Library Routines", +{ fFPSETROUND_NEAREST(); fHIDE(int infinp; int infminusinf; size4s_t tmp;) + infminusinf = ((isinf(fFLOAT(RxV))) && + (fISINFPROD(fFLOAT(RsV),fFLOAT(RtV))) && + (fGETBIT(31,RsV ^ RxV ^ RtV) == 0)); + infinp = (isinf(fFLOAT(RxV))) || (isinf(fFLOAT(RtV))) || (isinf(fFLOAT(RsV))); + fCHECKSFNAN3(RxV,RxV,RsV,RtV); + tmp=fUNFLOAT(fFMAF(-fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV))); + if (!((fFLOAT(RxV) == 0.0) && fISZEROPROD(fFLOAT(RsV),fFLOAT(RtV)))) RxV = tmp; + fFPCANCELFLAGS(); + if (isinf(fFLOAT(RxV)) && !infinp) RxV = RxV - 1; + if (infminusinf) RxV = 0; +}) + + +Q6INSN(F2_sfcmpeq,"Pd4=sfcmp.eq(Rs32,Rt32)",ATTRIBS(), +"Floating Point Compare for Equal", +{PdV=f8BITSOF(fFLOAT(RsV)==fFLOAT(RtV));}) + +Q6INSN(F2_sfcmpgt,"Pd4=sfcmp.gt(Rs32,Rt32)",ATTRIBS(), +"Floating-Point Compare for Greater Than", +{PdV=f8BITSOF(fFLOAT(RsV)>fFLOAT(RtV));}) + +/* cmpge is not the same as !cmpgt(swapops) in IEEE */ + +Q6INSN(F2_sfcmpge,"Pd4=sfcmp.ge(Rs32,Rt32)",ATTRIBS(), +"Floating-Point Compare for Greater Than / Equal To", +{PdV=f8BITSOF(fFLOAT(RsV)>=fFLOAT(RtV));}) + +/* Everyone seems to have this... */ + +Q6INSN(F2_sfcmpuo,"Pd4=sfcmp.uo(Rs32,Rt32)",ATTRIBS(), +"Floating-Point Compare for Unordered", +{PdV=f8BITSOF(isunordered(fFLOAT(RsV),fFLOAT(RtV)));}) + + +Q6INSN(F2_sfmax,"Rd32=sfmax(Rs32,Rt32)",ATTRIBS(), +"Maximum of Floating-Point values", +{ RdV = fUNFLOAT(fSF_MAX(fFLOAT(RsV),fFLOAT(RtV))); }) + +Q6INSN(F2_sfmin,"Rd32=sfmin(Rs32,Rt32)",ATTRIBS(), +"Minimum of Floating-Point values", +{ RdV = fUNFLOAT(fSF_MIN(fFLOAT(RsV),fFLOAT(RtV))); }) + + +Q6INSN(F2_sfclass,"Pd4=sfclass(Rs32,#u5)",ATTRIBS(), +"Classify Floating-Point Value", +{ + fHIDE(int class;) + PdV = 0; + class = fpclassify(fFLOAT(RsV)); + /* Is the value zero? */ + if (fGETBIT(0,uiV) && (class == FP_ZERO)) PdV = 0xff; + if (fGETBIT(1,uiV) && (class == FP_NORMAL)) PdV = 0xff; + if (fGETBIT(2,uiV) && (class == FP_SUBNORMAL)) PdV = 0xff; + if (fGETBIT(3,uiV) && (class == FP_INFINITE)) PdV = 0xff; + if (fGETBIT(4,uiV) && (class == FP_NAN)) PdV = 0xff; + fFPCANCELFLAGS(); +}) + +/* Range: +/- (1.0 .. 1+(63/64)) * 2**(-6 .. +9) */ +/* More immediate bits should probably be used for more precision? */ + +Q6INSN(F2_sfimm_p,"Rd32=sfmake(#u10):pos",ATTRIBS(), +"Make Floating Point Value", +{ + RdV = (127 - 6) << 23; + RdV += uiV << 17; +}) + +Q6INSN(F2_sfimm_n,"Rd32=sfmake(#u10):neg",ATTRIBS(), +"Make Floating Point Value", +{ + RdV = (127 - 6) << 23; + RdV += (uiV << 17); + RdV |= (1 << 31); +}) + + +Q6INSN(F2_sffixupn,"Rd32=sffixupn(Rs32,Rt32)",ATTRIBS(), +"Fix Up Numerator", +{ + fHIDE(int adjust;) + fSF_RECIP_COMMON(RsV,RtV,RdV,adjust); + RdV = RsV; +}) + +Q6INSN(F2_sffixupd,"Rd32=sffixupd(Rs32,Rt32)",ATTRIBS(), +"Fix Up Denominator", +{ + fHIDE(int adjust;) + fSF_RECIP_COMMON(RsV,RtV,RdV,adjust); + RdV = RtV; +}) + +Q6INSN(F2_sffixupr,"Rd32=sffixupr(Rs32)",ATTRIBS(), +"Fix Up Radicand", +{ + fHIDE(int adjust;) + fSF_INVSQRT_COMMON(RsV,RdV,adjust); + RdV = RsV; +}) + +/*************************************/ +/* Scalar DP */ +/*************************************/ +Q6INSN(F2_dfadd,"Rdd32=dfadd(Rss32,Rtt32)",ATTRIBS(), +"Floating-Point Add", +{ RddV=fUNDOUBLE(fDOUBLE(RssV)+fDOUBLE(RttV));}) + +Q6INSN(F2_dfsub,"Rdd32=dfsub(Rss32,Rtt32)",ATTRIBS(), +"Floating-Point Subtract", +{ RddV=fUNDOUBLE(fDOUBLE(RssV)-fDOUBLE(RttV));}) + +Q6INSN(F2_dfmax,"Rdd32=dfmax(Rss32,Rtt32)",ATTRIBS(), +"Maximum of Floating-Point values", +{ RddV = fUNDOUBLE(fDF_MAX(fDOUBLE(RssV),fDOUBLE(RttV))); }) + +Q6INSN(F2_dfmin,"Rdd32=dfmin(Rss32,Rtt32)",ATTRIBS(), +"Minimum of Floating-Point values", +{ RddV = fUNDOUBLE(fDF_MIN(fDOUBLE(RssV),fDOUBLE(RttV))); }) + +Q6INSN(F2_dfmpyfix,"Rdd32=dfmpyfix(Rss32,Rtt32)",ATTRIBS(), +"Fix Up Multiplicand for Multiplication", +{ + if (fDF_ISDENORM(RssV) && fDF_ISBIG(RttV) && fDF_ISNORMAL(RttV)) RddV = fUNDOUBLE(fDOUBLE(RssV) * 0x1.0p52); + else if (fDF_ISDENORM(RttV) && fDF_ISBIG(RssV) && fDF_ISNORMAL(RssV)) RddV = fUNDOUBLE(fDOUBLE(RssV) * 0x1.0p-52); + else RddV = RssV; +}) + +Q6INSN(F2_dfmpyll,"Rdd32=dfmpyll(Rss32,Rtt32)",ATTRIBS(), +"Multiply low*low and shift off low 32 bits into sticky (in MSB)", +{ + fHIDE(size8u_t prod;) + prod = fMPY32UU(fGETUWORD(0,RssV),fGETUWORD(0,RttV)); + RddV = (prod >> 32) << 1; + if (fGETUWORD(0,prod) != 0) fSETBIT(0,RddV,1); +}) + +Q6INSN(F2_dfmpylh,"Rxx32+=dfmpylh(Rss32,Rtt32)",ATTRIBS(), +"Multiply low*high and accumulate", +{ + RxxV += (fGETUWORD(0,RssV) * (0x00100000 | fZXTN(20,64,fGETUWORD(1,RttV)))) << 1; +}) + +Q6INSN(F2_dfmpyhh,"Rxx32+=dfmpyhh(Rss32,Rtt32)",ATTRIBS(), +"Multiply high*high and accumulate with L*H value", +{ + RxxV = fUNDOUBLE(fDF_MPY_HH(fDOUBLE(RssV),fDOUBLE(RttV),RxxV)); +}) + + + +Q6INSN(F2_dfcmpeq,"Pd4=dfcmp.eq(Rss32,Rtt32)",ATTRIBS(), +"Floating Point Compare for Equal", +{PdV=f8BITSOF(fDOUBLE(RssV)==fDOUBLE(RttV));}) + +Q6INSN(F2_dfcmpgt,"Pd4=dfcmp.gt(Rss32,Rtt32)",ATTRIBS(), +"Floating-Point Compare for Greater Than", +{PdV=f8BITSOF(fDOUBLE(RssV)>fDOUBLE(RttV));}) + + +/* cmpge is not the same as !cmpgt(swapops) in IEEE */ + +Q6INSN(F2_dfcmpge,"Pd4=dfcmp.ge(Rss32,Rtt32)",ATTRIBS(), +"Floating-Point Compare for Greater Than / Equal To", +{PdV=f8BITSOF(fDOUBLE(RssV)>=fDOUBLE(RttV));}) + +/* Everyone seems to have this... */ + +Q6INSN(F2_dfcmpuo,"Pd4=dfcmp.uo(Rss32,Rtt32)",ATTRIBS(), +"Floating-Point Compare for Unordered", +{PdV=f8BITSOF(isunordered(fDOUBLE(RssV),fDOUBLE(RttV)));}) + + +Q6INSN(F2_dfclass,"Pd4=dfclass(Rss32,#u5)",ATTRIBS(), +"Classify Floating-Point Value", +{ + fHIDE(int class;) + PdV = 0; + class = fpclassify(fDOUBLE(RssV)); + /* Is the value zero? */ + if (fGETBIT(0,uiV) && (class == FP_ZERO)) PdV = 0xff; + if (fGETBIT(1,uiV) && (class == FP_NORMAL)) PdV = 0xff; + if (fGETBIT(2,uiV) && (class == FP_SUBNORMAL)) PdV = 0xff; + if (fGETBIT(3,uiV) && (class == FP_INFINITE)) PdV = 0xff; + if (fGETBIT(4,uiV) && (class == FP_NAN)) PdV = 0xff; + fFPCANCELFLAGS(); +}) + + +/* Range: +/- (1.0 .. 1+(63/64)) * 2**(-6 .. +9) */ +/* More immediate bits should probably be used for more precision? */ + +Q6INSN(F2_dfimm_p,"Rdd32=dfmake(#u10):pos",ATTRIBS(), +"Make Floating Point Value", +{ + RddV = (1023ULL - 6) << 52; + RddV += (fHIDE((size8u_t))uiV) << 46; +}) + +Q6INSN(F2_dfimm_n,"Rdd32=dfmake(#u10):neg",ATTRIBS(), +"Make Floating Point Value", +{ + RddV = (1023ULL - 6) << 52; + RddV += (fHIDE((size8u_t))uiV) << 46; + RddV |= ((1ULL) << 63); +}) + + +/* CONVERSION */ + +#define CONVERT(TAG,DEST,DESTV,SRC,SRCV,OUTCAST,OUTTYPE,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \ + Q6INSN(F2_conv_##TAG##MODETAG,#DEST"=convert_"#TAG"("#SRC")"#MODESYN,ATTRIBS(), \ + "Floating point format conversion", \ + { MODEBEH DESTV = OUTCAST(conv_##INTYPE##_to_##OUTTYPE(INCAST(SRCV))); }) + +CONVERT(sf2df,Rdd32,RddV,Rs32,RsV,fUNDOUBLE,df,fFLOAT,sf,,,) +CONVERT(df2sf,Rd32,RdV,Rss32,RssV,fUNFLOAT,sf,fDOUBLE,df,,,) + +#define ALLINTDST(TAGSTART,SRC,SRCV,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \ +CONVERT(TAGSTART##uw,Rd32,RdV,SRC,SRCV,fCAST4u,4u,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \ +CONVERT(TAGSTART##w,Rd32,RdV,SRC,SRCV,fCAST4s,4s,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \ +CONVERT(TAGSTART##ud,Rdd32,RddV,SRC,SRCV,fCAST8u,8u,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \ +CONVERT(TAGSTART##d,Rdd32,RddV,SRC,SRCV,fCAST8s,8s,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) + +#define ALLFPDST(TAGSTART,SRC,SRCV,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \ +CONVERT(TAGSTART##sf,Rd32,RdV,SRC,SRCV,fUNFLOAT,sf,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \ +CONVERT(TAGSTART##df,Rdd32,RddV,SRC,SRCV,fUNDOUBLE,df,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) + +#define ALLINTSRC(GEN,MODETAG,MODESYN,MODEBEH) \ +GEN(uw##2,Rs32,RsV,fCAST4u,4u,MODETAG,MODESYN,MODEBEH) \ +GEN(w##2,Rs32,RsV,fCAST4s,4s,MODETAG,MODESYN,MODEBEH) \ +GEN(ud##2,Rss32,RssV,fCAST8u,8u,MODETAG,MODESYN,MODEBEH) \ +GEN(d##2,Rss32,RssV,fCAST8s,8s,MODETAG,MODESYN,MODEBEH) + +#define ALLFPSRC(GEN,MODETAG,MODESYN,MODEBEH) \ +GEN(sf##2,Rs32,RsV,fFLOAT,sf,MODETAG,MODESYN,MODEBEH) \ +GEN(df##2,Rss32,RssV,fDOUBLE,df,MODETAG,MODESYN,MODEBEH) + +ALLINTSRC(ALLFPDST,,,) +ALLFPSRC(ALLINTDST,,,) +ALLFPSRC(ALLINTDST,_chop,:chop,fFPSETROUND_CHOP();) diff --git a/target/hexagon/imported/ldst.idef b/target/hexagon/imported/ldst.idef new file mode 100644 index 0000000000..78a2ea441c --- /dev/null +++ b/target/hexagon/imported/ldst.idef @@ -0,0 +1,286 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Load and Store instruction definitions + */ + +/* The set of addressing modes standard to all Load instructions */ +#define STD_LD_AMODES(TAG,OPER,DESCR,ATTRIB,SHFT,SEMANTICS,SCALE)\ +Q6INSN(L2_##TAG##_io, OPER"(Rs32+#s11:"SHFT")", ATTRIB,DESCR,{fIMMEXT(siV); fEA_RI(RsV,siV); SEMANTICS; })\ +Q6INSN(L4_##TAG##_ur, OPER"(Rt32<<#u2+#U6)", ATTRIB,DESCR,{fMUST_IMMEXT(UiV); fEA_IRs(UiV,RtV,uiV); SEMANTICS;})\ +Q6INSN(L4_##TAG##_ap, OPER"(Re32=#U6)", ATTRIB,DESCR,{fMUST_IMMEXT(UiV); fEA_IMM(UiV); SEMANTICS; ReV=UiV; })\ +Q6INSN(L2_##TAG##_pr, OPER"(Rx32++Mu2)", ATTRIB,DESCR,{fEA_REG(RxV); fPM_M(RxV,MuV); SEMANTICS;})\ +Q6INSN(L2_##TAG##_pi, OPER"(Rx32++#s4:"SHFT")", ATTRIB,DESCR,{fEA_REG(RxV); fPM_I(RxV,siV); SEMANTICS;})\ + +/* The set of 32-bit load instructions */ +STD_LD_AMODES(loadrub,"Rd32=memub","Load Unsigned Byte",ATTRIBS(A_LOAD),"0",fLOAD(1,1,u,EA,RdV),0) +STD_LD_AMODES(loadrb, "Rd32=memb", "Load signed Byte",ATTRIBS(A_LOAD),"0",fLOAD(1,1,s,EA,RdV),0) +STD_LD_AMODES(loadruh,"Rd32=memuh","Load unsigned Half integer",ATTRIBS(A_LOAD),"1",fLOAD(1,2,u,EA,RdV),1) +STD_LD_AMODES(loadrh, "Rd32=memh", "Load signed Half integer",ATTRIBS(A_LOAD),"1",fLOAD(1,2,s,EA,RdV),1) +STD_LD_AMODES(loadri, "Rd32=memw", "Load Word",ATTRIBS(A_LOAD),"2",fLOAD(1,4,u,EA,RdV),2) +STD_LD_AMODES(loadrd, "Rdd32=memd","Load Double integer",ATTRIBS(A_LOAD),"3",fLOAD(1,8,u,EA,RddV),3) + +/* The set of addressing modes standard to all Store instructions */ +#define STD_ST_AMODES(TAG,DEST,OPER,DESCR,ATTRIB,SHFT,SEMANTICS,SCALE)\ +Q6INSN(S2_##TAG##_io, OPER"(Rs32+#s11:"SHFT")="DEST, ATTRIB,DESCR,{fIMMEXT(siV); fEA_RI(RsV,siV); SEMANTICS; })\ +Q6INSN(S2_##TAG##_pi, OPER"(Rx32++#s4:"SHFT")="DEST, ATTRIB,DESCR,{fEA_REG(RxV); fPM_I(RxV,siV); SEMANTICS; })\ +Q6INSN(S4_##TAG##_ap, OPER"(Re32=#U6)="DEST, ATTRIB,DESCR,{fMUST_IMMEXT(UiV); fEA_IMM(UiV); SEMANTICS; ReV=UiV; })\ +Q6INSN(S2_##TAG##_pr, OPER"(Rx32++Mu2)="DEST, ATTRIB,DESCR,{fEA_REG(RxV); fPM_M(RxV,MuV); SEMANTICS; })\ +Q6INSN(S4_##TAG##_ur, OPER"(Ru32<<#u2+#U6)="DEST, ATTRIB,DESCR,{fMUST_IMMEXT(UiV); fEA_IRs(UiV,RuV,uiV); SEMANTICS;})\ + + +/* The set of 32-bit store instructions */ +STD_ST_AMODES(storerb, "Rt32", "memb","Store Byte",ATTRIBS(A_STORE),"0",fSTORE(1,1,EA,fGETBYTE(0,RtV)),0) +STD_ST_AMODES(storerh, "Rt32", "memh","Store Half integer",ATTRIBS(A_STORE),"1",fSTORE(1,2,EA,fGETHALF(0,RtV)),1) +STD_ST_AMODES(storerf, "Rt.H32", "memh","Store Upper Half integer",ATTRIBS(A_STORE),"1",fSTORE(1,2,EA,fGETHALF(1,RtV)),1) +STD_ST_AMODES(storeri, "Rt32", "memw","Store Word",ATTRIBS(A_STORE),"2",fSTORE(1,4,EA,RtV),2) +STD_ST_AMODES(storerd, "Rtt32","memd","Store Double integer",ATTRIBS(A_STORE),"3",fSTORE(1,8,EA,RttV),3) +STD_ST_AMODES(storerinew, "Nt8.new", "memw","Store Word",ATTRIBS(A_STORE),"2",fSTORE(1,4,EA,fNEWREG_ST(NtN)),2) +STD_ST_AMODES(storerbnew, "Nt8.new", "memb","Store Byte",ATTRIBS(A_STORE),"0",fSTORE(1,1,EA,fGETBYTE(0,fNEWREG_ST(NtN))),0) +STD_ST_AMODES(storerhnew, "Nt8.new", "memh","Store Half integer",ATTRIBS(A_STORE),"1",fSTORE(1,2,EA,fGETHALF(0,fNEWREG_ST(NtN))),1) + + +Q6INSN(S2_allocframe,"allocframe(Rx32,#u11:3):raw", ATTRIBS(A_STORE,A_RESTRICT_SLOT0ONLY), "Allocate stack frame", +{ fEA_RI(RxV,-8); fSTORE(1,8,EA,fFRAME_SCRAMBLE((fCAST8_8u(fREAD_LR()) << 32) | fCAST4_4u(fREAD_FP()))); fWRITE_FP(EA); fFRAMECHECK(EA-uiV,EA); RxV = EA-uiV; }) + +#define A_RETURN A_RESTRICT_SLOT0ONLY + +Q6INSN(L2_deallocframe,"Rdd32=deallocframe(Rs32):raw", ATTRIBS(A_LOAD), "Deallocate stack frame", +{ fHIDE(size8u_t tmp;) fEA_REG(RsV); + fLOAD(1,8,u,EA,tmp); + RddV = fFRAME_UNSCRAMBLE(tmp); + fWRITE_SP(EA+8); }) + +Q6INSN(L4_return,"Rdd32=dealloc_return(Rs32):raw", ATTRIBS(A_JINDIR,A_LOAD,A_RETURN), "Deallocate stack frame and return", +{ fHIDE(size8u_t tmp;) fEA_REG(RsV); + fLOAD(1,8,u,EA,tmp); + RddV = fFRAME_UNSCRAMBLE(tmp); + fWRITE_SP(EA+8); + fJUMPR(REG_LR,fGETWORD(1,RddV),COF_TYPE_JUMPR);}) + +#define CONDSEM(SRCREG,STALLBITS0,STALLBITS1,PREDFUNC,PREDARG,STALLSPEC,PREDCOND) \ +{ \ + fHIDE(size8u_t tmp;) \ + fBRANCH_SPECULATE_STALL(PREDFUNC##PREDCOND(PREDARG),,STALLSPEC,STALLBITS0,STALLBITS1); \ + fEA_REG(SRCREG); \ + if (PREDFUNC##PREDCOND(PREDARG)) { \ + fLOAD(1,8,u,EA,tmp); \ + RddV = fFRAME_UNSCRAMBLE(tmp); \ + fWRITE_SP(EA+8); \ + fJUMPR(REG_LR,fGETWORD(1,RddV),COF_TYPE_JUMPR); \ + } else { \ + LOAD_CANCEL(EA); \ + } \ +} + +#define COND_RETURN_TF(TG,TG2,DOTNEW,STALLBITS0,STALLBITS1,STALLSPEC,ATTRIBS,PREDFUNC,PREDARG,T_NT) \ + Q6INSN(TG##_t##TG2,"if (Pv4"DOTNEW") Rdd32=dealloc_return(Rs32)"T_NT":raw",ATTRIBS,"deallocate stack frame and return", \ + CONDSEM(RsV,STALLBITS0,STALLBITS1,PREDFUNC,PREDARG,STALLSPEC,)) \ + Q6INSN(TG##_f##TG2,"if (!Pv4"DOTNEW") Rdd32=dealloc_return(Rs32)"T_NT":raw",ATTRIBS,"deallocate stack frame and return", \ + CONDSEM(RsV,STALLBITS0,STALLBITS1,PREDFUNC##NOT,PREDARG,STALLSPEC,)) + +#define COND_RETURN_NEW(TG,STALLBITS0,STALLBITS1,ATTRIBS) \ + COND_RETURN_TF(TG,new_pt,".new",12,0,SPECULATE_TAKEN,ATTRIBS,fLSBNEW,PvN,":t") \ + COND_RETURN_TF(TG,new_pnt,".new",12,0,SPECULATE_NOT_TAKEN,ATTRIBS,fLSBNEW,PvN,":nt") \ + +#define RETURN_ATTRIBS A_LOAD,A_RETURN + +COND_RETURN_TF(L4_return,,,7,0,SPECULATE_NOT_TAKEN,ATTRIBS(RETURN_ATTRIBS,A_JINDIROLD),fLSBOLD,PvV,) +COND_RETURN_NEW(L4_return,12,0,ATTRIBS(RETURN_ATTRIBS,A_JINDIRNEW)) + + + + +Q6INSN(L2_loadw_locked,"Rd32=memw_locked(Rs32)", ATTRIBS(A_LOAD,A_RESTRICT_SLOT0ONLY), "Load word with lock", +{ fEA_REG(RsV); fLOAD_LOCKED(1,4,u,EA,RdV) }) + + +Q6INSN(S2_storew_locked,"memw_locked(Rs32,Pd4)=Rt32", ATTRIBS(A_STORE,A_RESTRICT_SLOT0ONLY), "Store word with lock", +{ fEA_REG(RsV); fSTORE_LOCKED(1,4,EA,RtV,PdV) }) + + +Q6INSN(L4_loadd_locked,"Rdd32=memd_locked(Rs32)", ATTRIBS(A_LOAD,A_RESTRICT_SLOT0ONLY), "Load double with lock", +{ fEA_REG(RsV); fLOAD_LOCKED(1,8,u,EA,RddV) }) + +Q6INSN(S4_stored_locked,"memd_locked(Rs32,Pd4)=Rtt32", ATTRIBS(A_STORE,A_RESTRICT_SLOT0ONLY), "Store word with lock", +{ fEA_REG(RsV); fSTORE_LOCKED(1,8,EA,RttV,PdV) }) + + + + + +/*****************************************************************/ +/* */ +/* Predicated LDST */ +/* */ +/*****************************************************************/ + +#define STD_PLD_AMODES(TAG,OPER,DESCR,ATTRIB,SHFT,SHFTNUM,SEMANTICS)\ +Q6INSN(L4_##TAG##_rr, OPER"(Rs32+Rt32<<#u2)", ATTRIB,DESCR,{fEA_RRs(RsV,RtV,uiV); SEMANTICS;})\ +Q6INSN(L2_p##TAG##t_io, "if (Pt4) "OPER"(Rs32+#u6:"SHFT")", ATTRIB,DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); if(fLSBOLD(PtV)){SEMANTICS;} else {LOAD_CANCEL(EA);}})\ +Q6INSN(L2_p##TAG##t_pi, "if (Pt4) "OPER"(Rx32++#s4:"SHFT")", ATTRIB,DESCR,{fEA_REG(RxV); if(fLSBOLD(PtV)){ fPM_I(RxV,siV); SEMANTICS;} else {LOAD_CANCEL(EA);}})\ +Q6INSN(L2_p##TAG##f_io, "if (!Pt4) "OPER"(Rs32+#u6:"SHFT")", ATTRIB,DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); if(fLSBOLDNOT(PtV)){ SEMANTICS; } else {LOAD_CANCEL(EA);}})\ +Q6INSN(L2_p##TAG##f_pi, "if (!Pt4) "OPER"(Rx32++#s4:"SHFT")", ATTRIB,DESCR,{fEA_REG(RxV); if(fLSBOLDNOT(PtV)){ fPM_I(RxV,siV); SEMANTICS;} else {LOAD_CANCEL(EA);}})\ +Q6INSN(L2_p##TAG##tnew_io,"if (Pt4.new) "OPER"(Rs32+#u6:"SHFT")",ATTRIB,DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); if (fLSBNEW(PtN)) { SEMANTICS; } else {LOAD_CANCEL(EA);}})\ +Q6INSN(L2_p##TAG##fnew_io,"if (!Pt4.new) "OPER"(Rs32+#u6:"SHFT")",ATTRIB,DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); if (fLSBNEWNOT(PtN)) { SEMANTICS; } else {LOAD_CANCEL(EA);}})\ +Q6INSN(L4_p##TAG##t_rr, "if (Pv4) "OPER"(Rs32+Rt32<<#u2)", ATTRIB,DESCR,{fEA_RRs(RsV,RtV,uiV); if(fLSBOLD(PvV)){ SEMANTICS;} else {LOAD_CANCEL(EA);}})\ +Q6INSN(L4_p##TAG##f_rr, "if (!Pv4) "OPER"(Rs32+Rt32<<#u2)", ATTRIB,DESCR,{fEA_RRs(RsV,RtV,uiV); if(fLSBOLDNOT(PvV)){ SEMANTICS; } else {LOAD_CANCEL(EA);}})\ +Q6INSN(L4_p##TAG##tnew_rr,"if (Pv4.new) "OPER"(Rs32+Rt32<<#u2)",ATTRIB,DESCR,{fEA_RRs(RsV,RtV,uiV); if (fLSBNEW(PvN)) { SEMANTICS; } else {LOAD_CANCEL(EA);}})\ +Q6INSN(L4_p##TAG##fnew_rr,"if (!Pv4.new) "OPER"(Rs32+Rt32<<#u2)",ATTRIB,DESCR,{fEA_RRs(RsV,RtV,uiV); if (fLSBNEWNOT(PvN)) { SEMANTICS; } else {LOAD_CANCEL(EA);}})\ +Q6INSN(L2_p##TAG##tnew_pi, "if (Pt4.new) "OPER"(Rx32++#s4:"SHFT")", ATTRIB,DESCR,{fEA_REG(RxV); if(fLSBNEW(PtN)){ fPM_I(RxV,siV); SEMANTICS;} else {LOAD_CANCEL(EA);}})\ +Q6INSN(L2_p##TAG##fnew_pi, "if (!Pt4.new) "OPER"(Rx32++#s4:"SHFT")", ATTRIB,DESCR,{fEA_REG(RxV); if(fLSBNEWNOT(PtN)){ fPM_I(RxV,siV); SEMANTICS;} else {LOAD_CANCEL(EA);}})\ +Q6INSN(L4_p##TAG##t_abs, "if (Pt4) "OPER"(#u6)", ATTRIB,DESCR,{fMUST_IMMEXT(uiV); fEA_IMM(uiV); if(fLSBOLD(PtV)){ SEMANTICS;} else {LOAD_CANCEL(EA);}})\ +Q6INSN(L4_p##TAG##f_abs, "if (!Pt4) "OPER"(#u6)", ATTRIB,DESCR,{fMUST_IMMEXT(uiV); fEA_IMM(uiV); if(fLSBOLDNOT(PtV)){ SEMANTICS; } else {LOAD_CANCEL(EA);}})\ +Q6INSN(L4_p##TAG##tnew_abs,"if (Pt4.new) "OPER"(#u6)",ATTRIB,DESCR,{fMUST_IMMEXT(uiV); fEA_IMM(uiV);if (fLSBNEW(PtN)) { SEMANTICS; } else {LOAD_CANCEL(EA);}})\ +Q6INSN(L4_p##TAG##fnew_abs,"if (!Pt4.new) "OPER"(#u6)",ATTRIB,DESCR,{fMUST_IMMEXT(uiV); fEA_IMM(uiV);if (fLSBNEWNOT(PtN)) { SEMANTICS; } else {LOAD_CANCEL(EA);}}) + + + +/* The set of 32-bit predicated load instructions */ +STD_PLD_AMODES(loadrub,"Rd32=memub","Load Unsigned Byte",ATTRIBS(A_ARCHV2,A_LOAD),"0",0,fLOAD(1,1,u,EA,RdV)) +STD_PLD_AMODES(loadrb, "Rd32=memb", "Load signed Byte",ATTRIBS(A_ARCHV2,A_LOAD),"0",0,fLOAD(1,1,s,EA,RdV)) +STD_PLD_AMODES(loadruh,"Rd32=memuh","Load unsigned Half integer",ATTRIBS(A_ARCHV2,A_LOAD),"1",1,fLOAD(1,2,u,EA,RdV)) +STD_PLD_AMODES(loadrh, "Rd32=memh", "Load signed Half integer",ATTRIBS(A_ARCHV2,A_LOAD),"1",1,fLOAD(1,2,s,EA,RdV)) +STD_PLD_AMODES(loadri, "Rd32=memw", "Load Word",ATTRIBS(A_ARCHV2,A_LOAD),"2",2,fLOAD(1,4,u,EA,RdV)) +STD_PLD_AMODES(loadrd, "Rdd32=memd","Load Double integer",ATTRIBS(A_ARCHV2,A_LOAD),"3",3,fLOAD(1,8,u,EA,RddV)) + +/* The set of addressing modes standard to all predicated store instructions */ +#define STD_PST_AMODES(TAG,DEST,OPER,DESCR,ATTRIB,SHFT,SHFTNUM,SEMANTICS)\ +Q6INSN(S4_##TAG##_rr, OPER"(Rs32+Ru32<<#u2)="DEST, ATTRIB,DESCR,{fEA_RRs(RsV,RuV,uiV); SEMANTICS;})\ +Q6INSN(S2_p##TAG##t_io, "if (Pv4) "OPER"(Rs32+#u6:"SHFT")="DEST, ATTRIB,DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); if (fLSBOLD(PvV)){ SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S2_p##TAG##t_pi, "if (Pv4) "OPER"(Rx32++#s4:"SHFT")="DEST, ATTRIB,DESCR,{fEA_REG(RxV); if (fLSBOLD(PvV)){ fPM_I(RxV,siV); SEMANTICS;} else {STORE_CANCEL(EA);}})\ +Q6INSN(S2_p##TAG##f_io, "if (!Pv4) "OPER"(Rs32+#u6:"SHFT")="DEST, ATTRIB,DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); if (fLSBOLDNOT(PvV)){ SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S2_p##TAG##f_pi, "if (!Pv4) "OPER"(Rx32++#s4:"SHFT")="DEST, ATTRIB,DESCR,{fEA_REG(RxV); if (fLSBOLDNOT(PvV)){ fPM_I(RxV,siV); SEMANTICS;} else {STORE_CANCEL(EA);}})\ +Q6INSN(S4_p##TAG##t_rr, "if (Pv4) "OPER"(Rs32+Ru32<<#u2)="DEST, ATTRIB,DESCR,{fEA_RRs(RsV,RuV,uiV); if (fLSBOLD(PvV)){ SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S4_p##TAG##f_rr, "if (!Pv4) "OPER"(Rs32+Ru32<<#u2)="DEST, ATTRIB,DESCR,{fEA_RRs(RsV,RuV,uiV); if (fLSBOLDNOT(PvV)){ SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S4_p##TAG##tnew_io,"if (Pv4.new) "OPER"(Rs32+#u6:"SHFT")="DEST,ATTRIB,DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); if ( fLSBNEW(PvN)) { SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S4_p##TAG##fnew_io,"if (!Pv4.new) "OPER"(Rs32+#u6:"SHFT")="DEST,ATTRIB,DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); if (fLSBNEWNOT(PvN)) { SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S4_p##TAG##tnew_rr,"if (Pv4.new) "OPER"(Rs32+Ru32<<#u2)="DEST,ATTRIB,DESCR,{fEA_RRs(RsV,RuV,uiV); if ( fLSBNEW(PvN)) { SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S4_p##TAG##fnew_rr,"if (!Pv4.new) "OPER"(Rs32+Ru32<<#u2)="DEST,ATTRIB,DESCR,{fEA_RRs(RsV,RuV,uiV); if (fLSBNEWNOT(PvN)) { SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S2_p##TAG##tnew_pi, "if (Pv4.new) "OPER"(Rx32++#s4:"SHFT")="DEST, ATTRIB,DESCR,{fEA_REG(RxV); if (fLSBNEW(PvN)){ fPM_I(RxV,siV); SEMANTICS;} else {STORE_CANCEL(EA);}})\ +Q6INSN(S2_p##TAG##fnew_pi, "if (!Pv4.new) "OPER"(Rx32++#s4:"SHFT")="DEST, ATTRIB,DESCR,{fEA_REG(RxV); if (fLSBNEWNOT(PvN)){ fPM_I(RxV,siV); SEMANTICS;} else {STORE_CANCEL(EA);}})\ +Q6INSN(S4_p##TAG##t_abs, "if (Pv4) "OPER"(#u6)="DEST, ATTRIB,DESCR,{fMUST_IMMEXT(uiV); fEA_IMM(uiV); if (fLSBOLD(PvV)){ SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S4_p##TAG##f_abs, "if (!Pv4) "OPER"(#u6)="DEST, ATTRIB,DESCR,{fMUST_IMMEXT(uiV);fEA_IMM(uiV); if (fLSBOLDNOT(PvV)){ SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S4_p##TAG##tnew_abs,"if (Pv4.new) "OPER"(#u6)="DEST,ATTRIB,DESCR,{fMUST_IMMEXT(uiV);fEA_IMM(uiV); if ( fLSBNEW(PvN)) { SEMANTICS; } else {STORE_CANCEL(EA);}})\ +Q6INSN(S4_p##TAG##fnew_abs,"if (!Pv4.new) "OPER"(#u6)="DEST,ATTRIB,DESCR,{fMUST_IMMEXT(uiV);fEA_IMM(uiV); if (fLSBNEWNOT(PvN)) { SEMANTICS; } else {STORE_CANCEL(EA);}}) + + + + +/* The set of 32-bit predicated store instructions */ +STD_PST_AMODES(storerb,"Rt32","memb","Store Byte",ATTRIBS(A_ARCHV2,A_STORE),"0",0,fSTORE(1,1,EA,fGETBYTE(0,RtV))) +STD_PST_AMODES(storerh,"Rt32","memh","Store Half integer",ATTRIBS(A_ARCHV2,A_STORE),"1",1,fSTORE(1,2,EA,fGETHALF(0,RtV))) +STD_PST_AMODES(storerf,"Rt.H32","memh","Store Upper Half integer",ATTRIBS(A_ARCHV2,A_STORE),"1",1,fSTORE(1,2,EA,fGETHALF(1,RtV))) +STD_PST_AMODES(storeri,"Rt32","memw","Store Word",ATTRIBS(A_ARCHV2,A_STORE),"2",2,fSTORE(1,4,EA,RtV)) +STD_PST_AMODES(storerd,"Rtt32","memd","Store Double integer",ATTRIBS(A_ARCHV2,A_STORE),"3",3,fSTORE(1,8,EA,RttV)) +STD_PST_AMODES(storerinew,"Nt8.new","memw","Store Word",ATTRIBS(A_ARCHV2,A_STORE),"2",2,fSTORE(1,4,EA,fNEWREG_ST(NtN))) +STD_PST_AMODES(storerbnew,"Nt8.new","memb","Store Byte",ATTRIBS(A_ARCHV2,A_STORE),"0",0,fSTORE(1,1,EA,fGETBYTE(0,fNEWREG_ST(NtN)))) +STD_PST_AMODES(storerhnew,"Nt8.new","memh","Store Half integer",ATTRIBS(A_ARCHV2,A_STORE),"1",1,fSTORE(1,2,EA,fGETHALF(0,fNEWREG_ST(NtN)))) + + + + +/*****************************************************************/ +/* */ +/* Mem-Ops (Load-op-Store) */ +/* */ +/*****************************************************************/ + +/* The set of 32-bit non-predicated mem-ops */ +#define STD_MEMOP_AMODES(TAG,OPER,DESCR,SEMANTICS)\ +Q6INSN(L4_##TAG##w_io, "memw(Rs32+#u6:2)"OPER, ATTRIBS(A_RESTRICT_SLOT0ONLY),DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); fHIDE(size4s_t tmp;) fLOAD(1,4,s,EA,tmp); SEMANTICS; fSTORE(1,4,EA,tmp); })\ +Q6INSN(L4_##TAG##b_io, "memb(Rs32+#u6:0)"OPER, ATTRIBS(A_RESTRICT_SLOT0ONLY),DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); fHIDE(size4s_t tmp;) fLOAD(1,1,s,EA,tmp); SEMANTICS; fSTORE(1,1,EA,tmp); })\ +Q6INSN(L4_##TAG##h_io, "memh(Rs32+#u6:1)"OPER, ATTRIBS(A_RESTRICT_SLOT0ONLY),DESCR,{fIMMEXT(uiV); fEA_RI(RsV,uiV); fHIDE(size4s_t tmp;) fLOAD(1,2,s,EA,tmp); SEMANTICS; fSTORE(1,2,EA,tmp); }) + + + +STD_MEMOP_AMODES(add_memop, "+=Rt32", "Add Register to Memory Word", tmp += RtV) +STD_MEMOP_AMODES(sub_memop, "-=Rt32", "Sub Register from Memory Word", tmp -= RtV) +STD_MEMOP_AMODES(and_memop, "&=Rt32", "Logical AND Register to Memory Word", tmp &= RtV) +STD_MEMOP_AMODES(or_memop, "|=Rt32", "Logical OR Register to Memory Word", tmp |= RtV) + + +STD_MEMOP_AMODES(iadd_memop, "+=#U5", "Add Immediate to Memory Word", tmp += UiV) +STD_MEMOP_AMODES(isub_memop, "-=#U5", "Sub Immediate to Memory Word", tmp -= UiV) +STD_MEMOP_AMODES(iand_memop, "=clrbit(#U5)", "Clear a bit in memory", tmp &= (~(1<. + */ + +DEF_MACRO( + LIKELY, /* NAME */ + __builtin_expect((X),1), /* BEH */ + () /* attribs */ +) + +DEF_MACRO( + UNLIKELY, /* NAME */ + __builtin_expect((X),0), /* BEH */ + () /* attribs */ +) + +DEF_MACRO( + CANCEL, /* macro name */ + {if (thread->last_pkt) thread->last_pkt->slot_cancelled |= (1<slot); return;} , /* behavior */ + (A_CONDEXEC) +) + +DEF_MACRO( + LOAD_CANCEL, /* macro name */ + {mem_general_load_cancelled(thread,EA,insn);CANCEL;} , /* behavior */ + (A_CONDEXEC) +) + +DEF_MACRO( + STORE_CANCEL, /* macro name */ + {mem_general_store_cancelled(thread,EA,insn);CANCEL;} , /* behavior */ + (A_CONDEXEC) +) + +DEF_MACRO( + fMAX, /* macro name */ + (((A) > (B)) ? (A) : (B)), /* behavior */ + /* optional attributes */ +) + +DEF_MACRO( + fMIN, /* macro name */ + (((A) < (B)) ? (A) : (B)), /* behavior */ + /* optional attributes */ +) + +DEF_MACRO( + fABS, /* macro name */ + (((A)<0)?(-(A)):(A)), /* behavior */ + /* optional attributes */ +) + + +/* Bit insert */ +DEF_MACRO( + fINSERT_BITS, + { + REG = ((REG) & ~(((fCONSTLL(1)<<(WIDTH))-1)<<(OFFSET))) | (((INVAL) & ((fCONSTLL(1)<<(WIDTH))-1)) << (OFFSET)); + }, + /* attribs */ +) + +/* Bit extract */ +DEF_MACRO( + fEXTRACTU_BITS, + (fZXTN(WIDTH,32,(INREG >> OFFSET))), + /* attribs */ +) + +DEF_MACRO( + fEXTRACTU_BIDIR, + (fZXTN(WIDTH,32,fBIDIR_LSHIFTR((INREG),(OFFSET),4_8))), + /* attribs */ +) + +DEF_MACRO( + fEXTRACTU_RANGE, + (fZXTN((HIBIT-LOWBIT+1),32,(INREG >> LOWBIT))), + /* attribs */ +) + +DEF_MACRO( + f8BITSOF, + ( (VAL) ? 0xff : 0x00), + /* attribs */ +) + +DEF_MACRO( + fLSBOLD, + ((VAL) & 1), + () +) + +DEF_MACRO( + fLSBNEW, + predlog_read(thread,PNUM), + () +) + +DEF_MACRO( + fLSBNEW0, + predlog_read(thread,0), + () +) + +DEF_MACRO( + fLSBNEW1, + predlog_read(thread,1), + () +) + +DEF_MACRO( + fLSBOLDNOT, + (!fLSBOLD(VAL)), + () +) + +DEF_MACRO( + fLSBNEWNOT, + (!fLSBNEW(PNUM)), + () +) + +DEF_MACRO( + fLSBNEW0NOT, + (!fLSBNEW0), + () +) + +DEF_MACRO( + fLSBNEW1NOT, + (!fLSBNEW1), + () +) + +DEF_MACRO( + fNEWREG, + ({if (newvalue_missing(thread,RNUM) || + IS_CANCELLED(insn->new_value_producer_slot)) CANCEL; reglog_read(thread,RNUM);}), + (A_DOTNEWVALUE,A_RESTRICT_SLOT0ONLY) +) +// Store new with a missing newvalue or cancelled goes out as a zero byte store in V65 +// take advantage of the fact that reglog_read returns zero for not valid rnum +DEF_MACRO( + fNEWREG_ST, + ({if (newvalue_missing(thread,RNUM) || + IS_CANCELLED(insn->new_value_producer_slot)) { STORE_ZERO; RNUM = -1; }; reglog_read(thread,RNUM);}), + (A_DOTNEWVALUE,A_RESTRICT_SLOT0ONLY) +) + +DEF_MACRO( + fSATUVALN, + ({fSET_OVERFLOW(); ((VAL) < 0) ? 0 : ((1LL<<(N))-1);}), + () +) + +DEF_MACRO( + fSATVALN, + ({fSET_OVERFLOW(); ((VAL) < 0) ? (-(1LL<<((N)-1))) : ((1LL<<((N)-1))-1);}), + () +) + +DEF_MACRO( + fZXTN, /* macro name */ + ((VAL) & ((1LL<<(N))-1)), + /* attribs */ +) + +DEF_MACRO( + fSXTN, /* macro name */ + ((fZXTN(N,M,VAL) ^ (1LL<<((N)-1))) - (1LL<<((N)-1))), + /* attribs */ +) + +DEF_MACRO( + fSATN, + ((fSXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATVALN(N,VAL)), + () +) + +DEF_MACRO( + fADDSAT64, + { + size8u_t __a = fCAST8u(A); + size8u_t __b = fCAST8u(B); + size8u_t __sum = __a + __b; + size8u_t __xor = __a ^ __b; + const size8u_t __mask = 0x8000000000000000ULL; + if (__xor & __mask) { + /* Opposite signs, OK */ + DST = __sum; + } else if ((__a ^ __sum) & __mask) { + /* Signs mismatch */ + if (__sum & __mask) { + /* overflowed to negative, make max pos */ + DST=0x7FFFFFFFFFFFFFFFLL; fSET_OVERFLOW(); + } else { + /* overflowed to positive, make max neg */ + DST=0x8000000000000000LL; fSET_OVERFLOW(); + } + } else { + /* signs did not mismatch, OK */ + DST = __sum; + } + }, + () +) + +DEF_MACRO( + fSATUN, + ((fZXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATUVALN(N,VAL)), + () +) + +DEF_MACRO( + fSATH, + (fSATN(16,VAL)), + () +) + + +DEF_MACRO( + fSATUH, + (fSATUN(16,VAL)), + () +) + +DEF_MACRO( + fSATUB, + (fSATUN(8,VAL)), + () +) +DEF_MACRO( + fSATB, + (fSATN(8,VAL)), + () +) + + +/*************************************/ +/* immediate extension */ +/*************************************/ + +DEF_MACRO( + fIMMEXT, + (IMM = IMM), + (A_EXTENDABLE) +) + +DEF_MACRO( + fMUST_IMMEXT, + fIMMEXT(IMM), + (A_EXTENDABLE) +) + +DEF_MACRO( + fPCALIGN, + IMM=(IMM & ~PCALIGN_MASK), + (A_EXTENDABLE) +) + +/*************************************/ +/* Read and Write Implicit Regs */ +/*************************************/ + +DEF_MACRO( + fREAD_LR, /* read link register */ + (READ_RREG(REG_LR)), /* behavior */ + () +) + +DEF_MACRO( + fWRITE_LR, /* write lr */ + WRITE_RREG(REG_LR,A), /* behavior */ + (A_IMPLICIT_WRITES_LR) +) + +DEF_MACRO( + fWRITE_FP, /* write sp */ + WRITE_RREG(REG_FP,A), /* behavior */ + (A_IMPLICIT_WRITES_FP) +) + +DEF_MACRO( + fWRITE_SP, /* write sp */ + WRITE_RREG(REG_SP,A), /* behavior */ + (A_IMPLICIT_WRITES_SP) +) + +DEF_MACRO( + fREAD_SP, /* read stack pointer */ + (READ_RREG(REG_SP)), /* behavior */ + () +) + +DEF_MACRO( + fREAD_LC0, /* read loop count */ + (READ_RREG(REG_LC0)), /* behavior */ + () +) + +DEF_MACRO( + fREAD_LC1, /* read loop count */ + (READ_RREG(REG_LC1)), /* behavior */ + () +) + +DEF_MACRO( + fREAD_SA0, /* read start addr */ + (READ_RREG(REG_SA0)), /* behavior */ + () +) + +DEF_MACRO( + fREAD_SA1, /* read start addr */ + (READ_RREG(REG_SA1)), /* behavior */ + () +) + + +DEF_MACRO( + fREAD_FP, /* read frame pointer */ + (READ_RREG(REG_FP)), /* behavior */ + () +) + +DEF_MACRO( + fREAD_GP, /* read global pointer */ + (insn->extension_valid ? 0 : READ_RREG(REG_GP)), /* behavior */ + () +) + +DEF_MACRO( + fREAD_PC, /* read PC */ + (READ_RREG(REG_PC)), /* behavior */ + () +) + +DEF_MACRO( + fREAD_NPC, /* read next PC */ + (thread->next_PC & (0xfffffffe)), /* behavior */ + () +) + +DEF_MACRO( + fREAD_P0, /* read Predicate 0 */ + (READ_PREG(0)), /* behavior */ + () +) + +DEF_MACRO( + fREAD_P3, /* read Predicate 3 */ + (READ_PREG(3)), /* behavior */ + () +) + +DEF_MACRO( + fCHECK_PCALIGN, + if (((A) & PCALIGN_MASK)) { + register_error_exception(thread,PRECISE_CAUSE_PC_NOT_ALIGNED,thread->Regs[REG_BADVA0],thread->Regs[REG_BADVA1],GET_SSR_FIELD(SSR_BVS),GET_SSR_FIELD(SSR_V0),GET_SSR_FIELD(SSR_V1),0); + }, + () +) + +DEF_MACRO( + fWRITE_NPC, /* write next PC */ + if (!thread->branch_taken) { + if (A != thread->next_PC) { + thread->next_pkt_guess=thread->last_pkt->taken_ptr; + } + fCHECK_PCALIGN(A); + thread->branched = 1; thread->branch_taken = 1; thread->next_PC = A; \ + thread->branch_offset = insn->encoding_offset; thread->branch_opcode = insn->opcode; + }, /* behavior */ + (A_COF) +) + +DEF_MACRO( + fBRANCH, + fWRITE_NPC(LOC); fCOF_CALLBACK(LOC,TYPE), + () +) + +DEF_MACRO( + fJUMPR, /* A jumpr has executed */ + {fBRANCH(TARGET,COF_TYPE_JUMPR);}, + (A_INDIRECT) +) + +DEF_MACRO( + fHINTJR, /* A hintjr instruction has executed */ + { }, +) + +DEF_MACRO( + fCALL, /* Do a call */ + if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALL);}, + (A_COF,A_IMPLICIT_WRITES_LR,A_CALL) +) + +DEF_MACRO( + fCALLR, /* Do a call Register */ + if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALLR);}, + (A_COF,A_IMPLICIT_WRITES_LR,A_CALL) +) + +DEF_MACRO( + fWRITE_LOOP_REGS0, /* write ln,sa,ea,lc */ + {WRITE_RREG(REG_LC0,COUNT); + WRITE_RREG(REG_SA0,START);}, + (A_IMPLICIT_WRITES_LC0,A_IMPLICIT_WRITES_SA0) +) + +DEF_MACRO( + fWRITE_LOOP_REGS1, /* write ln,sa,ea,lc */ + {WRITE_RREG(REG_LC1,COUNT); + WRITE_RREG(REG_SA1,START);}, + (A_IMPLICIT_WRITES_LC1,A_IMPLICIT_WRITES_SA1) +) + +DEF_MACRO( + fWRITE_LC0, + WRITE_RREG(REG_LC0,VAL), + (A_IMPLICIT_WRITES_LC0) +) + +DEF_MACRO( + fWRITE_LC1, + WRITE_RREG(REG_LC1,VAL), + (A_IMPLICIT_WRITES_LC1) +) + +DEF_MACRO( + fCARRY_FROM_ADD, + carry_from_add64(A,B,C), + /* NOTHING */ +) + +DEF_MACRO( + fSET_OVERFLOW, + SET_USR_FIELD(USR_OVF,1), + () +) + +DEF_MACRO( + fSET_LPCFG, + SET_USR_FIELD(USR_LPCFG,(VAL)), + () +) + + +DEF_MACRO( + fGET_LPCFG, + (GET_USR_FIELD(USR_LPCFG)), + () +) + + + +DEF_MACRO( + fWRITE_P0, /* write Predicate 0 */ + WRITE_PREG(0,VAL), /* behavior */ + (A_IMPLICIT_WRITES_P0) +) + +DEF_MACRO( + fWRITE_P1, /* write Predicate 0 */ + WRITE_PREG(1,VAL), /* behavior */ + (A_IMPLICIT_WRITES_P1) +) + +DEF_MACRO( + fWRITE_P2, /* write Predicate 0 */ + WRITE_PREG(2,VAL), /* behavior */ + (A_IMPLICIT_WRITES_P2) +) + +DEF_MACRO( + fWRITE_P3, /* write Predicate 0 */ + WRITE_PREG(3,VAL), /* behavior */ + (A_IMPLICIT_WRITES_P3) +) + +DEF_MACRO( + fPART1, /* write Predicate 0 */ + if (insn->part1) { WORK; return; }, /* behavior */ + /* optional attributes */ +) + + +/*************************************/ +/* Casting, Sign-Zero extension, etc */ +/*************************************/ + +DEF_MACRO( + fCAST4u, /* macro name */ + ((size4u_t)(A)), /* behavior */ + /* optional attributes */ +) + +DEF_MACRO( + fCAST4s, /* macro name */ + ((size4s_t)(A)), /* behavior */ + /* optional attributes */ +) + +DEF_MACRO( + fCAST8u, /* macro name */ + ((size8u_t)(A)), /* behavior */ + /* optional attributes */ +) + +DEF_MACRO( + fCAST8s, /* macro name */ + ((size8s_t)(A)), /* behavior */ + /* optional attributes */ +) + +DEF_MACRO( + fCAST4_4s, /* macro name */ + ((size4s_t)(A)), + /* optional attributes */ +) + +DEF_MACRO( + fCAST4_4u, /* macro name */ + ((size4u_t)(A)), + /* optional attributes */ +) + + +DEF_MACRO( + fCAST4_8s, /* macro name */ + ((size8s_t)((size4s_t)(A))), + /* optional attributes */ +) + +DEF_MACRO( + fCAST4_8u, /* macro name */ + ((size8u_t)((size4u_t)(A))), + /* optional attributes */ +) + +DEF_MACRO( + fCAST8_8s, /* macro name */ + ((size8s_t)(A)), + /* optional attributes */ +) + +DEF_MACRO( + fCAST8_8u, /* macro name */ + ((size8u_t)(A)), + /* optional attributes */ +) + +DEF_MACRO( + fCAST2_8s, /* macro name */ + ((size8s_t)((size2s_t)(A))), + /* optional attributes */ +) +DEF_MACRO( + fCAST2_8u, /* macro name */ + ((size8u_t)((size2u_t)(A))), + /* optional attributes */ +) + +DEF_MACRO( + fZE8_16, /* zero-extend 8 to 16 */ + ((size2s_t)((size1u_t)(A))), + /* optional attributes */ +) +DEF_MACRO( + fSE8_16, /* sign-extend 8 to 16 */ + ((size2s_t)((size1s_t)(A))), + /* optional attributes */ +) + + +DEF_MACRO( + fSE16_32, /* sign-extend 16 to 32 */ + ((size4s_t)((size2s_t)(A))), /* behavior */ + /* optional attributes */ +) + +DEF_MACRO( + fZE16_32, /* zero-extend 16 to 32 */ + ((size4u_t)((size2u_t)(A))), /* behavior */ + /* optional attributes */ +) + +DEF_MACRO( + fSE32_64, + ( (size8s_t)((size4s_t)(A)) ), /* behavior */ + /* optional attributes */ +) + +DEF_MACRO( + fZE32_64, + ( (size8u_t)((size4u_t)(A)) ), /* behavior */ + /* optional attributes */ +) + +DEF_MACRO( + fSE8_32, /* sign-extend 8 to 32 */ + ((size4s_t)((size1s_t)(A))), + /* optional attributes */ +) + +DEF_MACRO( + fZE8_32, /* zero-extend 8 to 32 */ + ((size4s_t)((size1u_t)(A))), + /* optional attributes */ +) + +/*************************************/ +/* DSP arithmetic support */ +/************************************/ +DEF_MACRO( + fMPY8UU, /* multiply half integer */ + (int)(fZE8_16(A)*fZE8_16(B)), /* behavior */ + () +) +DEF_MACRO( + fMPY8US, /* multiply half integer */ + (int)(fZE8_16(A)*fSE8_16(B)), /* behavior */ + () +) +DEF_MACRO( + fMPY8SU, /* multiply half integer */ + (int)(fSE8_16(A)*fZE8_16(B)), /* behavior */ + () +) + +DEF_MACRO( + fMPY8SS, /* multiply half integer */ + (int)((short)(A)*(short)(B)), /* behavior */ + () +) + +DEF_MACRO( + fMPY16SS, /* multiply half integer */ + fSE32_64(fSE16_32(A)*fSE16_32(B)), /* behavior */ + () +) + +DEF_MACRO( + fMPY16UU, /* multiply unsigned half integer */ + fZE32_64(fZE16_32(A)*fZE16_32(B)), /* behavior */ + () +) + +DEF_MACRO( + fMPY16SU, /* multiply half integer */ + fSE32_64(fSE16_32(A)*fZE16_32(B)), /* behavior */ + () +) + +DEF_MACRO( + fMPY16US, /* multiply half integer */ + fMPY16SU(B,A), + () +) + +DEF_MACRO( + fMPY32SS, /* multiply half integer */ + (fSE32_64(A)*fSE32_64(B)), /* behavior */ + () +) + +DEF_MACRO( + fMPY32UU, /* multiply half integer */ + (fZE32_64(A)*fZE32_64(B)), /* behavior */ + () +) + +DEF_MACRO( + fMPY32SU, /* multiply half integer */ + (fSE32_64(A)*fZE32_64(B)), /* behavior */ + () +) + +DEF_MACRO( + fMPY3216SS, /* multiply mixed precision */ + (fSE32_64(A)*fSXTN(16,64,B)), /* behavior */ + () +) + +DEF_MACRO( + fMPY3216SU, /* multiply mixed precision */ + (fSE32_64(A)*fZXTN(16,64,B)), /* behavior */ + () +) + +DEF_MACRO( + fROUND, /* optional rounding */ + (A+0x8000), + /* optional attributes */ +) + +DEF_MACRO( + fCLIP, /* optional rounding */ + { size4s_t maxv = (1< 0) && ((A) == 0)) ? + fSATVALN(32,(ORIG_REG)) : + fSAT(A))), + () +) + +DEF_MACRO( + fPASS, + A, +) + +DEF_MACRO( + fRND, /* saturating to 32-bits*/ + (((A)+1)>>1), +) + + +DEF_MACRO( + fBIDIR_SHIFTL, + (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) >> ((-(SHAMT))-1)) >>1) : (fCAST##REGSTYPE(SRC) << (SHAMT))), + () +) + +DEF_MACRO( + fBIDIR_ASHIFTL, + fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##s), + () +) + +DEF_MACRO( + fBIDIR_LSHIFTL, + fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##u), + () +) + +DEF_MACRO( + fBIDIR_ASHIFTL_SAT, + (((SHAMT) < 0) ? ((fCAST##REGSTYPE##s(SRC) >> ((-(SHAMT))-1)) >>1) : fSAT_ORIG_SHL(fCAST##REGSTYPE##s(SRC) << (SHAMT),(SRC))), + () +) + + +DEF_MACRO( + fBIDIR_SHIFTR, + (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) << ((-(SHAMT))-1)) << 1) : (fCAST##REGSTYPE(SRC) >> (SHAMT))), + () +) + +DEF_MACRO( + fBIDIR_ASHIFTR, + fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##s), + () +) + +DEF_MACRO( + fBIDIR_LSHIFTR, + fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##u), + () +) + +DEF_MACRO( + fBIDIR_ASHIFTR_SAT, + (((SHAMT) < 0) ? fSAT_ORIG_SHL((fCAST##REGSTYPE##s(SRC) << ((-(SHAMT))-1)) << 1,(SRC)) : (fCAST##REGSTYPE##s(SRC) >> (SHAMT))), + () +) + +DEF_MACRO( + fASHIFTR, + (fCAST##REGSTYPE##s(SRC) >> (SHAMT)), + /* */ +) + +DEF_MACRO( + fLSHIFTR, + (((SHAMT) >= 64)?0:(fCAST##REGSTYPE##u(SRC) >> (SHAMT))), + /* */ +) + +DEF_MACRO( + fROTL, + (((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) << (SHAMT)) | \ + ((fCAST##REGSTYPE##u(SRC) >> ((sizeof(SRC)*8)-(SHAMT)))))), + /* */ +) + +DEF_MACRO( + fROTR, + (((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) >> (SHAMT)) | \ + ((fCAST##REGSTYPE##u(SRC) << ((sizeof(SRC)*8)-(SHAMT)))))), + /* */ +) + +DEF_MACRO( + fASHIFTL, + (((SHAMT) >= 64)?0:(fCAST##REGSTYPE##s(SRC) << (SHAMT))), + /* */ +) + +/*************************************/ +/* Floating-Point Support */ +/************************************/ + +DEF_MACRO( + fFLOAT, /* name */ + ({ union { float f; size4u_t i; } _fipun; _fipun.i = (A); _fipun.f; }), /* behavior */ + (A_FPOP) +) + +DEF_MACRO( + fUNFLOAT, /* multiply half integer */ + ({ union { float f; size4u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFU : _fipun.i; }), /* behavior */ + (A_FPOP) +) + +DEF_MACRO( + fSFNANVAL, + 0xffffffff, + () +) + +DEF_MACRO( + fSFINFVAL, + (((A) & 0x80000000) | 0x7f800000), + () +) + +DEF_MACRO( + fSFONEVAL, + (((A) & 0x80000000) | fUNFLOAT(1.0)), + () +) + +DEF_MACRO( + fCHECKSFNAN, + do { + if (isnan(fFLOAT(A))) { + if ((fGETBIT(22,A)) == 0) fRAISEFLAGS(FE_INVALID); + DST = fSFNANVAL(); + } + } while (0), + () +) + +DEF_MACRO( + fCHECKSFNAN3, + do { + fCHECKSFNAN(DST,A); + fCHECKSFNAN(DST,B); + fCHECKSFNAN(DST,C); + } while (0), + () +) + +DEF_MACRO( + fSF_BIAS, + 127, + () +) + +DEF_MACRO( + fSF_MANTBITS, + 23, + () +) + +DEF_MACRO( + fSF_MUL_POW2, + (fUNFLOAT(fFLOAT(A) * fFLOAT((fSF_BIAS() + (B)) << fSF_MANTBITS()))), + () +) + +DEF_MACRO( + fSF_GETEXP, + (((A) >> fSF_MANTBITS()) & 0xff), + () +) + +DEF_MACRO( + fSF_MAXEXP, + (254), + () +) + +DEF_MACRO( + fSF_RECIP_COMMON, + arch_sf_recip_common(&N,&D,&O,&A), + (A_FPOP) +) + +DEF_MACRO( + fSF_INVSQRT_COMMON, + arch_sf_invsqrt_common(&N,&O,&A), + (A_FPOP) +) + +DEF_MACRO( + fFMAFX, + internal_fmafx(A,B,C,fSXTN(8,64,ADJ)), + () +) + +DEF_MACRO( + fFMAF, + internal_fmafx(A,B,C,0), + () +) + +DEF_MACRO( + fSFMPY, + internal_mpyf(A,B), + () +) + +DEF_MACRO( + fMAKESF, + ((((SIGN) & 1) << 31) | (((EXP) & 0xff) << fSF_MANTBITS()) | + ((MANT) & ((1<= 512), + () +) + +DEF_MACRO( + fDF_MANTBITS, + 52, + () +) + +DEF_MACRO( + fDF_GETEXP, + (((A) >> fDF_MANTBITS()) & 0x7ff), + () +) + +DEF_MACRO( + fFMA, + internal_fma(A,B,C), + /* nothing */ +) + +DEF_MACRO( + fDF_MPY_HH, + internal_mpyhh(A,B,ACC), + /* nothing */ +) + +DEF_MACRO( + fFPOP_START, + arch_fpop_start(thread), + /* nothing */ +) + +DEF_MACRO( + fFPOP_END, + arch_fpop_end(thread), + /* nothing */ +) + +DEF_MACRO( + fFPSETROUND_NEAREST, + fesetround(FE_TONEAREST), + /* nothing */ +) + +DEF_MACRO( + fFPSETROUND_CHOP, + fesetround(FE_TOWARDZERO), + /* nothing */ +) + +DEF_MACRO( + fFPCANCELFLAGS, + feclearexcept(FE_ALL_EXCEPT), + /* nothing */ +) + +DEF_MACRO( + fISINFPROD, + ((isinf(A) && isinf(B)) || + (isinf(A) && isfinite(B) && ((B) != 0.0)) || + (isinf(B) && isfinite(A) && ((A) != 0.0))), + /* nothing */ +) + +DEF_MACRO( + fISZEROPROD, + ((((A) == 0.0) && isfinite(B)) || (((B) == 0.0) && isfinite(A))), + /* nothing */ +) + +DEF_MACRO( + fRAISEFLAGS, + arch_raise_fpflag(A), + /* NOTHING */ +) + +DEF_MACRO( + fDF_MAX, + (((A)==(B)) + ? fDOUBLE(fUNDOUBLE(A) & fUNDOUBLE(B)) + : fmax(A,B)), + (A_FPOP) +) + +DEF_MACRO( + fDF_MIN, + (((A)==(B)) + ? fDOUBLE(fUNDOUBLE(A) | fUNDOUBLE(B)) + : fmin(A,B)), + (A_FPOP) +) + +DEF_MACRO( + fSF_MAX, + (((A)==(B)) + ? fFLOAT(fUNFLOAT(A) & fUNFLOAT(B)) + : fmaxf(A,B)), + (A_FPOP) +) + +DEF_MACRO( + fSF_MIN, + (((A)==(B)) + ? fFLOAT(fUNFLOAT(A) | fUNFLOAT(B)) + : fminf(A,B)), + (A_FPOP) +) + +/*************************************/ +/* Load/Store support */ +/*************************************/ + +DEF_MACRO(fLOAD, + { DST = (size##SIZE##SIGN##_t)MEM_LOAD##SIZE(thread,EA,insn); }, + (A_LOAD,A_MEMLIKE) +) + +DEF_MACRO(fMEMOP, + { memop##SIZE##_##FNTYPE(thread,EA,VALUE); }, + (A_LOAD,A_STORE,A_MEMLIKE) +) + +DEF_MACRO(fGET_FRAMEKEY, + READ_RREG(REG_FRAMEKEY), + () +) + +DEF_MACRO(fFRAME_SCRAMBLE, + ((VAL) ^ (fCAST8u(fGET_FRAMEKEY()) << 32)), + /* ATTRIBS */ +) + +DEF_MACRO(fFRAME_UNSCRAMBLE, + fFRAME_SCRAMBLE(VAL), + /* ATTRIBS */ +) + +DEF_MACRO(fFRAMECHECK, + sys_check_framelimit(thread,ADDR,EA), + () +) + +DEF_MACRO(fLOAD_LOCKED, + { DST = (size##SIZE##SIGN##_t)mem_load_locked(thread,EA,SIZE,insn); }, + (A_LOAD,A_MEMLIKE) +) + +DEF_MACRO(fSTORE, + { MEM_STORE##SIZE(thread,EA,SRC,insn); }, + (A_STORE,A_MEMLIKE) +) + + +DEF_MACRO(fSTORE_LOCKED, + { PRED = (mem_store_conditional(thread,EA,SRC,SIZE,insn) ? 0xff : 0); }, + (A_STORE,A_MEMLIKE) +) + +/*************************************/ +/* Functions to help with bytes */ +/*************************************/ + +DEF_MACRO(fGETBYTE, + ((size1s_t)((SRC>>((N)*8))&0xff)), + /* nothing */ +) + +DEF_MACRO(fGETUBYTE, + ((size1u_t)((SRC>>((N)*8))&0xff)), + /* nothing */ +) + +DEF_MACRO(fSETBYTE, + { + DST = (DST & ~(0x0ffLL<<((N)*8))) | (((size8u_t)((VAL) & 0x0ffLL)) << ((N)*8)); + }, + /* nothing */ +) + +DEF_MACRO(fGETHALF, + ((size2s_t)((SRC>>((N)*16))&0xffff)), + /* nothing */ +) + +DEF_MACRO(fGETUHALF, + ((size2u_t)((SRC>>((N)*16))&0xffff)), + /* nothing */ +) + +DEF_MACRO(fSETHALF, + { + DST = (DST & ~(0x0ffffLL<<((N)*16))) | (((size8u_t)((VAL) & 0x0ffff)) << ((N)*16)); + }, + /* nothing */ +) + + + +DEF_MACRO(fGETWORD, + ((size8s_t)((size4s_t)((SRC>>((N)*32))&0x0ffffffffLL))), + /* nothing */ +) + +DEF_MACRO(fGETUWORD, + ((size8u_t)((size4u_t)((SRC>>((N)*32))&0x0ffffffffLL))), + /* nothing */ +) + +DEF_MACRO(fSETWORD, + { + DST = (DST & ~(0x0ffffffffLL<<((N)*32))) | (((VAL) & 0x0ffffffffLL) << ((N)*32)); + }, + /* nothing */ +) + +DEF_MACRO(fSETBIT, + { + DST = (DST & ~(1ULL<<(N))) | (((size8u_t)(VAL))<<(N)); + }, + /* nothing */ +) + +DEF_MACRO(fGETBIT, + (((SRC)>>N)&1), + /* nothing */ +) + + +DEF_MACRO(fSETBITS, + do { + int j; + for (j=LO;j<=HI;j++) { + fSETBIT(j,DST,VAL); + } + } while (0), + /* nothing */ +) + +/*************************************/ +/* Used for parity, etc........ */ +/*************************************/ +DEF_MACRO(fCOUNTONES_4, + count_ones_4(VAL), + /* nothing */ +) + +DEF_MACRO(fCOUNTONES_8, + count_ones_8(VAL), + /* nothing */ +) + +DEF_MACRO(fBREV_8, + reverse_bits_8(VAL), + /* nothing */ +) + +DEF_MACRO(fBREV_4, + reverse_bits_4(VAL), + /* nothing */ +) + +DEF_MACRO(fCL1_8, + count_leading_ones_8(VAL), + /* nothing */ +) + +DEF_MACRO(fCL1_4, + count_leading_ones_4(VAL), + /* nothing */ +) + +DEF_MACRO(fINTERLEAVE, + interleave(ODD,EVEN), + /* nothing */ +) + +DEF_MACRO(fDEINTERLEAVE, + deinterleave(MIXED), + /* nothing */ +) + +DEF_MACRO(fHIDE, + A, + () +) + +DEF_MACRO(fCONSTLL, + A##LL, +) + +/* Do the things in the parens, but don't print the parens. */ +DEF_MACRO(fECHO, + (A), + /* nothing */ +) + + +/********************************************/ +/* OS interface and stop/wait */ +/********************************************/ + +DEF_MACRO(fPAUSE, + {sys_pause(thread, insn->slot, IMM);}, + () +) + +DEF_MACRO(fTRAP, + warn("Trap NPC=%x ",fREAD_NPC()); + warn("Trap exception, PCYCLE=%lld TYPE=%d NPC=%x IMM=0x%x",thread->processor_ptr->pstats[pcycles],TRAPTYPE,fREAD_NPC(),IMM); + register_trap_exception(thread,fREAD_NPC(),TRAPTYPE,IMM);, + () +) + +DEF_MACRO(fALIGN_REG_FIELD_VALUE, + ((VAL)<Regs[REG_##REG], + reg_field_info[FIELD].width, + reg_field_info[FIELD].offset), + /* ATTRIBS */ +) + +DEF_MACRO(fGET_FIELD, + fEXTRACTU_BITS(VAL, + reg_field_info[FIELD].width, + reg_field_info[FIELD].offset), + /* ATTRIBS */ +) + +DEF_MACRO(fSET_FIELD, + fINSERT_BITS(VAL, + reg_field_info[FIELD].width, + reg_field_info[FIELD].offset, + (NEWVAL)), + /* ATTRIBS */ +) + +/********************************************/ +/* Cache Management */ +/********************************************/ + +DEF_MACRO(fBARRIER, + { + sys_barrier(thread, insn->slot); + }, + () +) + +DEF_MACRO(fSYNCH, + { + sys_sync(thread, insn->slot); + }, + () +) + +DEF_MACRO(fISYNC, + { + sys_isync(thread, insn->slot); + }, + () +) + + +DEF_MACRO(fDCFETCH, + sys_dcfetch(thread, (REG), insn->slot), + (A_MEMLIKE) +) + +DEF_MACRO(fICINVA, + { + arch_internal_flush(thread->processor_ptr, 0, 0xffffffff); + sys_icinva(thread, (REG),insn->slot); + }, + (A_ICINVA) +) + +DEF_MACRO(fL2FETCH, + sys_l2fetch(thread, ADDR,HEIGHT,WIDTH,STRIDE,FLAGS, insn->slot), + (A_MEMLIKE,A_L2FETCH) +) + +DEF_MACRO(fDCCLEANA, + sys_dccleana(thread, (REG)), + (A_MEMLIKE) +) + +DEF_MACRO(fDCCLEANINVA, + sys_dccleaninva(thread, (REG), insn->slot), + (A_MEMLIKE,A_DCCLEANINVA) +) + +DEF_MACRO(fDCZEROA, + sys_dczeroa(thread, (REG)), + (A_MEMLIKE) +) + +DEF_MACRO(fCHECKFORPRIV, + {sys_check_privs(thread); if (EXCEPTION_DETECTED) return; }, + () +) + +DEF_MACRO(fCHECKFORGUEST, + {sys_check_guest(thread); if (EXCEPTION_DETECTED) return; }, + () +) + +DEF_MACRO(fBRANCH_SPECULATE_STALL, + { + sys_speculate_branch_stall(thread, insn->slot, JUMP_COND(JUMP_PRED_SET), + SPEC_DIR, + DOTNEWVAL, + HINTBITNUM, + STRBITNUM, + 0, + thread->last_pkt->pkt_has_dual_jump, + insn->is_2nd_jump, + (thread->fetch_access.vaddr + insn->encoding_offset*4)); + }, + () +) diff --git a/target/hexagon/imported/mpy.idef b/target/hexagon/imported/mpy.idef new file mode 100644 index 0000000000..8744f6596c --- /dev/null +++ b/target/hexagon/imported/mpy.idef @@ -0,0 +1,1208 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Multiply Instructions + */ + + +#define STD_SP_MODES(TAG,OPER,ATR,DST,ACCSEM,SEM,OSEM,SATSEM,RNDSEM)\ +Q6INSN(M2_##TAG##_hh_s0, OPER"(Rs.H32,Rt.H32)"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM SEM( fGETHALF(1,RsV),fGETHALF(1,RtV))));})\ +Q6INSN(M2_##TAG##_hh_s1, OPER"(Rs.H32,Rt.H32):<<1"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM fSCALE(1,SEM(fGETHALF(1,RsV),fGETHALF(1,RtV)))));})\ +Q6INSN(M2_##TAG##_hl_s0, OPER"(Rs.H32,Rt.L32)"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM SEM( fGETHALF(1,RsV),fGETHALF(0,RtV))));})\ +Q6INSN(M2_##TAG##_hl_s1, OPER"(Rs.H32,Rt.L32):<<1"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM fSCALE(1,SEM(fGETHALF(1,RsV),fGETHALF(0,RtV)))));})\ +Q6INSN(M2_##TAG##_lh_s0, OPER"(Rs.L32,Rt.H32)"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM SEM( fGETHALF(0,RsV),fGETHALF(1,RtV))));})\ +Q6INSN(M2_##TAG##_lh_s1, OPER"(Rs.L32,Rt.H32):<<1"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM fSCALE(1,SEM(fGETHALF(0,RsV),fGETHALF(1,RtV)))));})\ +Q6INSN(M2_##TAG##_ll_s0, OPER"(Rs.L32,Rt.L32)"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM SEM( fGETHALF(0,RsV),fGETHALF(0,RtV))));})\ +Q6INSN(M2_##TAG##_ll_s1, OPER"(Rs.L32,Rt.L32):<<1"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM fSCALE(1,SEM(fGETHALF(0,RsV),fGETHALF(0,RtV)))));}) + +/*****************************************************/ +/* multiply 16x16->32 signed instructions */ +/*****************************************************/ +STD_SP_MODES(mpy_acc, "Rx32+=mpy", ,RxV,RxV+ ,fMPY16SS, ,fPASS,fPASS) +STD_SP_MODES(mpy_nac, "Rx32-=mpy", ,RxV,RxV- ,fMPY16SS, ,fPASS,fPASS) +STD_SP_MODES(mpy_acc_sat,"Rx32+=mpy", ,RxV,RxV+ ,fMPY16SS,":sat" ,fSAT, fPASS) +STD_SP_MODES(mpy_nac_sat,"Rx32-=mpy", ,RxV,RxV- ,fMPY16SS,":sat" ,fSAT, fPASS) +STD_SP_MODES(mpy, "Rd32=mpy", ,RdV, ,fMPY16SS, ,fPASS,fPASS) +STD_SP_MODES(mpy_sat, "Rd32=mpy", ,RdV, ,fMPY16SS,":sat" ,fSAT, fPASS) +STD_SP_MODES(mpy_rnd, "Rd32=mpy", ,RdV, ,fMPY16SS,":rnd" ,fPASS,fROUND) +STD_SP_MODES(mpy_sat_rnd,"Rd32=mpy", ,RdV, ,fMPY16SS,":rnd:sat",fSAT, fROUND) +STD_SP_MODES(mpyd_acc, "Rxx32+=mpy",,RxxV,RxxV+ ,fMPY16SS, ,fPASS,fPASS) +STD_SP_MODES(mpyd_nac, "Rxx32-=mpy",,RxxV,RxxV- ,fMPY16SS, ,fPASS,fPASS) +STD_SP_MODES(mpyd, "Rdd32=mpy", ,RddV, ,fMPY16SS, ,fPASS,fPASS) +STD_SP_MODES(mpyd_rnd, "Rdd32=mpy", ,RddV, ,fMPY16SS,":rnd" ,fPASS,fROUND) + + +/*****************************************************/ +/* multiply 16x16->32 unsigned instructions */ +/*****************************************************/ +#define STD_USP_MODES(TAG,OPER,ATR,DST,ACCSEM,SEM,OSEM,SATSEM,RNDSEM)\ +Q6INSN(M2_##TAG##_hh_s0, OPER"(Rs.H32,Rt.H32)"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM SEM( fGETUHALF(1,RsV),fGETUHALF(1,RtV))));})\ +Q6INSN(M2_##TAG##_hh_s1, OPER"(Rs.H32,Rt.H32):<<1"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM fSCALE(1,SEM(fGETUHALF(1,RsV),fGETUHALF(1,RtV)))));})\ +Q6INSN(M2_##TAG##_hl_s0, OPER"(Rs.H32,Rt.L32)"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM SEM( fGETUHALF(1,RsV),fGETUHALF(0,RtV))));})\ +Q6INSN(M2_##TAG##_hl_s1, OPER"(Rs.H32,Rt.L32):<<1"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM fSCALE(1,SEM(fGETUHALF(1,RsV),fGETUHALF(0,RtV)))));})\ +Q6INSN(M2_##TAG##_lh_s0, OPER"(Rs.L32,Rt.H32)"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM SEM( fGETUHALF(0,RsV),fGETUHALF(1,RtV))));})\ +Q6INSN(M2_##TAG##_lh_s1, OPER"(Rs.L32,Rt.H32):<<1"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM fSCALE(1,SEM(fGETUHALF(0,RsV),fGETUHALF(1,RtV)))));})\ +Q6INSN(M2_##TAG##_ll_s0, OPER"(Rs.L32,Rt.L32)"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM SEM( fGETUHALF(0,RsV),fGETUHALF(0,RtV))));})\ +Q6INSN(M2_##TAG##_ll_s1, OPER"(Rs.L32,Rt.L32):<<1"OSEM, ATR,"",{DST=SATSEM(RNDSEM(ACCSEM fSCALE(1,SEM(fGETUHALF(0,RsV),fGETUHALF(0,RtV)))));}) + +STD_USP_MODES(mpyu_acc, "Rx32+=mpyu", ,RxV,RxV+ ,fMPY16UU, ,fPASS,fPASS) +STD_USP_MODES(mpyu_nac, "Rx32-=mpyu", ,RxV,RxV- ,fMPY16UU, ,fPASS,fPASS) +STD_USP_MODES(mpyu, "Rd32=mpyu", ATTRIBS() ,RdV, ,fMPY16UU, ,fPASS,fPASS) +STD_USP_MODES(mpyud_acc, "Rxx32+=mpyu",,RxxV,RxxV+,fMPY16UU, ,fPASS,fPASS) +STD_USP_MODES(mpyud_nac, "Rxx32-=mpyu",,RxxV,RxxV-,fMPY16UU, ,fPASS,fPASS) +STD_USP_MODES(mpyud, "Rdd32=mpyu", ATTRIBS() ,RddV, ,fMPY16UU, ,fPASS,fPASS) + +/**********************************************/ +/* mpy 16x#s8->32 */ +/**********************************************/ + +Q6INSN(M2_mpysip,"Rd32=+mpyi(Rs32,#u8)",ATTRIBS(A_ARCHV2), +"32-bit Multiply by unsigned immediate", +{ fIMMEXT(uiV); RdV=RsV*uiV; }) + +Q6INSN(M2_mpysin,"Rd32=-mpyi(Rs32,#u8)",ATTRIBS(A_ARCHV2), +"32-bit Multiply by unsigned immediate, negate result", +{ RdV=RsV*-uiV; }) + +Q6INSN(M2_macsip,"Rx32+=mpyi(Rs32,#u8)",ATTRIBS(A_ARCHV2), +"32-bit Multiply-Add by unsigned immediate", +{ fIMMEXT(uiV); RxV=RxV + (RsV*uiV);}) + +Q6INSN(M2_macsin,"Rx32-=mpyi(Rs32,#u8)",ATTRIBS(A_ARCHV2), +"32-bit Multiply-Subtract by unsigned immediate", +{ fIMMEXT(uiV); RxV=RxV - (RsV*uiV);}) + + +/**********************************************/ +/* multiply/mac 32x32->64 instructions */ +/**********************************************/ +Q6INSN(M2_dpmpyss_s0, "Rdd32=mpy(Rs32,Rt32)", ATTRIBS(),"Multiply 32x32",{RddV=fMPY32SS(RsV,RtV);}) +Q6INSN(M2_dpmpyss_acc_s0,"Rxx32+=mpy(Rs32,Rt32)",ATTRIBS(),"Multiply 32x32",{RxxV= RxxV + fMPY32SS(RsV,RtV);}) +Q6INSN(M2_dpmpyss_nac_s0,"Rxx32-=mpy(Rs32,Rt32)",ATTRIBS(),"Multiply 32x32",{RxxV= RxxV - fMPY32SS(RsV,RtV);}) + +Q6INSN(M2_dpmpyuu_s0, "Rdd32=mpyu(Rs32,Rt32)", ATTRIBS(),"Multiply 32x32",{RddV=fMPY32UU(fCAST4u(RsV),fCAST4u(RtV));}) +Q6INSN(M2_dpmpyuu_acc_s0,"Rxx32+=mpyu(Rs32,Rt32)",ATTRIBS(),"Multiply 32x32",{RxxV= RxxV + fMPY32UU(fCAST4u(RsV),fCAST4u(RtV));}) +Q6INSN(M2_dpmpyuu_nac_s0,"Rxx32-=mpyu(Rs32,Rt32)",ATTRIBS(),"Multiply 32x32",{RxxV= RxxV - fMPY32UU(fCAST4u(RsV),fCAST4u(RtV));}) + + +/******************************************************/ +/* multiply/mac 32x32->32 (upper) instructions */ +/******************************************************/ +Q6INSN(M2_mpy_up, "Rd32=mpy(Rs32,Rt32)", ATTRIBS(),"Multiply 32x32",{RdV=fMPY32SS(RsV,RtV)>>32;}) +Q6INSN(M2_mpy_up_s1, "Rd32=mpy(Rs32,Rt32):<<1", ATTRIBS(),"Multiply 32x32",{RdV=fMPY32SS(RsV,RtV)>>31;}) +Q6INSN(M2_mpy_up_s1_sat, "Rd32=mpy(Rs32,Rt32):<<1:sat", ATTRIBS(),"Multiply 32x32",{RdV=fSAT(fMPY32SS(RsV,RtV)>>31);}) +Q6INSN(M2_mpyu_up, "Rd32=mpyu(Rs32,Rt32)", ATTRIBS(),"Multiply 32x32",{RdV=fMPY32UU(fCAST4u(RsV),fCAST4u(RtV))>>32;}) +Q6INSN(M2_mpysu_up, "Rd32=mpysu(Rs32,Rt32)", ATTRIBS(),"Multiply 32x32",{RdV=fMPY32SU(RsV,fCAST4u(RtV))>>32;}) +Q6INSN(M2_dpmpyss_rnd_s0,"Rd32=mpy(Rs32,Rt32):rnd", ATTRIBS(),"Multiply 32x32",{RdV=(fMPY32SS(RsV,RtV)+fCONSTLL(0x80000000))>>32;}) + +Q6INSN(M4_mac_up_s1_sat, "Rx32+=mpy(Rs32,Rt32):<<1:sat", ATTRIBS(),"Multiply 32x32",{RxV=fSAT( (fSE32_64(RxV)) + (fMPY32SS(RsV,RtV)>>31));}) +Q6INSN(M4_nac_up_s1_sat, "Rx32-=mpy(Rs32,Rt32):<<1:sat", ATTRIBS(),"Multiply 32x32",{RxV=fSAT( (fSE32_64(RxV)) - (fMPY32SS(RsV,RtV)>>31));}) + + +/**********************************************/ +/* 32x32->32 multiply (lower) */ +/**********************************************/ + +Q6INSN(M2_mpyi,"Rd32=mpyi(Rs32,Rt32)",ATTRIBS(), +"Multiply Integer", +{ RdV=RsV*RtV;}) + +Q6INSN(M2_maci,"Rx32+=mpyi(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Multiply-Accumulate Integer", +{ RxV=RxV + RsV*RtV;}) + +Q6INSN(M2_mnaci,"Rx32-=mpyi(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Multiply-Neg-Accumulate Integer", +{ RxV=RxV - RsV*RtV;}) + +/****** WHY ARE THESE IN MPY.IDEF? **********/ + +Q6INSN(M2_acci,"Rx32+=add(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Add with accumulate", +{ RxV=RxV + RsV + RtV;}) + +Q6INSN(M2_accii,"Rx32+=add(Rs32,#s8)",ATTRIBS(A_ARCHV2), +"Add with accumulate", +{ fIMMEXT(siV); RxV=RxV + RsV + siV;}) + +Q6INSN(M2_nacci,"Rx32-=add(Rs32,Rt32)",ATTRIBS(A_ARCHV2), +"Add with neg accumulate", +{ RxV=RxV - (RsV + RtV);}) + +Q6INSN(M2_naccii,"Rx32-=add(Rs32,#s8)",ATTRIBS(A_ARCHV2), +"Add with neg accumulate", +{ fIMMEXT(siV); RxV=RxV - (RsV + siV);}) + +Q6INSN(M2_subacc,"Rx32+=sub(Rt32,Rs32)",ATTRIBS(A_ARCHV2), +"Sub with accumulate", +{ RxV=RxV + RtV - RsV;}) + + + + +Q6INSN(M4_mpyrr_addr,"Ry32=add(Ru32,mpyi(Ry32,Rs32))",ATTRIBS(), +"Mpy by immed and add immed", +{ RyV = RuV + RsV*RyV;}) + +Q6INSN(M4_mpyri_addr_u2,"Rd32=add(Ru32,mpyi(#u6:2,Rs32))",ATTRIBS(), +"Mpy by immed and add immed", +{ RdV = RuV + RsV*uiV;}) + +Q6INSN(M4_mpyri_addr,"Rd32=add(Ru32,mpyi(Rs32,#u6))",ATTRIBS(), +"Mpy by immed and add immed", +{ fIMMEXT(uiV); RdV = RuV + RsV*uiV;}) + + + +Q6INSN(M4_mpyri_addi,"Rd32=add(#u6,mpyi(Rs32,#U6))",ATTRIBS(), +"Mpy by immed and add immed", +{ fIMMEXT(uiV); RdV = uiV + RsV*UiV;}) + + + +Q6INSN(M4_mpyrr_addi,"Rd32=add(#u6,mpyi(Rs32,Rt32))",ATTRIBS(), +"Mpy by immed and add immed", +{ fIMMEXT(uiV); RdV = uiV + RsV*RtV;}) + + + + + + + + + + + + + + + + + +/**********************************************/ +/* vector mac 2x[16x16 -> 32] */ +/**********************************************/ + +#undef vmac_sema +#define vmac_sema(N)\ +{ fSETWORD(0,RddV,fSAT(fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(0,RtV)))));\ + fSETWORD(1,RddV,fSAT(fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(1,RtV)))));\ +} +Q6INSN(M2_vmpy2s_s0,"Rdd32=vmpyh(Rs32,Rt32):sat",ATTRIBS(),"Vector Multiply",vmac_sema(0)) +Q6INSN(M2_vmpy2s_s1,"Rdd32=vmpyh(Rs32,Rt32):<<1:sat",ATTRIBS(),"Vector Multiply",vmac_sema(1)) + + +#undef vmac_sema +#define vmac_sema(N)\ +{ fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(0,RtV)))));\ + fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(1,RtV)))));\ +} +Q6INSN(M2_vmac2s_s0,"Rxx32+=vmpyh(Rs32,Rt32):sat",ATTRIBS(),"Vector Multiply",vmac_sema(0)) +Q6INSN(M2_vmac2s_s1,"Rxx32+=vmpyh(Rs32,Rt32):<<1:sat",ATTRIBS(),"Vector Multiply",vmac_sema(1)) + +#undef vmac_sema +#define vmac_sema(N)\ +{ fSETWORD(0,RddV,fSAT(fSCALE(N,fMPY16SU(fGETHALF(0,RsV),fGETUHALF(0,RtV)))));\ + fSETWORD(1,RddV,fSAT(fSCALE(N,fMPY16SU(fGETHALF(1,RsV),fGETUHALF(1,RtV)))));\ +} +Q6INSN(M2_vmpy2su_s0,"Rdd32=vmpyhsu(Rs32,Rt32):sat",ATTRIBS(),"Vector Multiply",vmac_sema(0)) +Q6INSN(M2_vmpy2su_s1,"Rdd32=vmpyhsu(Rs32,Rt32):<<1:sat",ATTRIBS(),"Vector Multiply",vmac_sema(1)) + + +#undef vmac_sema +#define vmac_sema(N)\ +{ fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + fSCALE(N,fMPY16SU(fGETHALF(0,RsV),fGETUHALF(0,RtV)))));\ + fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + fSCALE(N,fMPY16SU(fGETHALF(1,RsV),fGETUHALF(1,RtV)))));\ +} +Q6INSN(M2_vmac2su_s0,"Rxx32+=vmpyhsu(Rs32,Rt32):sat",ATTRIBS(),"Vector Multiply",vmac_sema(0)) +Q6INSN(M2_vmac2su_s1,"Rxx32+=vmpyhsu(Rs32,Rt32):<<1:sat",ATTRIBS(),"Vector Multiply",vmac_sema(1)) + + + +#undef vmac_sema +#define vmac_sema(N)\ +{ fSETHALF(1,RdV,fGETHALF(1,(fSAT(fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(1,RtV))) + 0x8000))));\ + fSETHALF(0,RdV,fGETHALF(1,(fSAT(fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(0,RtV))) + 0x8000))));\ +} +Q6INSN(M2_vmpy2s_s0pack,"Rd32=vmpyh(Rs32,Rt32):rnd:sat",ATTRIBS(A_ARCHV2),"Vector Multiply",vmac_sema(0)) +Q6INSN(M2_vmpy2s_s1pack,"Rd32=vmpyh(Rs32,Rt32):<<1:rnd:sat",ATTRIBS(A_ARCHV2),"Vector Multiply",vmac_sema(1)) + + +#undef vmac_sema +#define vmac_sema(N)\ +{ fSETWORD(0,RxxV,fGETWORD(0,RxxV) + fMPY16SS(fGETHALF(0,RsV),fGETHALF(0,RtV)));\ + fSETWORD(1,RxxV,fGETWORD(1,RxxV) + fMPY16SS(fGETHALF(1,RsV),fGETHALF(1,RtV)));\ +} +Q6INSN(M2_vmac2,"Rxx32+=vmpyh(Rs32,Rt32)",ATTRIBS(A_ARCHV2),"Vector Multiply",vmac_sema(0)) + +#undef vmac_sema +#define vmac_sema(N)\ +{ fSETWORD(0,RddV,fSAT(fSCALE(N,fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV)))));\ + fSETWORD(1,RddV,fSAT(fSCALE(N,fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV)))));\ +} +Q6INSN(M2_vmpy2es_s0,"Rdd32=vmpyeh(Rss32,Rtt32):sat",ATTRIBS(),"Vector Multiply",vmac_sema(0)) +Q6INSN(M2_vmpy2es_s1,"Rdd32=vmpyeh(Rss32,Rtt32):<<1:sat",ATTRIBS(),"Vector Multiply",vmac_sema(1)) + +#undef vmac_sema +#define vmac_sema(N)\ +{ fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + fSCALE(N,fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV)))));\ + fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + fSCALE(N,fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV)))));\ +} +Q6INSN(M2_vmac2es_s0,"Rxx32+=vmpyeh(Rss32,Rtt32):sat",ATTRIBS(),"Vector Multiply",vmac_sema(0)) +Q6INSN(M2_vmac2es_s1,"Rxx32+=vmpyeh(Rss32,Rtt32):<<1:sat",ATTRIBS(),"Vector Multiply",vmac_sema(1)) + +#undef vmac_sema +#define vmac_sema(N)\ +{ fSETWORD(0,RxxV,fGETWORD(0,RxxV) + fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV)));\ + fSETWORD(1,RxxV,fGETWORD(1,RxxV) + fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV)));\ +} +Q6INSN(M2_vmac2es,"Rxx32+=vmpyeh(Rss32,Rtt32)",ATTRIBS(A_ARCHV2),"Vector Multiply",vmac_sema(0)) + + + + +/********************************************************/ +/* vrmpyh, aka Big Mac, aka Mac Daddy, aka Mac-ac-ac-ac */ +/* vector mac 4x[16x16] + 64 ->64 */ +/********************************************************/ + + +#undef vmac_sema +#define vmac_sema(N)\ +{ RxxV = RxxV + fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV))\ + + fMPY16SS(fGETHALF(1,RssV),fGETHALF(1,RttV))\ + + fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV))\ + + fMPY16SS(fGETHALF(3,RssV),fGETHALF(3,RttV));\ +} +Q6INSN(M2_vrmac_s0,"Rxx32+=vrmpyh(Rss32,Rtt32)",ATTRIBS(),"Vector Multiply",vmac_sema(0)) + +#undef vmac_sema +#define vmac_sema(N)\ +{ RddV = fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV))\ + + fMPY16SS(fGETHALF(1,RssV),fGETHALF(1,RttV))\ + + fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV))\ + + fMPY16SS(fGETHALF(3,RssV),fGETHALF(3,RttV));\ +} +Q6INSN(M2_vrmpy_s0,"Rdd32=vrmpyh(Rss32,Rtt32)",ATTRIBS(),"Vector Multiply",vmac_sema(0)) + + + +/******************************************************/ +/* vector dual macs. just like complex */ +/******************************************************/ + + +/* With round&pack */ +#undef dmpy_sema +#define dmpy_sema(N)\ +{ fSETHALF(0,RdV,fGETHALF(1,(fSAT(fSCALE(N,fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV))) + \ + fSCALE(N,fMPY16SS(fGETHALF(1,RssV),fGETHALF(1,RttV))) + 0x8000))));\ + fSETHALF(1,RdV,fGETHALF(1,(fSAT(fSCALE(N,fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV))) + \ + fSCALE(N,fMPY16SS(fGETHALF(3,RssV),fGETHALF(3,RttV))) + 0x8000))));\ +} +Q6INSN(M2_vdmpyrs_s0,"Rd32=vdmpy(Rss32,Rtt32):rnd:sat",ATTRIBS(), "vector dual mac w/ round&pack",dmpy_sema(0)) +Q6INSN(M2_vdmpyrs_s1,"Rd32=vdmpy(Rss32,Rtt32):<<1:rnd:sat",ATTRIBS(),"vector dual mac w/ round&pack",dmpy_sema(1)) + + + + + +/******************************************************/ +/* vector byte multiplies */ +/******************************************************/ + + +Q6INSN(M5_vrmpybuu,"Rdd32=vrmpybu(Rss32,Rtt32)",ATTRIBS(), + "vector dual mpy bytes", +{ + fSETWORD(0,RddV,(fMPY16SS(fGETUBYTE(0,RssV),fGETUBYTE(0,RttV)) + + fMPY16SS(fGETUBYTE(1,RssV),fGETUBYTE(1,RttV)) + + fMPY16SS(fGETUBYTE(2,RssV),fGETUBYTE(2,RttV)) + + fMPY16SS(fGETUBYTE(3,RssV),fGETUBYTE(3,RttV)))); + fSETWORD(1,RddV,(fMPY16SS(fGETUBYTE(4,RssV),fGETUBYTE(4,RttV)) + + fMPY16SS(fGETUBYTE(5,RssV),fGETUBYTE(5,RttV)) + + fMPY16SS(fGETUBYTE(6,RssV),fGETUBYTE(6,RttV)) + + fMPY16SS(fGETUBYTE(7,RssV),fGETUBYTE(7,RttV)))); + }) + +Q6INSN(M5_vrmacbuu,"Rxx32+=vrmpybu(Rss32,Rtt32)",ATTRIBS(), + "vector dual mac bytes", +{ + fSETWORD(0,RxxV,(fGETWORD(0,RxxV) + + fMPY16SS(fGETUBYTE(0,RssV),fGETUBYTE(0,RttV)) + + fMPY16SS(fGETUBYTE(1,RssV),fGETUBYTE(1,RttV)) + + fMPY16SS(fGETUBYTE(2,RssV),fGETUBYTE(2,RttV)) + + fMPY16SS(fGETUBYTE(3,RssV),fGETUBYTE(3,RttV)))); + fSETWORD(1,RxxV,(fGETWORD(1,RxxV) + + fMPY16SS(fGETUBYTE(4,RssV),fGETUBYTE(4,RttV)) + + fMPY16SS(fGETUBYTE(5,RssV),fGETUBYTE(5,RttV)) + + fMPY16SS(fGETUBYTE(6,RssV),fGETUBYTE(6,RttV)) + + fMPY16SS(fGETUBYTE(7,RssV),fGETUBYTE(7,RttV)))); + }) + + +Q6INSN(M5_vrmpybsu,"Rdd32=vrmpybsu(Rss32,Rtt32)",ATTRIBS(), + "vector dual mpy bytes", +{ + fSETWORD(0,RddV,(fMPY16SS(fGETBYTE(0,RssV),fGETUBYTE(0,RttV)) + + fMPY16SS(fGETBYTE(1,RssV),fGETUBYTE(1,RttV)) + + fMPY16SS(fGETBYTE(2,RssV),fGETUBYTE(2,RttV)) + + fMPY16SS(fGETBYTE(3,RssV),fGETUBYTE(3,RttV)))); + fSETWORD(1,RddV,(fMPY16SS(fGETBYTE(4,RssV),fGETUBYTE(4,RttV)) + + fMPY16SS(fGETBYTE(5,RssV),fGETUBYTE(5,RttV)) + + fMPY16SS(fGETBYTE(6,RssV),fGETUBYTE(6,RttV)) + + fMPY16SS(fGETBYTE(7,RssV),fGETUBYTE(7,RttV)))); + }) + +Q6INSN(M5_vrmacbsu,"Rxx32+=vrmpybsu(Rss32,Rtt32)",ATTRIBS(), + "vector dual mac bytes", +{ + fSETWORD(0,RxxV,(fGETWORD(0,RxxV) + + fMPY16SS(fGETBYTE(0,RssV),fGETUBYTE(0,RttV)) + + fMPY16SS(fGETBYTE(1,RssV),fGETUBYTE(1,RttV)) + + fMPY16SS(fGETBYTE(2,RssV),fGETUBYTE(2,RttV)) + + fMPY16SS(fGETBYTE(3,RssV),fGETUBYTE(3,RttV)))); + fSETWORD(1,RxxV,(fGETWORD(1,RxxV) + + fMPY16SS(fGETBYTE(4,RssV),fGETUBYTE(4,RttV)) + + fMPY16SS(fGETBYTE(5,RssV),fGETUBYTE(5,RttV)) + + fMPY16SS(fGETBYTE(6,RssV),fGETUBYTE(6,RttV)) + + fMPY16SS(fGETBYTE(7,RssV),fGETUBYTE(7,RttV)))); + }) + + +Q6INSN(M5_vmpybuu,"Rdd32=vmpybu(Rs32,Rt32)",ATTRIBS(), + "vector mpy bytes", +{ + fSETHALF(0,RddV,(fMPY16SS(fGETUBYTE(0,RsV),fGETUBYTE(0,RtV)))); + fSETHALF(1,RddV,(fMPY16SS(fGETUBYTE(1,RsV),fGETUBYTE(1,RtV)))); + fSETHALF(2,RddV,(fMPY16SS(fGETUBYTE(2,RsV),fGETUBYTE(2,RtV)))); + fSETHALF(3,RddV,(fMPY16SS(fGETUBYTE(3,RsV),fGETUBYTE(3,RtV)))); + }) + +Q6INSN(M5_vmpybsu,"Rdd32=vmpybsu(Rs32,Rt32)",ATTRIBS(), + "vector mpy bytes", +{ + fSETHALF(0,RddV,(fMPY16SS(fGETBYTE(0,RsV),fGETUBYTE(0,RtV)))); + fSETHALF(1,RddV,(fMPY16SS(fGETBYTE(1,RsV),fGETUBYTE(1,RtV)))); + fSETHALF(2,RddV,(fMPY16SS(fGETBYTE(2,RsV),fGETUBYTE(2,RtV)))); + fSETHALF(3,RddV,(fMPY16SS(fGETBYTE(3,RsV),fGETUBYTE(3,RtV)))); + }) + + +Q6INSN(M5_vmacbuu,"Rxx32+=vmpybu(Rs32,Rt32)",ATTRIBS(), + "vector mac bytes", +{ + fSETHALF(0,RxxV,(fGETHALF(0,RxxV)+fMPY16SS(fGETUBYTE(0,RsV),fGETUBYTE(0,RtV)))); + fSETHALF(1,RxxV,(fGETHALF(1,RxxV)+fMPY16SS(fGETUBYTE(1,RsV),fGETUBYTE(1,RtV)))); + fSETHALF(2,RxxV,(fGETHALF(2,RxxV)+fMPY16SS(fGETUBYTE(2,RsV),fGETUBYTE(2,RtV)))); + fSETHALF(3,RxxV,(fGETHALF(3,RxxV)+fMPY16SS(fGETUBYTE(3,RsV),fGETUBYTE(3,RtV)))); + }) + +Q6INSN(M5_vmacbsu,"Rxx32+=vmpybsu(Rs32,Rt32)",ATTRIBS(), + "vector mac bytes", +{ + fSETHALF(0,RxxV,(fGETHALF(0,RxxV)+fMPY16SS(fGETBYTE(0,RsV),fGETUBYTE(0,RtV)))); + fSETHALF(1,RxxV,(fGETHALF(1,RxxV)+fMPY16SS(fGETBYTE(1,RsV),fGETUBYTE(1,RtV)))); + fSETHALF(2,RxxV,(fGETHALF(2,RxxV)+fMPY16SS(fGETBYTE(2,RsV),fGETUBYTE(2,RtV)))); + fSETHALF(3,RxxV,(fGETHALF(3,RxxV)+fMPY16SS(fGETBYTE(3,RsV),fGETUBYTE(3,RtV)))); + }) + + + +Q6INSN(M5_vdmpybsu,"Rdd32=vdmpybsu(Rss32,Rtt32):sat",ATTRIBS(), + "vector quad mpy bytes", +{ + fSETHALF(0,RddV,fSATN(16,(fMPY16SS(fGETBYTE(0,RssV),fGETUBYTE(0,RttV)) + + fMPY16SS(fGETBYTE(1,RssV),fGETUBYTE(1,RttV))))); + fSETHALF(1,RddV,fSATN(16,(fMPY16SS(fGETBYTE(2,RssV),fGETUBYTE(2,RttV)) + + fMPY16SS(fGETBYTE(3,RssV),fGETUBYTE(3,RttV))))); + fSETHALF(2,RddV,fSATN(16,(fMPY16SS(fGETBYTE(4,RssV),fGETUBYTE(4,RttV)) + + fMPY16SS(fGETBYTE(5,RssV),fGETUBYTE(5,RttV))))); + fSETHALF(3,RddV,fSATN(16,(fMPY16SS(fGETBYTE(6,RssV),fGETUBYTE(6,RttV)) + + fMPY16SS(fGETBYTE(7,RssV),fGETUBYTE(7,RttV))))); + }) + + +Q6INSN(M5_vdmacbsu,"Rxx32+=vdmpybsu(Rss32,Rtt32):sat",ATTRIBS(), + "vector quad mac bytes", +{ + fSETHALF(0,RxxV,fSATN(16,(fGETHALF(0,RxxV) + + fMPY16SS(fGETBYTE(0,RssV),fGETUBYTE(0,RttV)) + + fMPY16SS(fGETBYTE(1,RssV),fGETUBYTE(1,RttV))))); + fSETHALF(1,RxxV,fSATN(16,(fGETHALF(1,RxxV) + + fMPY16SS(fGETBYTE(2,RssV),fGETUBYTE(2,RttV)) + + fMPY16SS(fGETBYTE(3,RssV),fGETUBYTE(3,RttV))))); + fSETHALF(2,RxxV,fSATN(16,(fGETHALF(2,RxxV) + + fMPY16SS(fGETBYTE(4,RssV),fGETUBYTE(4,RttV)) + + fMPY16SS(fGETBYTE(5,RssV),fGETUBYTE(5,RttV))))); + fSETHALF(3,RxxV,fSATN(16,(fGETHALF(3,RxxV) + + fMPY16SS(fGETBYTE(6,RssV),fGETUBYTE(6,RttV)) + + fMPY16SS(fGETBYTE(7,RssV),fGETUBYTE(7,RttV))))); + }) + + + +/* Full version */ +#undef dmpy_sema +#define dmpy_sema(N)\ +{ fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + fSCALE(N,fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV))) + \ + fSCALE(N,fMPY16SS(fGETHALF(1,RssV),fGETHALF(1,RttV)))));\ + fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + fSCALE(N,fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV))) + \ + fSCALE(N,fMPY16SS(fGETHALF(3,RssV),fGETHALF(3,RttV)))));\ +} +Q6INSN(M2_vdmacs_s0,"Rxx32+=vdmpy(Rss32,Rtt32):sat",ATTRIBS(), "",dmpy_sema(0)) +Q6INSN(M2_vdmacs_s1,"Rxx32+=vdmpy(Rss32,Rtt32):<<1:sat",ATTRIBS(),"",dmpy_sema(1)) + +#undef dmpy_sema +#define dmpy_sema(N)\ +{ fSETWORD(0,RddV,fSAT(fSCALE(N,fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV))) + \ + fSCALE(N,fMPY16SS(fGETHALF(1,RssV),fGETHALF(1,RttV)))));\ + fSETWORD(1,RddV,fSAT(fSCALE(N,fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV))) + \ + fSCALE(N,fMPY16SS(fGETHALF(3,RssV),fGETHALF(3,RttV)))));\ +} + +Q6INSN(M2_vdmpys_s0,"Rdd32=vdmpy(Rss32,Rtt32):sat",ATTRIBS(), "",dmpy_sema(0)) +Q6INSN(M2_vdmpys_s1,"Rdd32=vdmpy(Rss32,Rtt32):<<1:sat",ATTRIBS(),"",dmpy_sema(1)) + + + +/******************************************************/ +/* complex multiply/mac with */ +/* real&imag are packed together and always saturated */ +/* to protect against overflow. */ +/******************************************************/ + +#undef cmpy_sema +#define cmpy_sema(N,CONJMINUS,CONJPLUS)\ +{ fSETHALF(1,RdV,fGETHALF(1,(fSAT(fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(0,RtV))) CONJMINUS \ + fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(1,RtV))) + 0x8000))));\ + fSETHALF(0,RdV,fGETHALF(1,(fSAT(fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(0,RtV))) CONJPLUS \ + fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(1,RtV))) + 0x8000))));\ +} +Q6INSN(M2_cmpyrs_s0,"Rd32=cmpy(Rs32,Rt32):rnd:sat",ATTRIBS(), "Complex Multiply",cmpy_sema(0,+,-)) +Q6INSN(M2_cmpyrs_s1,"Rd32=cmpy(Rs32,Rt32):<<1:rnd:sat",ATTRIBS(),"Complex Multiply",cmpy_sema(1,+,-)) + + +Q6INSN(M2_cmpyrsc_s0,"Rd32=cmpy(Rs32,Rt32*):rnd:sat",ATTRIBS(A_ARCHV2), "Complex Multiply",cmpy_sema(0,-,+)) +Q6INSN(M2_cmpyrsc_s1,"Rd32=cmpy(Rs32,Rt32*):<<1:rnd:sat",ATTRIBS(A_ARCHV2),"Complex Multiply",cmpy_sema(1,-,+)) + + +#undef cmpy_sema +#define cmpy_sema(N,CONJMINUS,CONJPLUS)\ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(0,RtV))) CONJMINUS \ + fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(1,RtV)))));\ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(0,RtV))) CONJPLUS \ + fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(1,RtV)))));\ +} +Q6INSN(M2_cmacs_s0,"Rxx32+=cmpy(Rs32,Rt32):sat",ATTRIBS(), "Complex Multiply",cmpy_sema(0,+,-)) +Q6INSN(M2_cmacs_s1,"Rxx32+=cmpy(Rs32,Rt32):<<1:sat",ATTRIBS(),"Complex Multiply",cmpy_sema(1,+,-)) + +/* EJP: Need mac versions w/ CONJ T? */ +Q6INSN(M2_cmacsc_s0,"Rxx32+=cmpy(Rs32,Rt32*):sat",ATTRIBS(A_ARCHV2), "Complex Multiply",cmpy_sema(0,-,+)) +Q6INSN(M2_cmacsc_s1,"Rxx32+=cmpy(Rs32,Rt32*):<<1:sat",ATTRIBS(A_ARCHV2),"Complex Multiply",cmpy_sema(1,-,+)) + + +#undef cmpy_sema +#define cmpy_sema(N,CONJMINUS,CONJPLUS)\ +{ fSETWORD(1,RddV,fSAT(fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(0,RtV))) CONJMINUS \ + fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(1,RtV)))));\ + fSETWORD(0,RddV,fSAT(fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(0,RtV))) CONJPLUS \ + fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(1,RtV)))));\ +} + +Q6INSN(M2_cmpys_s0,"Rdd32=cmpy(Rs32,Rt32):sat",ATTRIBS(), "Complex Multiply",cmpy_sema(0,+,-)) +Q6INSN(M2_cmpys_s1,"Rdd32=cmpy(Rs32,Rt32):<<1:sat",ATTRIBS(),"Complex Multiply",cmpy_sema(1,+,-)) + +Q6INSN(M2_cmpysc_s0,"Rdd32=cmpy(Rs32,Rt32*):sat",ATTRIBS(A_ARCHV2), "Complex Multiply",cmpy_sema(0,-,+)) +Q6INSN(M2_cmpysc_s1,"Rdd32=cmpy(Rs32,Rt32*):<<1:sat",ATTRIBS(A_ARCHV2),"Complex Multiply",cmpy_sema(1,-,+)) + + + +#undef cmpy_sema +#define cmpy_sema(N,CONJMINUS,CONJPLUS)\ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) - (fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(0,RtV))) CONJMINUS \ + fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(1,RtV))))));\ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) - (fSCALE(N,fMPY16SS(fGETHALF(0,RsV),fGETHALF(0,RtV))) CONJPLUS \ + fSCALE(N,fMPY16SS(fGETHALF(1,RsV),fGETHALF(1,RtV))))));\ +} +Q6INSN(M2_cnacs_s0,"Rxx32-=cmpy(Rs32,Rt32):sat",ATTRIBS(A_ARCHV2), "Complex Multiply",cmpy_sema(0,+,-)) +Q6INSN(M2_cnacs_s1,"Rxx32-=cmpy(Rs32,Rt32):<<1:sat",ATTRIBS(A_ARCHV2),"Complex Multiply",cmpy_sema(1,+,-)) + +/* EJP: need CONJ versions? */ +Q6INSN(M2_cnacsc_s0,"Rxx32-=cmpy(Rs32,Rt32*):sat",ATTRIBS(A_ARCHV2), "Complex Multiply",cmpy_sema(0,-,+)) +Q6INSN(M2_cnacsc_s1,"Rxx32-=cmpy(Rs32,Rt32*):<<1:sat",ATTRIBS(A_ARCHV2),"Complex Multiply",cmpy_sema(1,-,+)) + + +/******************************************************/ +/* complex interpolation */ +/* Given a pair of complex values, scale by a,b, sum */ +/* Saturate/shift1 and round/pack */ +/******************************************************/ + +#undef vrcmpys_sema +#define vrcmpys_sema(N,INWORD) \ +{ fSETWORD(1,RddV,fSAT(fSCALE(N,fMPY16SS(fGETHALF(1,RssV),fGETHALF(0,INWORD))) + \ + fSCALE(N,fMPY16SS(fGETHALF(3,RssV),fGETHALF(1,INWORD)))));\ + fSETWORD(0,RddV,fSAT(fSCALE(N,fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,INWORD))) + \ + fSCALE(N,fMPY16SS(fGETHALF(2,RssV),fGETHALF(1,INWORD)))));\ +} + + + +Q6INSN(M2_vrcmpys_s1_h,"Rdd32=vrcmpys(Rss32,Rtt32):<<1:sat:raw:hi",ATTRIBS(A_ARCHV3), "Vector Reduce Complex Multiply by Scalar",vrcmpys_sema(1,fGETWORD(1,RttV))) +Q6INSN(M2_vrcmpys_s1_l,"Rdd32=vrcmpys(Rss32,Rtt32):<<1:sat:raw:lo",ATTRIBS(A_ARCHV3), "Vector Reduce Complex Multiply by Scalar",vrcmpys_sema(1,fGETWORD(0,RttV))) + +#undef vrcmpys_sema +#define vrcmpys_sema(N,INWORD) \ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + fSCALE(N,fMPY16SS(fGETHALF(1,RssV),fGETHALF(0,INWORD))) + \ + fSCALE(N,fMPY16SS(fGETHALF(3,RssV),fGETHALF(1,INWORD)))));\ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + fSCALE(N,fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,INWORD))) + \ + fSCALE(N,fMPY16SS(fGETHALF(2,RssV),fGETHALF(1,INWORD)))));\ +} + + + +Q6INSN(M2_vrcmpys_acc_s1_h,"Rxx32+=vrcmpys(Rss32,Rtt32):<<1:sat:raw:hi",ATTRIBS(A_ARCHV3), "Vector Reduce Complex Multiply by Scalar",vrcmpys_sema(1,fGETWORD(1,RttV))) +Q6INSN(M2_vrcmpys_acc_s1_l,"Rxx32+=vrcmpys(Rss32,Rtt32):<<1:sat:raw:lo",ATTRIBS(A_ARCHV3), "Vector Reduce Complex Multiply by Scalar",vrcmpys_sema(1,fGETWORD(0,RttV))) + +#undef vrcmpys_sema +#define vrcmpys_sema(N,INWORD) \ +{ fSETHALF(1,RdV,fGETHALF(1,fSAT(fSCALE(N,fMPY16SS(fGETHALF(1,RssV),fGETHALF(0,INWORD))) + \ + fSCALE(N,fMPY16SS(fGETHALF(3,RssV),fGETHALF(1,INWORD))) + 0x8000)));\ + fSETHALF(0,RdV,fGETHALF(1,fSAT(fSCALE(N,fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,INWORD))) + \ + fSCALE(N,fMPY16SS(fGETHALF(2,RssV),fGETHALF(1,INWORD))) + 0x8000)));\ +} + +Q6INSN(M2_vrcmpys_s1rp_h,"Rd32=vrcmpys(Rss32,Rtt32):<<1:rnd:sat:raw:hi",ATTRIBS(A_ARCHV3), "Vector Reduce Complex Multiply by Scalar",vrcmpys_sema(1,fGETWORD(1,RttV))) +Q6INSN(M2_vrcmpys_s1rp_l,"Rd32=vrcmpys(Rss32,Rtt32):<<1:rnd:sat:raw:lo",ATTRIBS(A_ARCHV3), "Vector Reduce Complex Multiply by Scalar",vrcmpys_sema(1,fGETWORD(0,RttV))) + +/**************************************************************/ +/* mixed mode 32x16 vector dual multiplies */ +/* */ +/**************************************************************/ + +/* SIGNED 32 x SIGNED 16 */ + + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + ((fSCALE(N,fMPY3216SS(fGETWORD(1,RssV),fGETHALF(2,RttV))))>>16)) ); \ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + ((fSCALE(N,fMPY3216SS(fGETWORD(0,RssV),fGETHALF(0,RttV))))>>16)) ); \ +} +Q6INSN(M2_mmacls_s0,"Rxx32+=vmpyweh(Rss32,Rtt32):sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmacls_s1,"Rxx32+=vmpyweh(Rss32,Rtt32):<<1:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + ((fSCALE(N,fMPY3216SS(fGETWORD(1,RssV),fGETHALF(3,RttV))))>>16) )); \ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + ((fSCALE(N,fMPY3216SS(fGETWORD(0,RssV),fGETHALF(1,RttV))))>>16 ))); \ +} +Q6INSN(M2_mmachs_s0,"Rxx32+=vmpywoh(Rss32,Rtt32):sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmachs_s1,"Rxx32+=vmpywoh(Rss32,Rtt32):<<1:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RddV,fSAT((fSCALE(N,fMPY3216SS(fGETWORD(1,RssV),fGETHALF(2,RttV))))>>16)); \ + fSETWORD(0,RddV,fSAT((fSCALE(N,fMPY3216SS(fGETWORD(0,RssV),fGETHALF(0,RttV))))>>16)); \ +} +Q6INSN(M2_mmpyl_s0,"Rdd32=vmpyweh(Rss32,Rtt32):sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmpyl_s1,"Rdd32=vmpyweh(Rss32,Rtt32):<<1:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RddV,fSAT((fSCALE(N,fMPY3216SS(fGETWORD(1,RssV),fGETHALF(3,RttV))))>>16)); \ + fSETWORD(0,RddV,fSAT((fSCALE(N,fMPY3216SS(fGETWORD(0,RssV),fGETHALF(1,RttV))))>>16)); \ +} +Q6INSN(M2_mmpyh_s0,"Rdd32=vmpywoh(Rss32,Rtt32):sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmpyh_s1,"Rdd32=vmpywoh(Rss32,Rtt32):<<1:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + + +/* With rounding */ + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + ((fSCALE(N,fMPY3216SS(fGETWORD(1,RssV),fGETHALF(2,RttV)))+0x8000)>>16)) ); \ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + ((fSCALE(N,fMPY3216SS(fGETWORD(0,RssV),fGETHALF(0,RttV)))+0x8000)>>16)) ); \ +} +Q6INSN(M2_mmacls_rs0,"Rxx32+=vmpyweh(Rss32,Rtt32):rnd:sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmacls_rs1,"Rxx32+=vmpyweh(Rss32,Rtt32):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + ((fSCALE(N,fMPY3216SS(fGETWORD(1,RssV),fGETHALF(3,RttV)))+0x8000)>>16) )); \ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + ((fSCALE(N,fMPY3216SS(fGETWORD(0,RssV),fGETHALF(1,RttV)))+0x8000)>>16 ))); \ +} +Q6INSN(M2_mmachs_rs0,"Rxx32+=vmpywoh(Rss32,Rtt32):rnd:sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmachs_rs1,"Rxx32+=vmpywoh(Rss32,Rtt32):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RddV,fSAT((fSCALE(N,fMPY3216SS(fGETWORD(1,RssV),fGETHALF(2,RttV)))+0x8000)>>16)); \ + fSETWORD(0,RddV,fSAT((fSCALE(N,fMPY3216SS(fGETWORD(0,RssV),fGETHALF(0,RttV)))+0x8000)>>16)); \ +} +Q6INSN(M2_mmpyl_rs0,"Rdd32=vmpyweh(Rss32,Rtt32):rnd:sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmpyl_rs1,"Rdd32=vmpyweh(Rss32,Rtt32):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RddV,fSAT((fSCALE(N,fMPY3216SS(fGETWORD(1,RssV),fGETHALF(3,RttV)))+0x8000)>>16)); \ + fSETWORD(0,RddV,fSAT((fSCALE(N,fMPY3216SS(fGETWORD(0,RssV),fGETHALF(1,RttV)))+0x8000)>>16)); \ +} +Q6INSN(M2_mmpyh_rs0,"Rdd32=vmpywoh(Rss32,Rtt32):rnd:sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmpyh_rs1,"Rdd32=vmpywoh(Rss32,Rtt32):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + + +#undef mixmpy_sema +#define mixmpy_sema(DEST,EQUALS,N)\ +{ DEST EQUALS fSCALE(N,fMPY3216SS(fGETWORD(1,RssV),fGETHALF(2,RttV))) + fSCALE(N,fMPY3216SS(fGETWORD(0,RssV),fGETHALF(0,RttV)));} + +Q6INSN(M4_vrmpyeh_s0,"Rdd32=vrmpyweh(Rss32,Rtt32)",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(RddV,=,0)) +Q6INSN(M4_vrmpyeh_s1,"Rdd32=vrmpyweh(Rss32,Rtt32):<<1",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(RddV,=,1)) +Q6INSN(M4_vrmpyeh_acc_s0,"Rxx32+=vrmpyweh(Rss32,Rtt32)",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(RxxV,+=,0)) +Q6INSN(M4_vrmpyeh_acc_s1,"Rxx32+=vrmpyweh(Rss32,Rtt32):<<1",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(RxxV,+=,1)) + +#undef mixmpy_sema +#define mixmpy_sema(DEST,EQUALS,N)\ +{ DEST EQUALS fSCALE(N,fMPY3216SS(fGETWORD(1,RssV),fGETHALF(3,RttV))) + fSCALE(N,fMPY3216SS(fGETWORD(0,RssV),fGETHALF(1,RttV)));} + +Q6INSN(M4_vrmpyoh_s0,"Rdd32=vrmpywoh(Rss32,Rtt32)",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(RddV,=,0)) +Q6INSN(M4_vrmpyoh_s1,"Rdd32=vrmpywoh(Rss32,Rtt32):<<1",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(RddV,=,1)) +Q6INSN(M4_vrmpyoh_acc_s0,"Rxx32+=vrmpywoh(Rss32,Rtt32)",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(RxxV,+=,0)) +Q6INSN(M4_vrmpyoh_acc_s1,"Rxx32+=vrmpywoh(Rss32,Rtt32):<<1",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(RxxV,+=,1)) + + + + + + +#undef mixmpy_sema +#define mixmpy_sema(N,H,RND)\ +{ RdV = fSAT((fSCALE(N,fMPY3216SS(RsV,fGETHALF(H,RtV)))RND)>>16); \ +} +Q6INSN(M2_hmmpyl_rs1,"Rd32=mpy(Rs32,Rt.L32):<<1:rnd:sat",ATTRIBS(A_ARCHV2),"Mixed Precision Multiply",mixmpy_sema(1,0,+0x8000)) +Q6INSN(M2_hmmpyh_rs1,"Rd32=mpy(Rs32,Rt.H32):<<1:rnd:sat",ATTRIBS(A_ARCHV2),"Mixed Precision Multiply",mixmpy_sema(1,1,+0x8000)) +Q6INSN(M2_hmmpyl_s1,"Rd32=mpy(Rs32,Rt.L32):<<1:sat",ATTRIBS(A_ARCHV2),"Mixed Precision Multiply",mixmpy_sema(1,0,)) +Q6INSN(M2_hmmpyh_s1,"Rd32=mpy(Rs32,Rt.H32):<<1:sat",ATTRIBS(A_ARCHV2),"Mixed Precision Multiply",mixmpy_sema(1,1,)) + + + + + + + + + +/* SIGNED 32 x UNSIGNED 16 */ + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + ((fSCALE(N,fMPY3216SU(fGETWORD(1,RssV),fGETUHALF(2,RttV))))>>16)) ); \ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + ((fSCALE(N,fMPY3216SU(fGETWORD(0,RssV),fGETUHALF(0,RttV))))>>16)) ); \ +} +Q6INSN(M2_mmaculs_s0,"Rxx32+=vmpyweuh(Rss32,Rtt32):sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmaculs_s1,"Rxx32+=vmpyweuh(Rss32,Rtt32):<<1:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + ((fSCALE(N,fMPY3216SU(fGETWORD(1,RssV),fGETUHALF(3,RttV))))>>16) )); \ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + ((fSCALE(N,fMPY3216SU(fGETWORD(0,RssV),fGETUHALF(1,RttV))))>>16 ))); \ +} +Q6INSN(M2_mmacuhs_s0,"Rxx32+=vmpywouh(Rss32,Rtt32):sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmacuhs_s1,"Rxx32+=vmpywouh(Rss32,Rtt32):<<1:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RddV,fSAT((fSCALE(N,fMPY3216SU(fGETWORD(1,RssV),fGETUHALF(2,RttV))))>>16)); \ + fSETWORD(0,RddV,fSAT((fSCALE(N,fMPY3216SU(fGETWORD(0,RssV),fGETUHALF(0,RttV))))>>16)); \ +} +Q6INSN(M2_mmpyul_s0,"Rdd32=vmpyweuh(Rss32,Rtt32):sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmpyul_s1,"Rdd32=vmpyweuh(Rss32,Rtt32):<<1:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RddV,fSAT((fSCALE(N,fMPY3216SU(fGETWORD(1,RssV),fGETUHALF(3,RttV))))>>16)); \ + fSETWORD(0,RddV,fSAT((fSCALE(N,fMPY3216SU(fGETWORD(0,RssV),fGETUHALF(1,RttV))))>>16)); \ +} +Q6INSN(M2_mmpyuh_s0,"Rdd32=vmpywouh(Rss32,Rtt32):sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmpyuh_s1,"Rdd32=vmpywouh(Rss32,Rtt32):<<1:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + + +/* With rounding */ + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + ((fSCALE(N,fMPY3216SU(fGETWORD(1,RssV),fGETUHALF(2,RttV)))+0x8000)>>16)) ); \ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + ((fSCALE(N,fMPY3216SU(fGETWORD(0,RssV),fGETUHALF(0,RttV)))+0x8000)>>16)) ); \ +} +Q6INSN(M2_mmaculs_rs0,"Rxx32+=vmpyweuh(Rss32,Rtt32):rnd:sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmaculs_rs1,"Rxx32+=vmpyweuh(Rss32,Rtt32):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RxxV,fSAT(fGETWORD(1,RxxV) + ((fSCALE(N,fMPY3216SU(fGETWORD(1,RssV),fGETUHALF(3,RttV)))+0x8000)>>16) )); \ + fSETWORD(0,RxxV,fSAT(fGETWORD(0,RxxV) + ((fSCALE(N,fMPY3216SU(fGETWORD(0,RssV),fGETUHALF(1,RttV)))+0x8000)>>16 ))); \ +} +Q6INSN(M2_mmacuhs_rs0,"Rxx32+=vmpywouh(Rss32,Rtt32):rnd:sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmacuhs_rs1,"Rxx32+=vmpywouh(Rss32,Rtt32):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RddV,fSAT((fSCALE(N,fMPY3216SU(fGETWORD(1,RssV),fGETUHALF(2,RttV)))+0x8000)>>16)); \ + fSETWORD(0,RddV,fSAT((fSCALE(N,fMPY3216SU(fGETWORD(0,RssV),fGETUHALF(0,RttV)))+0x8000)>>16)); \ +} +Q6INSN(M2_mmpyul_rs0,"Rdd32=vmpyweuh(Rss32,Rtt32):rnd:sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmpyul_rs1,"Rdd32=vmpyweuh(Rss32,Rtt32):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + +#undef mixmpy_sema +#define mixmpy_sema(N)\ +{ fSETWORD(1,RddV,fSAT((fSCALE(N,fMPY3216SU(fGETWORD(1,RssV),fGETUHALF(3,RttV)))+0x8000)>>16)); \ + fSETWORD(0,RddV,fSAT((fSCALE(N,fMPY3216SU(fGETWORD(0,RssV),fGETUHALF(1,RttV)))+0x8000)>>16)); \ +} +Q6INSN(M2_mmpyuh_rs0,"Rdd32=vmpywouh(Rss32,Rtt32):rnd:sat",ATTRIBS(), "Mixed Precision Multiply",mixmpy_sema(0)) +Q6INSN(M2_mmpyuh_rs1,"Rdd32=vmpywouh(Rss32,Rtt32):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Multiply",mixmpy_sema(1)) + + +/**************************************************************/ +/* complex mac with full 64-bit accum - no sat, no shift */ +/* either do real or accum, never both */ +/**************************************************************/ + +Q6INSN(M2_vrcmaci_s0,"Rxx32+=vrcmpyi(Rss32,Rtt32)",ATTRIBS(),"Vector Complex Mac Imaginary", +{ +RxxV = RxxV + fMPY16SS(fGETHALF(1,RssV),fGETHALF(0,RttV)) + \ + fMPY16SS(fGETHALF(0,RssV),fGETHALF(1,RttV)) + \ + fMPY16SS(fGETHALF(3,RssV),fGETHALF(2,RttV)) + \ + fMPY16SS(fGETHALF(2,RssV),fGETHALF(3,RttV));\ +}) + +Q6INSN(M2_vrcmacr_s0,"Rxx32+=vrcmpyr(Rss32,Rtt32)",ATTRIBS(),"Vector Complex Mac Real", +{ RxxV = RxxV + fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV)) - \ + fMPY16SS(fGETHALF(1,RssV),fGETHALF(1,RttV)) + \ + fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV)) - \ + fMPY16SS(fGETHALF(3,RssV),fGETHALF(3,RttV));\ +}) + +Q6INSN(M2_vrcmaci_s0c,"Rxx32+=vrcmpyi(Rss32,Rtt32*)",ATTRIBS(A_ARCHV2),"Vector Complex Mac Imaginary", +{ +RxxV = RxxV + fMPY16SS(fGETHALF(1,RssV),fGETHALF(0,RttV)) - \ + fMPY16SS(fGETHALF(0,RssV),fGETHALF(1,RttV)) + \ + fMPY16SS(fGETHALF(3,RssV),fGETHALF(2,RttV)) - \ + fMPY16SS(fGETHALF(2,RssV),fGETHALF(3,RttV));\ +}) + +Q6INSN(M2_vrcmacr_s0c,"Rxx32+=vrcmpyr(Rss32,Rtt32*)",ATTRIBS(A_ARCHV2),"Vector Complex Mac Real", +{ RxxV = RxxV + fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV)) + \ + fMPY16SS(fGETHALF(1,RssV),fGETHALF(1,RttV)) + \ + fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV)) + \ + fMPY16SS(fGETHALF(3,RssV),fGETHALF(3,RttV));\ +}) + +Q6INSN(M2_cmaci_s0,"Rxx32+=cmpyi(Rs32,Rt32)",ATTRIBS(),"Vector Complex Mac Imaginary", +{ +RxxV = RxxV + fMPY16SS(fGETHALF(1,RsV),fGETHALF(0,RtV)) + \ + fMPY16SS(fGETHALF(0,RsV),fGETHALF(1,RtV)); +}) + +Q6INSN(M2_cmacr_s0,"Rxx32+=cmpyr(Rs32,Rt32)",ATTRIBS(),"Vector Complex Mac Real", +{ RxxV = RxxV + fMPY16SS(fGETHALF(0,RsV),fGETHALF(0,RtV)) - \ + fMPY16SS(fGETHALF(1,RsV),fGETHALF(1,RtV)); +}) + + +Q6INSN(M2_vrcmpyi_s0,"Rdd32=vrcmpyi(Rss32,Rtt32)",ATTRIBS(),"Vector Complex Mpy Imaginary", +{ +RddV = fMPY16SS(fGETHALF(1,RssV),fGETHALF(0,RttV)) + \ + fMPY16SS(fGETHALF(0,RssV),fGETHALF(1,RttV)) + \ + fMPY16SS(fGETHALF(3,RssV),fGETHALF(2,RttV)) + \ + fMPY16SS(fGETHALF(2,RssV),fGETHALF(3,RttV));\ +}) + +Q6INSN(M2_vrcmpyr_s0,"Rdd32=vrcmpyr(Rss32,Rtt32)",ATTRIBS(),"Vector Complex Mpy Real", +{ RddV = fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV)) - \ + fMPY16SS(fGETHALF(1,RssV),fGETHALF(1,RttV)) + \ + fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV)) - \ + fMPY16SS(fGETHALF(3,RssV),fGETHALF(3,RttV));\ +}) + +Q6INSN(M2_vrcmpyi_s0c,"Rdd32=vrcmpyi(Rss32,Rtt32*)",ATTRIBS(A_ARCHV2),"Vector Complex Mpy Imaginary", +{ +RddV = fMPY16SS(fGETHALF(1,RssV),fGETHALF(0,RttV)) - \ + fMPY16SS(fGETHALF(0,RssV),fGETHALF(1,RttV)) + \ + fMPY16SS(fGETHALF(3,RssV),fGETHALF(2,RttV)) - \ + fMPY16SS(fGETHALF(2,RssV),fGETHALF(3,RttV));\ +}) + +Q6INSN(M2_vrcmpyr_s0c,"Rdd32=vrcmpyr(Rss32,Rtt32*)",ATTRIBS(A_ARCHV2),"Vector Complex Mpy Real", +{ RddV = fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV)) + \ + fMPY16SS(fGETHALF(1,RssV),fGETHALF(1,RttV)) + \ + fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV)) + \ + fMPY16SS(fGETHALF(3,RssV),fGETHALF(3,RttV));\ +}) + +Q6INSN(M2_cmpyi_s0,"Rdd32=cmpyi(Rs32,Rt32)",ATTRIBS(),"Vector Complex Mpy Imaginary", +{ +RddV = fMPY16SS(fGETHALF(1,RsV),fGETHALF(0,RtV)) + \ + fMPY16SS(fGETHALF(0,RsV),fGETHALF(1,RtV)); +}) + +Q6INSN(M2_cmpyr_s0,"Rdd32=cmpyr(Rs32,Rt32)",ATTRIBS(),"Vector Complex Mpy Real", +{ RddV = fMPY16SS(fGETHALF(0,RsV),fGETHALF(0,RtV)) - \ + fMPY16SS(fGETHALF(1,RsV),fGETHALF(1,RtV)); +}) + + +/**************************************************************/ +/* Complex mpy/mac with 2x32 bit accum, sat, shift */ +/* 32x16 real or imag */ +/**************************************************************/ + +#if 1 + +Q6INSN(M4_cmpyi_wh,"Rd32=cmpyiwh(Rss32,Rt32):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Complex Multiply", +{ + RdV = fSAT( ( fMPY3216SS(fGETWORD(0,RssV),fGETHALF(1,RtV)) + + fMPY3216SS(fGETWORD(1,RssV),fGETHALF(0,RtV)) + + 0x4000)>>15); +}) + + +Q6INSN(M4_cmpyr_wh,"Rd32=cmpyrwh(Rss32,Rt32):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Complex Multiply", +{ + RdV = fSAT( ( fMPY3216SS(fGETWORD(0,RssV),fGETHALF(0,RtV)) + - fMPY3216SS(fGETWORD(1,RssV),fGETHALF(1,RtV)) + + 0x4000)>>15); +}) + +Q6INSN(M4_cmpyi_whc,"Rd32=cmpyiwh(Rss32,Rt32*):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Complex Multiply", +{ + RdV = fSAT( ( fMPY3216SS(fGETWORD(1,RssV),fGETHALF(0,RtV)) + - fMPY3216SS(fGETWORD(0,RssV),fGETHALF(1,RtV)) + + 0x4000)>>15); +}) + + +Q6INSN(M4_cmpyr_whc,"Rd32=cmpyrwh(Rss32,Rt32*):<<1:rnd:sat",ATTRIBS(),"Mixed Precision Complex Multiply", +{ + RdV = fSAT( ( fMPY3216SS(fGETWORD(0,RssV),fGETHALF(0,RtV)) + + fMPY3216SS(fGETWORD(1,RssV),fGETHALF(1,RtV)) + + 0x4000)>>15); +}) + + +#endif + +/**************************************************************/ +/* Vector mpy/mac with 2x32 bit accum, sat, shift */ +/* either do real or imag, never both */ +/**************************************************************/ + +#undef VCMPYSEMI +#define VCMPYSEMI(DST,ACC0,ACC1,SHIFT,SAT) \ + fSETWORD(0,DST,SAT(ACC0 fSCALE(SHIFT,fMPY16SS(fGETHALF(1,RssV),fGETHALF(0,RttV)) + \ + fMPY16SS(fGETHALF(0,RssV),fGETHALF(1,RttV))))); \ + fSETWORD(1,DST,SAT(ACC1 fSCALE(SHIFT,fMPY16SS(fGETHALF(3,RssV),fGETHALF(2,RttV)) + \ + fMPY16SS(fGETHALF(2,RssV),fGETHALF(3,RttV))))); \ + +#undef VCMPYSEMR +#define VCMPYSEMR(DST,ACC0,ACC1,SHIFT,SAT) \ + fSETWORD(0,DST,SAT(ACC0 fSCALE(SHIFT,fMPY16SS(fGETHALF(0,RssV),fGETHALF(0,RttV)) - \ + fMPY16SS(fGETHALF(1,RssV),fGETHALF(1,RttV))))); \ + fSETWORD(1,DST,SAT(ACC1 fSCALE(SHIFT,fMPY16SS(fGETHALF(2,RssV),fGETHALF(2,RttV)) - \ + fMPY16SS(fGETHALF(3,RssV),fGETHALF(3,RttV))))); \ + + +#undef VCMPYIR +#define VCMPYIR(TAGBASE,DSTSYN,DSTVAL,ACCSEM,ACCVAL0,ACCVAL1,SHIFTSYN,SHIFTVAL,SATSYN,SATVAL) \ +Q6INSN(M2_##TAGBASE##i,DSTSYN ACCSEM "vcmpyi(Rss32,Rtt32)" SHIFTSYN SATSYN,ATTRIBS(A_ARCHV2), \ + "Vector Complex Multiply Imaginary", { VCMPYSEMI(DSTVAL,ACCVAL0,ACCVAL1,SHIFTVAL,SATVAL); }) \ +Q6INSN(M2_##TAGBASE##r,DSTSYN ACCSEM "vcmpyr(Rss32,Rtt32)" SHIFTSYN SATSYN,ATTRIBS(A_ARCHV2), \ + "Vector Complex Multiply Imaginary", { VCMPYSEMR(DSTVAL,ACCVAL0,ACCVAL1,SHIFTVAL,SATVAL); }) + + +VCMPYIR(vcmpy_s0_sat_,"Rdd32",RddV,"=",,,"",0,":sat",fSAT) +VCMPYIR(vcmpy_s1_sat_,"Rdd32",RddV,"=",,,":<<1",1,":sat",fSAT) +VCMPYIR(vcmac_s0_sat_,"Rxx32",RxxV,"+=",fGETWORD(0,RxxV) + ,fGETWORD(1,RxxV) + ,"",0,":sat",fSAT) + + +/********************************************************************** + * Rotation -- by 0, 90, 180, or 270 means mult by 1, J, -1, -J * + *********************************************************************/ + +Q6INSN(S2_vcrotate,"Rdd32=vcrotate(Rss32,Rt32)",ATTRIBS(A_ARCHV2),"Rotate complex value by multiple of PI/2", +{ + fHIDE(size1u_t tmp;) + tmp = fEXTRACTU_RANGE(RtV,1,0); + if (tmp == 0) { /* No rotation */ + fSETHALF(0,RddV,fGETHALF(0,RssV)); + fSETHALF(1,RddV,fGETHALF(1,RssV)); + } else if (tmp == 1) { /* Multiply by -J */ + fSETHALF(0,RddV,fGETHALF(1,RssV)); + fSETHALF(1,RddV,fSATH(-fGETHALF(0,RssV))); + } else if (tmp == 2) { /* Multiply by J */ + fSETHALF(0,RddV,fSATH(-fGETHALF(1,RssV))); + fSETHALF(1,RddV,fGETHALF(0,RssV)); + } else { /* Multiply by -1 */ + fHIDE(if (tmp != 3) fatal("C is broken");) + fSETHALF(0,RddV,fSATH(-fGETHALF(0,RssV))); + fSETHALF(1,RddV,fSATH(-fGETHALF(1,RssV))); + } + tmp = fEXTRACTU_RANGE(RtV,3,2); + if (tmp == 0) { /* No rotation */ + fSETHALF(2,RddV,fGETHALF(2,RssV)); + fSETHALF(3,RddV,fGETHALF(3,RssV)); + } else if (tmp == 1) { /* Multiply by -J */ + fSETHALF(2,RddV,fGETHALF(3,RssV)); + fSETHALF(3,RddV,fSATH(-fGETHALF(2,RssV))); + } else if (tmp == 2) { /* Multiply by J */ + fSETHALF(2,RddV,fSATH(-fGETHALF(3,RssV))); + fSETHALF(3,RddV,fGETHALF(2,RssV)); + } else { /* Multiply by -1 */ + fHIDE(if (tmp != 3) fatal("C is broken");) + fSETHALF(2,RddV,fSATH(-fGETHALF(2,RssV))); + fSETHALF(3,RddV,fSATH(-fGETHALF(3,RssV))); + } +}) + + +Q6INSN(S4_vrcrotate_acc,"Rxx32+=vrcrotate(Rss32,Rt32,#u2)",ATTRIBS(),"Rotate and Reduce Bytes", +{ + fHIDE(int i; int tmpr; int tmpi; unsigned int control;) + fHIDE(int sumr; int sumi;) + sumr = 0; + sumi = 0; + control = fGETUBYTE(uiV,RtV); + for (i = 0; i < 8; i += 2) { + tmpr = fGETBYTE(i ,RssV); + tmpi = fGETBYTE(i+1,RssV); + switch (control & 3) { + case 0: /* No Rotation */ + sumr += tmpr; + sumi += tmpi; + break; + case 1: /* Multiply by -J */ + sumr += tmpi; + sumi -= tmpr; + break; + case 2: /* Multiply by J */ + sumr -= tmpi; + sumi += tmpr; + break; + case 3: /* Multiply by -1 */ + sumr -= tmpr; + sumi -= tmpi; + break; + fHIDE(default: fatal("C is broken!");) + } + control = control >> 2; + } + fSETWORD(0,RxxV,fGETWORD(0,RxxV) + sumr); + fSETWORD(1,RxxV,fGETWORD(1,RxxV) + sumi); +}) + +Q6INSN(S4_vrcrotate,"Rdd32=vrcrotate(Rss32,Rt32,#u2)",ATTRIBS(),"Rotate and Reduce Bytes", +{ + fHIDE(int i; int tmpr; int tmpi; unsigned int control;) + fHIDE(int sumr; int sumi;) + sumr = 0; + sumi = 0; + control = fGETUBYTE(uiV,RtV); + for (i = 0; i < 8; i += 2) { + tmpr = fGETBYTE(i ,RssV); + tmpi = fGETBYTE(i+1,RssV); + switch (control & 3) { + case 0: /* No Rotation */ + sumr += tmpr; + sumi += tmpi; + break; + case 1: /* Multiply by -J */ + sumr += tmpi; + sumi -= tmpr; + break; + case 2: /* Multiply by J */ + sumr -= tmpi; + sumi += tmpr; + break; + case 3: /* Multiply by -1 */ + sumr -= tmpr; + sumi -= tmpi; + break; + fHIDE(default: fatal("C is broken!");) + } + control = control >> 2; + } + fSETWORD(0,RddV,sumr); + fSETWORD(1,RddV,sumi); +}) + + +Q6INSN(S2_vcnegh,"Rdd32=vcnegh(Rss32,Rt32)",ATTRIBS(),"Conditional Negate halfwords", +{ + fHIDE(int i;) + for (i = 0; i < 4; i++) { + if (fGETBIT(i,RtV)) { + fSETHALF(i,RddV,fSATH(-fGETHALF(i,RssV))); + } else { + fSETHALF(i,RddV,fGETHALF(i,RssV)); + } + } +}) + +Q6INSN(S2_vrcnegh,"Rxx32+=vrcnegh(Rss32,Rt32)",ATTRIBS(),"Vector Reduce Conditional Negate halfwords", +{ + fHIDE(int i;) + for (i = 0; i < 4; i++) { + if (fGETBIT(i,RtV)) { + RxxV += -fGETHALF(i,RssV); + } else { + RxxV += fGETHALF(i,RssV); + } + } +}) + + +/********************************************************************** + * Finite-field multiplies. Written by David Hoyle * + *********************************************************************/ + +Q6INSN(M4_pmpyw,"Rdd32=pmpyw(Rs32,Rt32)",ATTRIBS(),"Polynomial 32bit Multiplication with Addition in GF(2)", +{ + fHIDE(int i; unsigned int y;) + fHIDE(unsigned long long x; unsigned long long prod;) + x = fGETUWORD(0, RsV); + y = fGETUWORD(0, RtV); + + prod = 0; + for(i=0; i < 32; i++) { + if((y >> i) & 1) prod ^= (x << i); + } + RddV = prod; +}) + +Q6INSN(M4_vpmpyh,"Rdd32=vpmpyh(Rs32,Rt32)",ATTRIBS(),"Dual Polynomial 16bit Multiplication with Addition in GF(2)", +{ + fHIDE(int i; unsigned int x0; unsigned int x1;) + fHIDE(unsigned int y0; unsigned int y1;) + fHIDE(unsigned int prod0; unsigned int prod1;) + + x0 = fGETUHALF(0, RsV); + x1 = fGETUHALF(1, RsV); + y0 = fGETUHALF(0, RtV); + y1 = fGETUHALF(1, RtV); + + prod0 = prod1 = 0; + for(i=0; i < 16; i++) { + if((y0 >> i) & 1) prod0 ^= (x0 << i); + if((y1 >> i) & 1) prod1 ^= (x1 << i); + } + fSETHALF(0,RddV,fGETUHALF(0,prod0)); + fSETHALF(1,RddV,fGETUHALF(0,prod1)); + fSETHALF(2,RddV,fGETUHALF(1,prod0)); + fSETHALF(3,RddV,fGETUHALF(1,prod1)); +}) + +Q6INSN(M4_pmpyw_acc,"Rxx32^=pmpyw(Rs32,Rt32)",ATTRIBS(),"Polynomial 32bit Multiplication with Addition in GF(2)", +{ + fHIDE(int i; unsigned int y;) + fHIDE(unsigned long long x; unsigned long long prod;) + x = fGETUWORD(0, RsV); + y = fGETUWORD(0, RtV); + + prod = 0; + for(i=0; i < 32; i++) { + if((y >> i) & 1) prod ^= (x << i); + } + RxxV ^= prod; +}) + +Q6INSN(M4_vpmpyh_acc,"Rxx32^=vpmpyh(Rs32,Rt32)",ATTRIBS(),"Dual Polynomial 16bit Multiplication with Addition in GF(2)", +{ + fHIDE(int i; unsigned int x0; unsigned int x1;) + fHIDE(unsigned int y0; unsigned int y1;) + fHIDE(unsigned int prod0; unsigned int prod1;) + + x0 = fGETUHALF(0, RsV); + x1 = fGETUHALF(1, RsV); + y0 = fGETUHALF(0, RtV); + y1 = fGETUHALF(1, RtV); + + prod0 = prod1 = 0; + for(i=0; i < 16; i++) { + if((y0 >> i) & 1) prod0 ^= (x0 << i); + if((y1 >> i) & 1) prod1 ^= (x1 << i); + } + fSETHALF(0,RxxV,fGETUHALF(0,RxxV) ^ fGETUHALF(0,prod0)); + fSETHALF(1,RxxV,fGETUHALF(1,RxxV) ^ fGETUHALF(0,prod1)); + fSETHALF(2,RxxV,fGETUHALF(2,RxxV) ^ fGETUHALF(1,prod0)); + fSETHALF(3,RxxV,fGETUHALF(3,RxxV) ^ fGETUHALF(1,prod1)); +}) + + +/* V70: TINY CORE */ + +#define CMPY64(TAG,NAME,DESC,OPERAND1,OP,W0,W1,W2,W3) \ +Q6INSN(M7_##TAG,"Rdd32=" NAME "(Rss32," OPERAND1 ")",ATTRIBS(A_RESTRICT_SLOT3ONLY),"Complex Multiply 64-bit " DESC, { RddV = (fMPY32SS(fGETWORD(W0, RssV), fGETWORD(W1, RttV)) OP fMPY32SS(fGETWORD(W2, RssV), fGETWORD(W3, RttV)));})\ +Q6INSN(M7_##TAG##_acc,"Rxx32+=" NAME "(Rss32,"OPERAND1")",ATTRIBS(A_RESTRICT_SLOT3ONLY),"Complex Multiply-Accumulate 64-bit " DESC, { RxxV += (fMPY32SS(fGETWORD(W0, RssV), fGETWORD(W1, RttV)) OP fMPY32SS(fGETWORD(W2, RssV), fGETWORD(W3, RttV)));}) + +CMPY64(dcmpyrw, "cmpyrw","Real","Rtt32" ,-,0,0,1,1) +CMPY64(dcmpyrwc,"cmpyrw","Real","Rtt32*",+,0,0,1,1) +CMPY64(dcmpyiw, "cmpyiw","Imag","Rtt32" ,+,0,1,1,0) +CMPY64(dcmpyiwc,"cmpyiw","Imag","Rtt32*",-,1,0,0,1) + +#define CMPY128(TAG, NAME, OPERAND1, WORD0, WORD1, WORD2, WORD3, OP) \ +Q6INSN(M7_##TAG,"Rd32=" NAME "(Rss32,"OPERAND1"):<<1:sat",ATTRIBS(A_RESTRICT_SLOT3ONLY),"Complex Multiply 32-bit result real", \ +{ \ +fHIDE(size16s_t acc128;)\ +fHIDE(size16s_t tmp128;)\ +fHIDE(size8s_t acc64;)\ +tmp128 = fCAST8S_16S(fMPY32SS(fGETWORD(WORD0, RssV), fGETWORD(WORD1, RttV)));\ +acc128 = fCAST8S_16S(fMPY32SS(fGETWORD(WORD2, RssV), fGETWORD(WORD3, RttV)));\ +acc128 = OP(tmp128,acc128);\ +acc128 = fSHIFTR128(acc128, 31);\ +acc64 = fCAST16S_8S(acc128);\ +RdV = fSATW(acc64);\ +}) + + +CMPY128(wcmpyrw, "cmpyrw", "Rtt32", 0, 0, 1, 1, fSUB128) +CMPY128(wcmpyrwc, "cmpyrw", "Rtt32*", 0, 0, 1, 1, fADD128) +CMPY128(wcmpyiw, "cmpyiw", "Rtt32", 0, 1, 1, 0, fADD128) +CMPY128(wcmpyiwc, "cmpyiw", "Rtt32*", 1, 0, 0, 1, fSUB128) + + +#define CMPY128RND(TAG, NAME, OPERAND1, WORD0, WORD1, WORD2, WORD3, OP) \ +Q6INSN(M7_##TAG##_rnd,"Rd32=" NAME "(Rss32,"OPERAND1"):<<1:rnd:sat",ATTRIBS(A_RESTRICT_SLOT3ONLY),"Complex Multiply 32-bit result real", \ +{ \ +fHIDE(size16s_t acc128;)\ +fHIDE(size16s_t tmp128;)\ +fHIDE(size16s_t const128;)\ +fHIDE(size8s_t acc64;)\ +tmp128 = fCAST8S_16S(fMPY32SS(fGETWORD(WORD0, RssV), fGETWORD(WORD1, RttV)));\ +acc128 = fCAST8S_16S(fMPY32SS(fGETWORD(WORD2, RssV), fGETWORD(WORD3, RttV)));\ +const128 = fCAST8S_16S(fCONSTLL(0x40000000));\ +acc128 = OP(tmp128,acc128);\ +acc128 = fADD128(acc128,const128);\ +acc128 = fSHIFTR128(acc128, 31);\ +acc64 = fCAST16S_8S(acc128);\ +RdV = fSATW(acc64);\ +}) + +CMPY128RND(wcmpyrw, "cmpyrw", "Rtt32", 0, 0, 1, 1, fSUB128) +CMPY128RND(wcmpyrwc, "cmpyrw", "Rtt32*", 0, 0, 1, 1, fADD128) +CMPY128RND(wcmpyiw, "cmpyiw", "Rtt32", 0, 1, 1, 0, fADD128) +CMPY128RND(wcmpyiwc, "cmpyiw", "Rtt32*", 1, 0, 0, 1, fSUB128) diff --git a/target/hexagon/imported/shift.idef b/target/hexagon/imported/shift.idef new file mode 100644 index 0000000000..e328ab7329 --- /dev/null +++ b/target/hexagon/imported/shift.idef @@ -0,0 +1,1066 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * S-type Instructions + */ + +/**********************************************/ +/* SHIFTS */ +/**********************************************/ + +/* NOTE: Rdd = Rs *right* shifts don't make sense */ +/* NOTE: Rd[d] = Rs[s] *right* shifts with saturation don't make sense */ + + +#define RSHIFTTYPES(TAGEND,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT,ATTRS) \ +Q6INSN(S2_asr_r_##TAGEND,#REGD "32" #ACC "=asr(" #REGS "32,Rt32)" #SATOPT,ATTRIBS(ATTRS), \ + "Arithmetic Shift Right by Register", \ + { \ + fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\ + REGD##V = SAT(ACCSRC ACC fBIDIR_ASHIFTR(REGS##V,shamt,REGSTYPE)); \ + })\ +\ +Q6INSN(S2_asl_r_##TAGEND,#REGD "32" #ACC "=asl(" #REGS "32,Rt32)" #SATOPT,ATTRIBS(ATTRS), \ + "Arithmetic Shift Left by Register", \ + { \ + fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\ + REGD##V = SAT(ACCSRC ACC fBIDIR_ASHIFTL(REGS##V,shamt,REGSTYPE)); \ + })\ +\ +Q6INSN(S2_lsr_r_##TAGEND,#REGD "32" #ACC "=lsr(" #REGS "32,Rt32)" #SATOPT,ATTRIBS(ATTRS), \ + "Logical Shift Right by Register", \ + { \ + fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\ + REGD##V = SAT(ACCSRC ACC fBIDIR_LSHIFTR(REGS##V,shamt,REGSTYPE)); \ + })\ +\ +Q6INSN(S2_lsl_r_##TAGEND,#REGD "32" #ACC "=lsl(" #REGS "32,Rt32)" #SATOPT,ATTRIBS(ATTRS), \ + "Logical Shift Left by Register", \ + { \ + fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\ + REGD##V = SAT(ACCSRC ACC fBIDIR_LSHIFTL(REGS##V,shamt,REGSTYPE)); \ + }) + +RSHIFTTYPES(r,Rd,Rs,4_8,,,fECHO,,) +RSHIFTTYPES(p,Rdd,Rss,8_8,,,fECHO,,) +RSHIFTTYPES(r_acc,Rx,Rs,4_8,+,RxV,fECHO,,) +RSHIFTTYPES(p_acc,Rxx,Rss,8_8,+,RxxV,fECHO,,) +RSHIFTTYPES(r_nac,Rx,Rs,4_8,-,RxV,fECHO,,) +RSHIFTTYPES(p_nac,Rxx,Rss,8_8,-,RxxV,fECHO,,) + +RSHIFTTYPES(r_and,Rx,Rs,4_8,&,RxV,fECHO,,) +RSHIFTTYPES(r_or,Rx,Rs,4_8,|,RxV,fECHO,,) +RSHIFTTYPES(p_and,Rxx,Rss,8_8,&,RxxV,fECHO,,) +RSHIFTTYPES(p_or,Rxx,Rss,8_8,|,RxxV,fECHO,,) +RSHIFTTYPES(p_xor,Rxx,Rss,8_8,^,RxxV,fECHO,,) + + +#undef RSHIFTTYPES + +/* Register shift with saturation */ +#define RSATSHIFTTYPES(TAGEND,REGD,REGS,REGSTYPE) \ +Q6INSN(S2_asr_r_##TAGEND,#REGD "32" "=asr(" #REGS "32,Rt32):sat",ATTRIBS(), \ + "Arithmetic Shift Right by Register", \ + { \ + fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\ + REGD##V = fBIDIR_ASHIFTR_SAT(REGS##V,shamt,REGSTYPE); \ + })\ +\ +Q6INSN(S2_asl_r_##TAGEND,#REGD "32" "=asl(" #REGS "32,Rt32):sat",ATTRIBS(), \ + "Arithmetic Shift Left by Register", \ + { \ + fHIDE(size4s_t) shamt=fSXTN(7,32,RtV);\ + REGD##V = fBIDIR_ASHIFTL_SAT(REGS##V,shamt,REGSTYPE); \ + }) + +RSATSHIFTTYPES(r_sat,Rd,Rs,4_8) + + + + + +#define ISHIFTTYPES(TAGEND,SIZE,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT,ATTRS) \ +Q6INSN(S2_asr_i_##TAGEND,#REGD "32" #ACC "=asr(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(ATTRS), \ + "Arithmetic Shift Right by Immediate", \ + { REGD##V = SAT(ACCSRC ACC fASHIFTR(REGS##V,uiV,REGSTYPE)); }) \ +\ +Q6INSN(S2_lsr_i_##TAGEND,#REGD "32" #ACC "=lsr(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(ATTRS), \ + "Logical Shift Right by Immediate", \ + { REGD##V = SAT(ACCSRC ACC fLSHIFTR(REGS##V,uiV,REGSTYPE)); }) \ +\ +Q6INSN(S2_asl_i_##TAGEND,#REGD "32" #ACC "=asl(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(ATTRS), \ + "Shift Left by Immediate", \ + { REGD##V = SAT(ACCSRC ACC fASHIFTL(REGS##V,uiV,REGSTYPE)); }) \ +Q6INSN(S6_rol_i_##TAGEND,#REGD "32" #ACC "=rol(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(ATTRS), \ + "Rotate Left by Immediate", \ + { REGD##V = SAT(ACCSRC ACC fROTL(REGS##V,uiV,REGSTYPE)); }) + + +#define ISHIFTTYPES_ONLY_ASL(TAGEND,SIZE,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT) \ +Q6INSN(S2_asl_i_##TAGEND,#REGD "32" #ACC "=asl(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(), \ + "", \ + { REGD##V = SAT(ACCSRC ACC fASHIFTL(REGS##V,uiV,REGSTYPE)); }) + +#define ISHIFTTYPES_ONLY_ASR(TAGEND,SIZE,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT) \ +Q6INSN(S2_asr_i_##TAGEND,#REGD "32" #ACC "=asr(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(), \ + "", \ + { REGD##V = SAT(ACCSRC ACC fASHIFTR(REGS##V,uiV,REGSTYPE)); }) + + +#define ISHIFTTYPES_NOASR(TAGEND,SIZE,REGD,REGS,REGSTYPE,ACC,ACCSRC,SAT,SATOPT) \ +Q6INSN(S2_lsr_i_##TAGEND,#REGD "32" #ACC "=lsr(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(), \ + "Logical Shift Right by Register", \ + { REGD##V = SAT(ACCSRC ACC fLSHIFTR(REGS##V,uiV,REGSTYPE)); }) \ +Q6INSN(S2_asl_i_##TAGEND,#REGD "32" #ACC "=asl(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(), \ + "Shift Left by Register", \ + { REGD##V = SAT(ACCSRC ACC fASHIFTL(REGS##V,uiV,REGSTYPE)); }) \ +Q6INSN(S6_rol_i_##TAGEND,#REGD "32" #ACC "=rol(" #REGS "32,#u" #SIZE ")" #SATOPT,ATTRIBS(), \ + "Rotate Left by Immediate", \ + { REGD##V = SAT(ACCSRC ACC fROTL(REGS##V,uiV,REGSTYPE)); }) + + + +ISHIFTTYPES(r,5,Rd,Rs,4_4,,,fECHO,,) +ISHIFTTYPES(p,6,Rdd,Rss,8_8,,,fECHO,,) +ISHIFTTYPES(r_acc,5,Rx,Rs,4_4,+,RxV,fECHO,,) +ISHIFTTYPES(p_acc,6,Rxx,Rss,8_8,+,RxxV,fECHO,,) +ISHIFTTYPES(r_nac,5,Rx,Rs,4_4,-,RxV,fECHO,,) +ISHIFTTYPES(p_nac,6,Rxx,Rss,8_8,-,RxxV,fECHO,,) + +ISHIFTTYPES_NOASR(r_xacc,5,Rx,Rs,4_4,^, RxV,fECHO,) +ISHIFTTYPES_NOASR(p_xacc,6,Rxx,Rss,8_8,^, RxxV,fECHO,) + +ISHIFTTYPES(r_and,5,Rx,Rs,4_4,&,RxV,fECHO,,) +ISHIFTTYPES(r_or,5,Rx,Rs,4_4,|,RxV,fECHO,,) +ISHIFTTYPES(p_and,6,Rxx,Rss,8_8,&,RxxV,fECHO,,) +ISHIFTTYPES(p_or,6,Rxx,Rss,8_8,|,RxxV,fECHO,,) + +ISHIFTTYPES_ONLY_ASL(r_sat,5,Rd,Rs,4_8,,,fSAT,:sat) + + +Q6INSN(S2_asr_i_r_rnd,"Rd32=asr(Rs32,#u5):rnd",ATTRIBS(), + "Shift right with round", + { RdV = fASHIFTR(((fASHIFTR(RsV,uiV,4_8))+1),1,8_8); }) + + +Q6INSN(S2_asr_i_p_rnd,"Rdd32=asr(Rss32,#u6):rnd",ATTRIBS(), "Shift right with round", +{ fHIDE(size8u_t tmp;) + fHIDE(size8u_t rnd;) + tmp = fASHIFTR(RssV,uiV,8_8); + rnd = tmp & 1; + RddV = fASHIFTR(tmp,1,8_8) + rnd; }) + + +Q6INSN(S4_lsli,"Rd32=lsl(#s6,Rt32)",ATTRIBS(), "Shift an immediate left by register amount", +{ + fHIDE(size4s_t) shamt = fSXTN(7,32,RtV); + RdV = fBIDIR_LSHIFTL(siV,shamt,4_8); +}) + + + + +Q6INSN(S2_addasl_rrri,"Rd32=addasl(Rt32,Rs32,#u3)",ATTRIBS(), + "Shift left by small amount and add", + { RdV = RtV + fASHIFTL(RsV,uiV,4_4); }) + + + +#define SHIFTOPI(TAGEND,INNEROP,INNERSEM)\ +Q6INSN(S4_andi_##TAGEND,"Rx32=and(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)&INNERSEM;})\ +Q6INSN(S4_ori_##TAGEND, "Rx32=or(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)|INNERSEM;})\ +Q6INSN(S4_addi_##TAGEND,"Rx32=add(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)+INNERSEM;})\ +Q6INSN(S4_subi_##TAGEND,"Rx32=sub(#u8,"INNEROP")",,"Shift-op",{RxV=fIMMEXT(uiV)-INNERSEM;}) + + +SHIFTOPI(asl_ri,"asl(Rx32,#U5)",(RxV<>UiV)) + + +/**********************************************/ +/* PERMUTES */ +/**********************************************/ +Q6INSN(S2_valignib,"Rdd32=valignb(Rtt32,Rss32,#u3)", +ATTRIBS(), "Vector align bytes", +{ + RddV = (fLSHIFTR(RssV,uiV*8,8_8))|(fASHIFTL(RttV,((8-uiV)*8),8_8)); +}) + +Q6INSN(S2_valignrb,"Rdd32=valignb(Rtt32,Rss32,Pu4)", +ATTRIBS(), "Align with register", +{ RddV = fLSHIFTR(RssV,(PuV&0x7)*8,8_8)|(fASHIFTL(RttV,(8-(PuV&0x7))*8,8_8));}) + +Q6INSN(S2_vspliceib,"Rdd32=vspliceb(Rss32,Rtt32,#u3)", +ATTRIBS(), "Vector splice bytes", +{ RddV = fASHIFTL(RttV,uiV*8,8_8) | fZXTN(uiV*8,64,RssV); }) + +Q6INSN(S2_vsplicerb,"Rdd32=vspliceb(Rss32,Rtt32,Pu4)", +ATTRIBS(), "Splice with register", +{ RddV = fASHIFTL(RttV,(PuV&7)*8,8_8) | fZXTN((PuV&7)*8,64,RssV); }) + +Q6INSN(S2_vsplatrh,"Rdd32=vsplath(Rs32)", +ATTRIBS(), "Vector splat halfwords from register", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV, fGETHALF(0,RsV)); + } +}) + + +Q6INSN(S2_vsplatrb,"Rd32=vsplatb(Rs32)", +ATTRIBS(), "Vector splat bytes from register", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETBYTE(i,RdV, fGETBYTE(0,RsV)); + } +}) + +Q6INSN(S6_vsplatrbp,"Rdd32=vsplatb(Rs32)", +ATTRIBS(), "Vector splat bytes from register", +{ + fHIDE(int i;) + for (i=0;i<8;i++) { + fSETBYTE(i,RddV, fGETBYTE(0,RsV)); + } +}) + + + +/**********************************************/ +/* Insert/Extract[u] */ +/**********************************************/ + +Q6INSN(S2_insert,"Rx32=insert(Rs32,#u5,#U5)", +ATTRIBS(), "Insert bits", +{ + fHIDE(int) width=uiV; + fHIDE(int) offset=UiV; + /* clear bits in Rxx where new bits go */ + RxV &= ~(((fCONSTLL(1)<>uiV)); + fSETWORD(0,RddV,fZXTN(uiV,32,RsV)); +}) + +Q6INSN(A4_bitsplit,"Rdd32=bitsplit(Rs32,Rt32)", +ATTRIBS(), "Split a bitfield into two registers", +{ + fHIDE(size4u_t) shamt = fZXTN(5,32,RtV); + fSETWORD(1,RddV,(fCAST4_4u(RsV)>>shamt)); + fSETWORD(0,RddV,fZXTN(shamt,32,RsV)); +}) + + + + +Q6INSN(S4_extract,"Rd32=extract(Rs32,#u5,#U5)", +ATTRIBS(), "Extract signed bitfield", +{ + fHIDE(int) width=uiV; + fHIDE(int) offset=UiV; + RdV = fSXTN(width,32,(fCAST4_4u(RsV) >> offset)); +}) + + +Q6INSN(S2_extractu,"Rd32=extractu(Rs32,#u5,#U5)", +ATTRIBS(), "Extract unsigned bitfield", +{ + fHIDE(int) width=uiV; + fHIDE(int) offset=UiV; + RdV = fZXTN(width,32,(fCAST4_4u(RsV) >> offset)); +}) + +Q6INSN(S2_insertp,"Rxx32=insert(Rss32,#u6,#U6)", +ATTRIBS(), "Insert bits", +{ + fHIDE(int) width=uiV; + fHIDE(int) offset=UiV; + /* clear bits in Rxx where new bits go */ + RxxV &= ~(((fCONSTLL(1)<> offset)); +}) + + +Q6INSN(S2_extractup,"Rdd32=extractu(Rss32,#u6,#U6)", +ATTRIBS(), "Extract unsigned bitfield", +{ + fHIDE(int) width=uiV; + fHIDE(int) offset=UiV; + RddV = fZXTN(width,64,(fCAST8_8u(RssV) >> offset)); +}) + + + + +Q6INSN(S2_mask,"Rd32=mask(#u5,#U5)", +ATTRIBS(), "Form mask from immediate", +{ + RdV = ((1<>uiV)); + } +}) + + +Q6INSN(S2_lsr_i_vh,"Rdd32=vlsrh(Rss32,#u4)",ATTRIBS(), + "Vector Logical Shift Right by Immediate", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV, (fGETUHALF(i,RssV)>>uiV)); + } +}) + +Q6INSN(S2_asl_i_vh,"Rdd32=vaslh(Rss32,#u4)",ATTRIBS(), + "Vector Arithmetic Shift Left by Immediate", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV, (fGETHALF(i,RssV)<> uiV )+1)>>1 )); + } +}) + +Q6INSN(S5_asrhub_sat,"Rd32=vasrhub(Rss32,#u4):sat",, + "Vector Arithmetic Shift Right by Immediate with Saturate and Pack", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETBYTE(i,RdV, fSATUB( fGETHALF(i,RssV) >> uiV )); + } +}) + + + +Q6INSN(S5_vasrhrnd,"Rdd32=vasrh(Rss32,#u4):raw",, + "Vector Arithmetic Shift Right by Immediate with Round", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV, ( ((fGETHALF(i,RssV) >> uiV)+1)>>1 )); + } +}) + + +Q6INSN(S2_asl_r_vh,"Rdd32=vaslh(Rss32,Rt32)",ATTRIBS(), + "Vector Arithmetic Shift Left by Register", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV, fBIDIR_ASHIFTL(fGETHALF(i,RssV),fSXTN(7,32,RtV),2_8)); + } +}) + + + +Q6INSN(S2_lsr_r_vh,"Rdd32=vlsrh(Rss32,Rt32)",ATTRIBS(), + "Vector Logical Shift Right by Register", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV, fBIDIR_LSHIFTR(fGETUHALF(i,RssV),fSXTN(7,32,RtV),2_8)); + } +}) + + +Q6INSN(S2_lsl_r_vh,"Rdd32=vlslh(Rss32,Rt32)",ATTRIBS(), + "Vector Logical Shift Left by Register", +{ + fHIDE(int i;) + for (i=0;i<4;i++) { + fSETHALF(i,RddV, fBIDIR_LSHIFTL(fGETUHALF(i,RssV),fSXTN(7,32,RtV),2_8)); + } +}) + + + + +/* Word Vector Immediate Shifts */ + +Q6INSN(S2_asr_i_vw,"Rdd32=vasrw(Rss32,#u5)",ATTRIBS(), + "Vector Arithmetic Shift Right by Immediate", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,(fGETWORD(i,RssV)>>uiV)); + } +}) + + + +Q6INSN(S2_asr_i_svw_trun,"Rd32=vasrw(Rss32,#u5)",ATTRIBS(A_ARCHV2), + "Vector Arithmetic Shift Right by Immediate with Truncate and Pack", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,fGETHALF(0,(fGETWORD(i,RssV)>>uiV))); + } +}) + +Q6INSN(S2_asr_r_svw_trun,"Rd32=vasrw(Rss32,Rt32)",ATTRIBS(A_ARCHV2), + "Vector Arithmetic Shift Right truncate and Pack", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETHALF(i,RdV,fGETHALF(0,fBIDIR_ASHIFTR(fGETWORD(i,RssV),fSXTN(7,32,RtV),4_8))); + } +}) + + +Q6INSN(S2_lsr_i_vw,"Rdd32=vlsrw(Rss32,#u5)",ATTRIBS(), + "Vector Logical Shift Right by Immediate", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,(fGETUWORD(i,RssV)>>uiV)); + } +}) + +Q6INSN(S2_asl_i_vw,"Rdd32=vaslw(Rss32,#u5)",ATTRIBS(), + "Vector Arithmetic Shift Left by Immediate", +{ + fHIDE(int i;) + for (i=0;i<2;i++) { + fSETWORD(i,RddV,(fGETWORD(i,RssV)<> 1) | (fCAST8u((1&fCOUNTONES_8(RssV & RttV)))<<63) ; }) + +Q6INSN(S2_clbnorm,"Rd32=normamt(Rs32)",ATTRIBS(A_ARCHV2), +"Count leading sign bits - 1", { if (RsV == 0) { RdV = 0; } else { RdV = (fMAX(fCL1_4(RsV),fCL1_4(~RsV)))-1;} }) + +Q6INSN(S4_clbaddi,"Rd32=add(clb(Rs32),#s6)",ATTRIBS(A_ARCHV2), +"Count leading sign bits then add signed number", +{ RdV = (fMAX(fCL1_4(RsV),fCL1_4(~RsV)))+siV;} ) + +Q6INSN(S4_clbpnorm,"Rd32=normamt(Rss32)",ATTRIBS(A_ARCHV2), +"Count leading sign bits - 1", { if (RssV == 0) { RdV = 0; } +else { RdV = (fMAX(fCL1_8(RssV),fCL1_8(~RssV)))-1;}}) + +Q6INSN(S4_clbpaddi,"Rd32=add(clb(Rss32),#s6)",ATTRIBS(A_ARCHV2), +"Count leading sign bits then add signed number", +{ RdV = (fMAX(fCL1_8(RssV),fCL1_8(~RssV)))+siV;}) + + +Q6INSN(S2_clb,"Rd32=clb(Rs32)",ATTRIBS(), +"Count leading bits", {RdV = fMAX(fCL1_4(RsV),fCL1_4(~RsV));}) + + +Q6INSN(S2_cl0,"Rd32=cl0(Rs32)",ATTRIBS(), +"Count leading bits", {RdV = fCL1_4(~RsV);}) + +Q6INSN(S2_cl1,"Rd32=cl1(Rs32)",ATTRIBS(), +"Count leading bits", {RdV = fCL1_4(RsV);}) + +Q6INSN(S2_clbp,"Rd32=clb(Rss32)",ATTRIBS(), +"Count leading bits", {RdV = fMAX(fCL1_8(RssV),fCL1_8(~RssV));}) + +Q6INSN(S2_cl0p,"Rd32=cl0(Rss32)",ATTRIBS(), +"Count leading bits", {RdV = fCL1_8(~RssV);}) + +Q6INSN(S2_cl1p,"Rd32=cl1(Rss32)",ATTRIBS(), +"Count leading bits", {RdV = fCL1_8(RssV);}) + + + + +Q6INSN(S2_brev, "Rd32=brev(Rs32)", ATTRIBS(A_ARCHV2), "Bit Reverse",{RdV = fBREV_4(RsV);}) +Q6INSN(S2_brevp,"Rdd32=brev(Rss32)", ATTRIBS(), "Bit Reverse",{RddV = fBREV_8(RssV);}) +Q6INSN(S2_ct0, "Rd32=ct0(Rs32)", ATTRIBS(A_ARCHV2), "Count Trailing",{RdV = fCL1_4(~fBREV_4(RsV));}) +Q6INSN(S2_ct1, "Rd32=ct1(Rs32)", ATTRIBS(A_ARCHV2), "Count Trailing",{RdV = fCL1_4(fBREV_4(RsV));}) +Q6INSN(S2_ct0p, "Rd32=ct0(Rss32)", ATTRIBS(), "Count Trailing",{RdV = fCL1_8(~fBREV_8(RssV));}) +Q6INSN(S2_ct1p, "Rd32=ct1(Rss32)", ATTRIBS(), "Count Trailing",{RdV = fCL1_8(fBREV_8(RssV));}) + + +Q6INSN(S2_interleave,"Rdd32=interleave(Rss32)",ATTRIBS(A_ARCHV2),"Interleave bits", +{RddV = fINTERLEAVE(fGETWORD(1,RssV),fGETWORD(0,RssV));}) + +Q6INSN(S2_deinterleave,"Rdd32=deinterleave(Rss32)",ATTRIBS(A_ARCHV2),"Interleave bits", +{RddV = fDEINTERLEAVE(RssV);}) diff --git a/target/hexagon/imported/subinsns.idef b/target/hexagon/imported/subinsns.idef new file mode 100644 index 0000000000..ec1c74f479 --- /dev/null +++ b/target/hexagon/imported/subinsns.idef @@ -0,0 +1,149 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * sub-instructions + */ + + + +/*****************************************************************/ +/* */ +/* A-type subinsns */ +/* */ +/*****************************************************************/ + +Q6INSN(SA1_addi, "Rx16=add(Rx16,#s7)", ATTRIBS(A_SUBINSN),"Add", { fIMMEXT(siV); RxV=RxV+siV;}) +Q6INSN(SA1_tfr, "Rd16=Rs16", ATTRIBS(A_SUBINSN),"Tfr", { RdV=RsV;}) +Q6INSN(SA1_seti, "Rd16=#u6", ATTRIBS(A_SUBINSN),"Set immed", { fIMMEXT(uiV); RdV=uiV;}) +Q6INSN(SA1_setin1, "Rd16=#-1", ATTRIBS(A_SUBINSN),"Set to -1", { RdV=-1;}) +Q6INSN(SA1_clrtnew, "if (p0.new) Rd16=#0", ATTRIBS(A_SUBINSN),"clear if true", { if (fLSBNEW0) {RdV=0;} else {CANCEL;} }) +Q6INSN(SA1_clrfnew, "if (!p0.new) Rd16=#0", ATTRIBS(A_SUBINSN),"clear if false",{ if (fLSBNEW0NOT) {RdV=0;} else {CANCEL;} }) +Q6INSN(SA1_clrt, "if (p0) Rd16=#0", ATTRIBS(A_SUBINSN),"clear if true", { if (fLSBOLD(fREAD_P0())) {RdV=0;} else {CANCEL;} }) +Q6INSN(SA1_clrf, "if (!p0) Rd16=#0", ATTRIBS(A_SUBINSN),"clear if false",{ if (fLSBOLDNOT(fREAD_P0())) {RdV=0;} else {CANCEL;} }) + +Q6INSN(SA1_addsp, "Rd16=add(r29,#u6:2)", ATTRIBS(A_SUBINSN),"Add", { RdV=fREAD_SP()+uiV; }) +Q6INSN(SA1_inc, "Rd16=add(Rs16,#1)", ATTRIBS(A_SUBINSN),"Inc", { RdV=RsV+1;}) +Q6INSN(SA1_dec, "Rd16=add(Rs16,#-1)", ATTRIBS(A_SUBINSN),"Dec", { RdV=RsV-1;}) +Q6INSN(SA1_addrx, "Rx16=add(Rx16,Rs16)", ATTRIBS(A_SUBINSN),"Add", { RxV=RxV+RsV; }) +Q6INSN(SA1_zxtb, "Rd16=and(Rs16,#255)", ATTRIBS(A_SUBINSN),"Zxtb", { RdV= fZXTN(8,32,RsV);}) +Q6INSN(SA1_and1, "Rd16=and(Rs16,#1)", ATTRIBS(A_SUBINSN),"And #1", { RdV= RsV&1;}) +Q6INSN(SA1_sxtb, "Rd16=sxtb(Rs16)", ATTRIBS(A_SUBINSN),"Sxtb", { RdV= fSXTN(8,32,RsV);}) +Q6INSN(SA1_zxth, "Rd16=zxth(Rs16)", ATTRIBS(A_SUBINSN),"Zxth", { RdV= fZXTN(16,32,RsV);}) +Q6INSN(SA1_sxth, "Rd16=sxth(Rs16)", ATTRIBS(A_SUBINSN),"Sxth", { RdV= fSXTN(16,32,RsV);}) +Q6INSN(SA1_combinezr,"Rdd8=combine(#0,Rs16)", ATTRIBS(A_SUBINSN),"Combines", { fSETWORD(0,RddV,RsV); fSETWORD(1,RddV,0); }) +Q6INSN(SA1_combinerz,"Rdd8=combine(Rs16,#0)", ATTRIBS(A_SUBINSN),"Combines", { fSETWORD(0,RddV,0); fSETWORD(1,RddV,RsV); }) +Q6INSN(SA1_combine0i,"Rdd8=combine(#0,#u2)", ATTRIBS(A_SUBINSN),"Combines", { fSETWORD(0,RddV,uiV); fSETWORD(1,RddV,0); }) +Q6INSN(SA1_combine1i,"Rdd8=combine(#1,#u2)", ATTRIBS(A_SUBINSN),"Combines", { fSETWORD(0,RddV,uiV); fSETWORD(1,RddV,1); }) +Q6INSN(SA1_combine2i,"Rdd8=combine(#2,#u2)", ATTRIBS(A_SUBINSN),"Combines", { fSETWORD(0,RddV,uiV); fSETWORD(1,RddV,2); }) +Q6INSN(SA1_combine3i,"Rdd8=combine(#3,#u2)", ATTRIBS(A_SUBINSN),"Combines", { fSETWORD(0,RddV,uiV); fSETWORD(1,RddV,3); }) +Q6INSN(SA1_cmpeqi, "p0=cmp.eq(Rs16,#u2)", ATTRIBS(A_SUBINSN),"CompareImmed",{fWRITE_P0(f8BITSOF(RsV==uiV));}) + + + + +/*****************************************************************/ +/* */ +/* Ld1/2 subinsns */ +/* */ +/*****************************************************************/ + +Q6INSN(SL1_loadri_io, "Rd16=memw(Rs16+#u4:2)", ATTRIBS(A_LOAD,A_SUBINSN),"load word", {fEA_RI(RsV,uiV); fLOAD(1,4,u,EA,RdV);}) +Q6INSN(SL1_loadrub_io, "Rd16=memub(Rs16+#u4:0)",ATTRIBS(A_LOAD,A_SUBINSN),"load byte", {fEA_RI(RsV,uiV); fLOAD(1,1,u,EA,RdV);}) + +Q6INSN(SL2_loadrh_io, "Rd16=memh(Rs16+#u3:1)", ATTRIBS(A_LOAD,A_SUBINSN),"load half", {fEA_RI(RsV,uiV); fLOAD(1,2,s,EA,RdV);}) +Q6INSN(SL2_loadruh_io, "Rd16=memuh(Rs16+#u3:1)",ATTRIBS(A_LOAD,A_SUBINSN),"load half", {fEA_RI(RsV,uiV); fLOAD(1,2,u,EA,RdV);}) +Q6INSN(SL2_loadrb_io, "Rd16=memb(Rs16+#u3:0)", ATTRIBS(A_LOAD,A_SUBINSN),"load byte", {fEA_RI(RsV,uiV); fLOAD(1,1,s,EA,RdV);}) +Q6INSN(SL2_loadri_sp, "Rd16=memw(r29+#u5:2)", ATTRIBS(A_LOAD,A_SUBINSN),"load word", {fEA_RI(fREAD_SP(),uiV); fLOAD(1,4,u,EA,RdV);}) +Q6INSN(SL2_loadrd_sp, "Rdd8=memd(r29+#u5:3)", ATTRIBS(A_LOAD,A_SUBINSN),"load dword",{fEA_RI(fREAD_SP(),uiV); fLOAD(1,8,u,EA,RddV);}) + +Q6INSN(SL2_deallocframe,"deallocframe", ATTRIBS(A_SUBINSN,A_LOAD), "Deallocate stack frame", +{ fHIDE(size8u_t tmp;) fEA_REG(fREAD_FP()); + fLOAD(1,8,u,EA,tmp); + tmp = fFRAME_UNSCRAMBLE(tmp); + fWRITE_LR(fGETWORD(1,tmp)); + fWRITE_FP(fGETWORD(0,tmp)); + fWRITE_SP(EA+8); }) + +Q6INSN(SL2_return,"dealloc_return", ATTRIBS(A_JINDIR,A_SUBINSN,A_LOAD,A_RETURN,A_RESTRICT_SLOT0ONLY), "Deallocate stack frame and return", +{ fHIDE(size8u_t tmp;) fEA_REG(fREAD_FP()); + fLOAD(1,8,u,EA,tmp); + tmp = fFRAME_UNSCRAMBLE(tmp); + fWRITE_LR(fGETWORD(1,tmp)); + fWRITE_FP(fGETWORD(0,tmp)); + fWRITE_SP(EA+8); + fJUMPR(REG_LR,fGETWORD(1,tmp),COF_TYPE_JUMPR);}) + +Q6INSN(SL2_return_t,"if (p0) dealloc_return", ATTRIBS(A_JINDIROLD,A_SUBINSN,A_LOAD,A_RETURN,A_RESTRICT_SLOT0ONLY), "Deallocate stack frame and return", +{ fHIDE(size8u_t tmp;); fBRANCH_SPECULATE_STALL(fLSBOLD(fREAD_P0()),, SPECULATE_NOT_TAKEN,4,0); fEA_REG(fREAD_FP()); if (fLSBOLD(fREAD_P0())) { fLOAD(1,8,u,EA,tmp); tmp = fFRAME_UNSCRAMBLE(tmp); fWRITE_LR(fGETWORD(1,tmp)); fWRITE_FP(fGETWORD(0,tmp)); fWRITE_SP(EA+8); + fJUMPR(REG_LR,fGETWORD(1,tmp),COF_TYPE_JUMPR);} else {LOAD_CANCEL(EA);} }) + +Q6INSN(SL2_return_f,"if (!p0) dealloc_return", ATTRIBS(A_JINDIROLD,A_SUBINSN,A_LOAD,A_RETURN,A_RESTRICT_SLOT0ONLY), "Deallocate stack frame and return", +{ fHIDE(size8u_t tmp;);fBRANCH_SPECULATE_STALL(fLSBOLDNOT(fREAD_P0()),, SPECULATE_NOT_TAKEN,4,0); fEA_REG(fREAD_FP()); if (fLSBOLDNOT(fREAD_P0())) { fLOAD(1,8,u,EA,tmp); tmp = fFRAME_UNSCRAMBLE(tmp); fWRITE_LR(fGETWORD(1,tmp)); fWRITE_FP(fGETWORD(0,tmp)); fWRITE_SP(EA+8); + fJUMPR(REG_LR,fGETWORD(1,tmp),COF_TYPE_JUMPR);} else {LOAD_CANCEL(EA);} }) + + + +Q6INSN(SL2_return_tnew,"if (p0.new) dealloc_return:nt", ATTRIBS(A_JINDIRNEW,A_SUBINSN,A_LOAD,A_RETURN,A_RESTRICT_SLOT0ONLY), "Deallocate stack frame and return", +{ fHIDE(size8u_t tmp;) fBRANCH_SPECULATE_STALL(fLSBNEW0,, SPECULATE_NOT_TAKEN , 4,3); fEA_REG(fREAD_FP()); if (fLSBNEW0) { fLOAD(1,8,u,EA,tmp); tmp = fFRAME_UNSCRAMBLE(tmp); fWRITE_LR(fGETWORD(1,tmp)); fWRITE_FP(fGETWORD(0,tmp)); fWRITE_SP(EA+8); + fJUMPR(REG_LR,fGETWORD(1,tmp),COF_TYPE_JUMPR);} else {LOAD_CANCEL(EA);} }) + +Q6INSN(SL2_return_fnew,"if (!p0.new) dealloc_return:nt", ATTRIBS(A_JINDIRNEW,A_SUBINSN,A_LOAD,A_RETURN,A_RESTRICT_SLOT0ONLY), "Deallocate stack frame and return", +{ fHIDE(size8u_t tmp;) fBRANCH_SPECULATE_STALL(fLSBNEW0NOT,, SPECULATE_NOT_TAKEN , 4,3); fEA_REG(fREAD_FP()); if (fLSBNEW0NOT) { fLOAD(1,8,u,EA,tmp); tmp = fFRAME_UNSCRAMBLE(tmp); fWRITE_LR(fGETWORD(1,tmp)); fWRITE_FP(fGETWORD(0,tmp)); fWRITE_SP(EA+8); + fJUMPR(REG_LR,fGETWORD(1,tmp),COF_TYPE_JUMPR);} else {LOAD_CANCEL(EA);} }) + + +Q6INSN(SL2_jumpr31,"jumpr r31",ATTRIBS(A_SUBINSN,A_JINDIR,A_RESTRICT_SLOT0ONLY),"indirect unconditional jump", +{ fJUMPR(REG_LR,fREAD_LR(),COF_TYPE_JUMPR);}) + +Q6INSN(SL2_jumpr31_t,"if (p0) jumpr r31",ATTRIBS(A_SUBINSN,A_JINDIROLD,A_RESTRICT_SLOT0ONLY),"indirect conditional jump if true", +{fBRANCH_SPECULATE_STALL(fLSBOLD(fREAD_P0()),, SPECULATE_TAKEN,4,0); if (fLSBOLD(fREAD_P0())) {fJUMPR(REG_LR,fREAD_LR(),COF_TYPE_JUMPR);}}) + +Q6INSN(SL2_jumpr31_f,"if (!p0) jumpr r31",ATTRIBS(A_SUBINSN,A_JINDIROLD,A_RESTRICT_SLOT0ONLY),"indirect conditional jump if false", +{fBRANCH_SPECULATE_STALL(fLSBOLDNOT(fREAD_P0()),, SPECULATE_TAKEN,4,0); if (fLSBOLDNOT(fREAD_P0())) {fJUMPR(REG_LR,fREAD_LR(),COF_TYPE_JUMPR);}}) + + + +Q6INSN(SL2_jumpr31_tnew,"if (p0.new) jumpr:nt r31",ATTRIBS(A_SUBINSN,A_JINDIRNEW,A_RESTRICT_SLOT0ONLY),"indirect conditional jump if true", +{fBRANCH_SPECULATE_STALL(fLSBNEW0,, SPECULATE_NOT_TAKEN , 4,3); if (fLSBNEW0) {fJUMPR(REG_LR,fREAD_LR(),COF_TYPE_JUMPR);}}) + +Q6INSN(SL2_jumpr31_fnew,"if (!p0.new) jumpr:nt r31",ATTRIBS(A_SUBINSN,A_JINDIRNEW,A_RESTRICT_SLOT0ONLY),"indirect conditional jump if false", +{fBRANCH_SPECULATE_STALL(fLSBNEW0NOT,, SPECULATE_NOT_TAKEN , 4,3); if (fLSBNEW0NOT) {fJUMPR(REG_LR,fREAD_LR(),COF_TYPE_JUMPR);}}) + + + + + +/*****************************************************************/ +/* */ +/* St1/2 subinsns */ +/* */ +/*****************************************************************/ + +Q6INSN(SS1_storew_io, "memw(Rs16+#u4:2)=Rt16", ATTRIBS(A_STORE,A_SUBINSN), "store word", {fEA_RI(RsV,uiV); fSTORE(1,4,EA,RtV);}) +Q6INSN(SS1_storeb_io, "memb(Rs16+#u4:0)=Rt16", ATTRIBS(A_STORE,A_SUBINSN), "store byte", {fEA_RI(RsV,uiV); fSTORE(1,1,EA,fGETBYTE(0,RtV));}) +Q6INSN(SS2_storeh_io, "memh(Rs16+#u3:1)=Rt16", ATTRIBS(A_STORE,A_SUBINSN), "store half", {fEA_RI(RsV,uiV); fSTORE(1,2,EA,fGETHALF(0,RtV));}) +Q6INSN(SS2_stored_sp, "memd(r29+#s6:3)=Rtt8", ATTRIBS(A_STORE,A_SUBINSN), "store dword",{fEA_RI(fREAD_SP(),siV); fSTORE(1,8,EA,RttV);}) +Q6INSN(SS2_storew_sp, "memw(r29+#u5:2)=Rt16", ATTRIBS(A_STORE,A_SUBINSN), "store word", {fEA_RI(fREAD_SP(),uiV); fSTORE(1,4,EA,RtV);}) +Q6INSN(SS2_storewi0, "memw(Rs16+#u4:2)=#0", ATTRIBS(A_STORE,A_SUBINSN), "store word", {fEA_RI(RsV,uiV); fSTORE(1,4,EA,0);}) +Q6INSN(SS2_storebi0, "memb(Rs16+#u4:0)=#0", ATTRIBS(A_STORE,A_SUBINSN), "store byte", {fEA_RI(RsV,uiV); fSTORE(1,1,EA,0);}) +Q6INSN(SS2_storewi1, "memw(Rs16+#u4:2)=#1", ATTRIBS(A_STORE,A_SUBINSN), "store word", {fEA_RI(RsV,uiV); fSTORE(1,4,EA,1);}) +Q6INSN(SS2_storebi1, "memb(Rs16+#u4:0)=#1", ATTRIBS(A_STORE,A_SUBINSN), "store byte", {fEA_RI(RsV,uiV); fSTORE(1,1,EA,1);}) + + +Q6INSN(SS2_allocframe,"allocframe(#u5:3)", ATTRIBS(A_SUBINSN,A_STORE,A_RESTRICT_SLOT0ONLY), "Allocate stack frame", +{ fEA_RI(fREAD_SP(),-8); fSTORE(1,8,EA,fFRAME_SCRAMBLE((fCAST8_8u(fREAD_LR()) << 32) | fCAST4_4u(fREAD_FP()))); fWRITE_FP(EA); fFRAMECHECK(EA-uiV,EA); fWRITE_SP(EA-uiV); }) diff --git a/target/hexagon/imported/system.idef b/target/hexagon/imported/system.idef new file mode 100644 index 0000000000..7c6568e75e --- /dev/null +++ b/target/hexagon/imported/system.idef @@ -0,0 +1,68 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * System Interface Instructions + */ + + + +/********************************************/ +/* User->OS interface */ +/********************************************/ + +Q6INSN(J2_trap0,"trap0(#u8)",ATTRIBS(A_COF), +"Trap to Operating System", + fTRAP(0,uiV); +) + +Q6INSN(J2_pause,"pause(#u8)",ATTRIBS(A_COF), +"Enter low-power state for #u8 cycles",{fPAUSE(uiV);}) + +Q6INSN(Y2_icinva,"icinva(Rs32)",ATTRIBS(A_ICOP,A_ICFLUSHOP),"Instruction Cache Invalidate Address",{fEA_REG(RsV); fICINVA(EA);}) + +Q6INSN(Y2_isync,"isync",ATTRIBS(),"Memory Synchronization",{fISYNC();}) +Q6INSN(Y2_barrier,"barrier",ATTRIBS(A_RESTRICT_SLOT0ONLY),"Memory Barrier",{fBARRIER();}) +Q6INSN(Y2_syncht,"syncht",ATTRIBS(A_RESTRICT_SLOT0ONLY),"Memory Synchronization",{fSYNCH();}) + + +Q6INSN(Y2_dcfetchbo,"dcfetch(Rs32+#u11:3)",ATTRIBS(A_RESTRICT_PREFERSLOT0,A_DCFETCH),"Data Cache Prefetch",{fEA_RI(RsV,uiV); fDCFETCH(EA);}) + + +Q6INSN(Y2_dczeroa,"dczeroa(Rs32)",ATTRIBS(A_STORE,A_RESTRICT_SLOT0ONLY,A_DCZEROA),"Zero an aligned 32-byte cacheline",{fEA_REG(RsV); fDCZEROA(EA);}) +Q6INSN(Y2_dccleana,"dccleana(Rs32)",ATTRIBS(A_RESTRICT_SLOT0ONLY,A_DCFLUSHOP),"Data Cache Clean Address",{fEA_REG(RsV); fDCCLEANA(EA);}) +Q6INSN(Y2_dccleaninva,"dccleaninva(Rs32)",ATTRIBS(A_RESTRICT_SLOT0ONLY,A_DCFLUSHOP),"Data Cache Clean and Invalidate Address",{fEA_REG(RsV); fDCCLEANINVA(EA);}) +Q6INSN(Y2_dcinva,"dcinva(Rs32)",ATTRIBS(A_RESTRICT_SLOT0ONLY,A_DCFLUSHOP),"Data Cache Invalidate Address",{fEA_REG(RsV); fDCCLEANINVA(EA);}) + + +Q6INSN(Y4_l2fetch,"l2fetch(Rs32,Rt32)",ATTRIBS(A_RESTRICT_SLOT0ONLY),"L2 Cache Prefetch", +{ fL2FETCH(RsV, + (RtV&0xff), /*height*/ + ((RtV>>8)&0xff), /*width*/ + ((RtV>>16)&0xffff), /*stride*/ + 0); /*extra attrib flags*/ +}) + + + +Q6INSN(Y5_l2fetch,"l2fetch(Rs32,Rtt32)",ATTRIBS(A_RESTRICT_SLOT0ONLY),"L2 Cache Prefetch", +{ fL2FETCH(RsV, + fGETUHALF(0,RttV), /*height*/ + fGETUHALF(1,RttV), /*width*/ + fGETUHALF(2,RttV), /*stride*/ + fGETUHALF(3,RttV)); /*flags*/ +}) From patchwork Wed Feb 17 23:40:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384179 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3225903jao; Wed, 17 Feb 2021 15:57:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJx5WxZh24+Cnz9IQoCasmjKCyF+dpF4WIcyHfATUoGWsUg9imf3XJxb7N3Mzy1K1+wqL6ci X-Received: by 2002:a25:824c:: with SMTP id d12mr2907591ybn.137.1613606260707; Wed, 17 Feb 2021 15:57:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606260; cv=none; d=google.com; s=arc-20160816; b=JsNVNDourDEpUXt6yETmbysy4brLWZ6jY6bsVe0/89yjOQxf2ZkWTtnfpD3hprDO69 yXpwG7xUhGsKwuOjrl9fpcXZN1S3Gr/TnrfxEE4JXamULHo388J1/XzJLzur9+WKeiCs VkOPOefOEeRWlRiinlUuHvgdvz3a3stR9tJcMmsAmXm+jmaOE7TP3mnI6zyAoIoairLn 7ildtJVqsmomeCJyDxFhJ2CWbA586v98tDhn6Sm5NV4rOYgESOLir10axNVXgozcmI2e J6ueOJ86zqc7TPvsVIpJfIFFz1qpt+QJTtyWAlJqBaWW4DRbZ4NcDUgjJTCJkMakctmU oAAw== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=wCQDJjv5dp1zQTdh7sTFK04v3fhiE0inPOMJx+iX1dA=; b=ApWI2/aVzEi10C+uEGqjO6iaxJVTqn5J+9KTzWOd3jSAyc5Av1wNx7dJ1Tu10Saf/5 Y9aNKhyFUkPODmDBMSmK1YftNzoAlRJcy8/KTeUrp0RRtdIItOyFzZ8PaPT2oFWm03pz 479XV0nkoQ01cW7SFaJszoOqEpkn2Oo5ZPbSAcwqnvXrFqVXDEjRrg0REd0EpAj4zfW3 8pJmkatsF2SKbl/UNtgY7tKvotJgYMHrNQtCRD0L5ho2egTCmSlVawtsxV+69iX/nzzL Bs9kPEvrXpdSG+wqp1G/XYPo9m0JFvcyZtpzlAgtYpBKqcVeWuSHf3KhTrHsXb7EIYU2 QFEQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="worM/Tbi"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id k3si3536303ybh.301.2021.02.17.15.57.40 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:57:40 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="worM/Tbi"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:55216 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWhQ-0003a1-2Z for patch@linaro.org; Wed, 17 Feb 2021 18:57:40 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51004) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRp-00018K-Tk for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:35 -0500 Received: from mail-pg1-x52b.google.com ([2607:f8b0:4864:20::52b]:38646) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRg-0004lb-Gc for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:33 -0500 Received: by mail-pg1-x52b.google.com with SMTP id m2so9526031pgq.5 for ; Wed, 17 Feb 2021 15:41:24 -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 :mime-version:content-transfer-encoding; bh=wCQDJjv5dp1zQTdh7sTFK04v3fhiE0inPOMJx+iX1dA=; b=worM/Tbigbf1l/K87YSNHmoSzFS6/Lv50RxjSiYN071gU/oau9iGbEzfJNSQlGt4PD CbELLvSn/GojjkNsygroIyGWaCZoiCKnuZaeORPj1UFx8qUTA7QZJwCC85F5iYeJiLaR nFau/oiRoHDvj3rPjZQeabIG5lYbh6LDOcYgj34kPWF0DCS3uvdX+Uy4DD93mziFvidv rAvfymK+dfp5rfMi+WKixj0DasRHXxLyw4Lgy0CGIEYA0m21N+3zLn3tZxboJq473O4S doupX0SxDNyj49VpL/qSzZdZmCLYa++mlYujDUN6ue+BL6zpA6shYmp7lqZcGzShIV5o kBCw== 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:mime-version:content-transfer-encoding; bh=wCQDJjv5dp1zQTdh7sTFK04v3fhiE0inPOMJx+iX1dA=; b=MoZy6AWfq1W0dH+iS2K+UecdMG9smyTAnaaw8bnjvguiyt5CCFRETk5xLjDvcaFQll PuEjezM2e27VacZLXOavZ23bal4wHVFgeqIESvNEx0rfZpP03OcOu9bk5iqWCtTmzrMS 3WHiH5fNxaDPtPSgUOjbffDomQlLs2JeLWspsSg5Kl7jr04BMwoTWEg2O5k/fWW4ti2S Bj3sQv8TT4rS/S3jhma+kbZvjpWGYjjZ1U+rSK3+y//Jbzm1ESGF3ZGt6WXyCmAIkuvT 57edr8VNjlcdPY4mn8nabm2ap6fjWSatlLN5S/31EEwe49atiIYjG2UFN0o3WjZ6OVvN y3Ew== X-Gm-Message-State: AOAM530bKgjMHqA5Lff5Yrxt13xTznIsAcmcAAUyrjh9lcGklIXTJhbO pmysQkmNM8btEmTRioxJksu8ME8To3qIHA== X-Received: by 2002:a62:6382:0:b029:1d2:46ed:d813 with SMTP id x124-20020a6263820000b02901d246edd813mr1475280pfb.44.1613605273575; Wed, 17 Feb 2021 15:41:13 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:13 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 20/35] Hexagon (target/hexagon) generator phase 1 - C preprocessor for semantics Date: Wed, 17 Feb 2021 15:40:08 -0800 Message-Id: <20210217234023.1742406-21-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52b; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Run the C preprocessor across the instruction definition files and macro definition file to expand macros and prepare the semantics_generated.pyinc file. The resulting file contains one entry with the semantics for each instruction and one line with the instruction attributes associated with each macro. Signed-off-by: Taylor Simpson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-20-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/gen_semantics.c | 88 ++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 target/hexagon/gen_semantics.c -- 2.25.1 diff --git a/target/hexagon/gen_semantics.c b/target/hexagon/gen_semantics.c new file mode 100644 index 0000000000..c5fccecc9e --- /dev/null +++ b/target/hexagon/gen_semantics.c @@ -0,0 +1,88 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * This program generates the semantics file that is processed by + * the do_qemu.py script. We use the C preporcessor to manipulate the + * files imported from the Hexagon architecture library. + */ + +#include +#define STRINGIZE(X) #X + +int main(int argc, char *argv[]) +{ + FILE *outfile; + + if (argc != 2) { + fprintf(stderr, "Usage: gen_semantics ouptputfile\n"); + return 1; + } + outfile = fopen(argv[1], "w"); + if (outfile == NULL) { + fprintf(stderr, "Cannot open %s for writing\n", argv[1]); + return 1; + } + +/* + * Process the instruction definitions + * Scalar core instructions have the following form + * Q6INSN(A2_add,"Rd32=add(Rs32,Rt32)",ATTRIBS(), + * "Add 32-bit registers", + * { RdV=RsV+RtV;}) + */ +#define Q6INSN(TAG, BEH, ATTRIBS, DESCR, SEM) \ + do { \ + fprintf(outfile, "SEMANTICS( \\\n" \ + " \"%s\", \\\n" \ + " %s, \\\n" \ + " \"\"\"%s\"\"\" \\\n" \ + ")\n", \ + #TAG, STRINGIZE(BEH), STRINGIZE(SEM)); \ + fprintf(outfile, "ATTRIBUTES( \\\n" \ + " \"%s\", \\\n" \ + " \"%s\" \\\n" \ + ")\n", \ + #TAG, STRINGIZE(ATTRIBS)); \ + } while (0); +#include "imported/allidefs.def" +#undef Q6INSN + +/* + * Process the macro definitions + * Macros definitions have the following form + * DEF_MACRO( + * fLSBNEW0, + * predlog_read(thread,0), + * () + * ) + * The important part here is the attributes. Whenever an instruction + * invokes a macro, we add the macro's attributes to the instruction. + */ +#define DEF_MACRO(MNAME, BEH, ATTRS) \ + fprintf(outfile, "MACROATTRIB( \\\n" \ + " \"%s\", \\\n" \ + " \"\"\"%s\"\"\", \\\n" \ + " \"%s\" \\\n" \ + ")\n", \ + #MNAME, STRINGIZE(BEH), STRINGIZE(ATTRS)); +#include "imported/macros.def" +#undef DEF_MACRO + + fclose(outfile); + return 0; +} From patchwork Wed Feb 17 23:40:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384027 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3222958jao; Wed, 17 Feb 2021 15:51:50 -0800 (PST) X-Google-Smtp-Source: ABdhPJzP0r5tzqmdoh2rsbA3WGR+uZbYB2Cc4apu7/HYKFYxi9QBXx/CuB3yJ4Uk83ZrXH+BHvoX X-Received: by 2002:a25:b206:: with SMTP id i6mr2713581ybj.499.1613605910662; Wed, 17 Feb 2021 15:51:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605910; cv=none; d=google.com; s=arc-20160816; b=Kb2yj/exLT9l2truOLfD94iorpZqMf8N0LTDqGCjSfT8OAuAmVg4V+A2hTb1xbw9Aj 4mjkL9lfUnHFymwXBR+T2uNMHMETPmY1+iLrd+WyarecZav+j2j4jLZ05ZtbMecFibkF K05JVmsSVPybQSQpIUUfxvldoziVdaVYqGSRG5pEPThoaS1vGh7BaCetJIIWP8C9dXOU ZbMndrz+MqTI/9rKiL+2Wm0ewN3UUIMByTsMhXGepuRG0b6ETS/5Ad3AQ6gE5b8eDVkZ 1r35y4Uo2rHbOBmRW9qXENJwf3FgUNdjgj8+cBJshSV+QxaNHjChmoEQq5HOxzPnvlyn T0zQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=BZYHnTZFbPkFROK+gKOOuSU33WSqb/WO2X72YmtxBd8=; b=Ccwg+Qy4JKneqCck2epM9OnJAfn9s6c0Ht/mzDlcvnrDO0yEKpEv9dOrCGqcV4lAUf rwx0jpV9sgvz1+5/GPAwaowbmRNbtAiVrEyswQCScu10eWyUlZFGIBCM37egTf+Cfr4C HHoc5aOg+n/hQZ2ZWkGmTvq7lGntpVjbi+mpn6CmDzO55glp7WVKJ28lUG6S4b0+Z0TW YVV+Eyx1TRD8V4rOM9JjH/vLR5PidpfCATL9fjWGF7ELyHOSnJflrsS62XtmzM+zZOWh WAynrmlDehb+6aEMrWLIy7bZnlhmkt1rKiBe8ZKdDGi7wSbDA+7m+a0MlMGKPdeiemoR dK8A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=tl53032U; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id a4si3540596ybk.217.2021.02.17.15.51.50 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:51:50 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=tl53032U; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:38560 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWbm-0004rO-25 for patch@linaro.org; Wed, 17 Feb 2021 18:51:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50962) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRk-000169-Cb for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:28 -0500 Received: from mail-pg1-x529.google.com ([2607:f8b0:4864:20::529]:42622) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRe-0004l5-9C for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:27 -0500 Received: by mail-pg1-x529.google.com with SMTP id o38so9502906pgm.9 for ; Wed, 17 Feb 2021 15:41:21 -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 :mime-version:content-transfer-encoding; bh=BZYHnTZFbPkFROK+gKOOuSU33WSqb/WO2X72YmtxBd8=; b=tl53032UkocvwEM9iAfmWd/h3z1Hw+l9hIlt2WCqpwqtmpHRJf3WseCPpO0xR1kA7z 1nGbdaELi2fF69BXA1OPVqRw1REz1rEQyPrDsupu+Oe6+AL0qpNPIZf6QIVFvDTEscpp oUjTQIvPEyCHXH1d9o6c2ShDp8klulkPF5TpuBBtVo+VhEY3Pluo3K6briMI7e+Qnh2j HgB+30M5f8l1BfRHi1KZieJKLhRk/juoII8TW4OWYr1XhsbcefBPQCq4SFODvWPla2PZ 6ofYvVAXHv9oBvUXBcLzZFX0g1j8P1VYtOOvJ30dgTg9zWQpS7FyG+Z/q7b5lJtkzJGh CdYw== 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:mime-version:content-transfer-encoding; bh=BZYHnTZFbPkFROK+gKOOuSU33WSqb/WO2X72YmtxBd8=; b=txaM6j95dSTTbGLVQ5IsH05KiC1Vcd+tcduT2eI60ZpJ6ais9Z4gbIGrj6U120OG/g zXnYfTAocMz8VDsAMp/Y+FS0uyz/A9I0ZUTC9bG/osAbL1q90QkJpWTPzhyIx0Hlvmzz CpJmLHNWDmZJEg5wh04YutyUMNg8mJrXZEmNZkCicXd+dxA8kNkWiwqAU8WbE/lE/GdX httiS8S7KzMvF7fgSe9wOJI4aWCR71ZAHqgZ2YE1CoCD9yE29dk14iUT9UyUtxyfe8Fh jnKJgnJD8sxG3T0vOooZgpN6iz3gYXnpAdUFthY0XFP3SJ/KBPBxLYhT8Jg1geNk2lPq N6cg== X-Gm-Message-State: AOAM533d5S0BSdaHzzGZ/hQCO9FVaQyp8OPDtuU1A5Y2K4fwd4OO7Sc+ 54bzhwGbphnplLz4+Rgq1MdyZBgXZ/N2UA== X-Received: by 2002:a62:ee09:0:b029:1c0:ba8c:fcea with SMTP id e9-20020a62ee090000b02901c0ba8cfceamr1529966pfi.7.1613605280176; Wed, 17 Feb 2021 15:41:20 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:19 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 21/35] Hexagon (target/hexagon) generator phase 2 - generate header files Date: Wed, 17 Feb 2021 15:40:09 -0800 Message-Id: <20210217234023.1742406-22-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::529; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x529.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Python scripts generate the following files helper_protos_generated.h.inc For each instruction we create DEF_HELPER function prototype helper_funcs_generated.c.inc For each instruction we create the helper function definition tcg_funcs_generated.c.inc For each instruction we create TCG code to generate call to helper tcg_func_table_generated.c.inc Table of function pointers indexed by opcode shortcode_generated.h.inc Generate a table of instruction "shortcode" semantics opcodes_def_generated.h.inc Gives a list of all the opcodes op_attribs_generated.h.inc Lists all the attributes associated with each instruction op_regs_generated.h.inc Lists the register and immediate operands for each instruction printinsn_generated.h.inc Data for printing (disassembling) each instruction (format string + operands) Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-21-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/gen_helper_funcs.py | 220 ++++++++++++ target/hexagon/gen_helper_protos.py | 150 +++++++++ target/hexagon/gen_op_attribs.py | 39 +++ target/hexagon/gen_op_regs.py | 110 ++++++ target/hexagon/gen_opcodes_def.py | 36 ++ target/hexagon/gen_printinsn.py | 173 ++++++++++ target/hexagon/gen_shortcode.py | 60 ++++ target/hexagon/gen_tcg_func_table.py | 58 ++++ target/hexagon/gen_tcg_funcs.py | 485 +++++++++++++++++++++++++++ target/hexagon/hex_common.py | 234 +++++++++++++ 10 files changed, 1565 insertions(+) create mode 100755 target/hexagon/gen_helper_funcs.py create mode 100755 target/hexagon/gen_helper_protos.py create mode 100755 target/hexagon/gen_op_attribs.py create mode 100755 target/hexagon/gen_op_regs.py create mode 100755 target/hexagon/gen_opcodes_def.py create mode 100755 target/hexagon/gen_printinsn.py create mode 100755 target/hexagon/gen_shortcode.py create mode 100755 target/hexagon/gen_tcg_func_table.py create mode 100755 target/hexagon/gen_tcg_funcs.py create mode 100755 target/hexagon/hex_common.py -- 2.25.1 diff --git a/target/hexagon/gen_helper_funcs.py b/target/hexagon/gen_helper_funcs.py new file mode 100755 index 0000000000..2b1c5d8e3e --- /dev/null +++ b/target/hexagon/gen_helper_funcs.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sys +import re +import string +import hex_common + +## +## Helpers for gen_helper_function +## +def gen_decl_ea(f): + f.write(" uint32_t EA;\n") + +def gen_helper_return_type(f,regtype,regid,regno): + if regno > 1 : f.write(", ") + f.write("int32_t") + +def gen_helper_return_type_pair(f,regtype,regid,regno): + if regno > 1 : f.write(", ") + f.write("int64_t") + +def gen_helper_arg(f,regtype,regid,regno): + if regno > 0 : f.write(", " ) + f.write("int32_t %s%sV" % (regtype,regid)) + +def gen_helper_arg_new(f,regtype,regid,regno): + if regno >= 0 : f.write(", " ) + f.write("int32_t %s%sN" % (regtype,regid)) + +def gen_helper_arg_pair(f,regtype,regid,regno): + if regno >= 0 : f.write(", ") + f.write("int64_t %s%sV" % (regtype,regid)) + +def gen_helper_arg_opn(f,regtype,regid,i,tag): + if (hex_common.is_pair(regid)): + gen_helper_arg_pair(f,regtype,regid,i) + elif (hex_common.is_single(regid)): + if hex_common.is_old_val(regtype, regid, tag): + gen_helper_arg(f,regtype,regid,i) + elif hex_common.is_new_val(regtype, regid, tag): + gen_helper_arg_new(f,regtype,regid,i) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + +def gen_helper_arg_imm(f,immlett): + f.write(", int32_t %s" % (hex_common.imm_name(immlett))) + +def gen_helper_dest_decl(f,regtype,regid,regno,subfield=""): + f.write(" int32_t %s%sV%s = 0;\n" % \ + (regtype,regid,subfield)) + +def gen_helper_dest_decl_pair(f,regtype,regid,regno,subfield=""): + f.write(" int64_t %s%sV%s = 0;\n" % \ + (regtype,regid,subfield)) + +def gen_helper_dest_decl_opn(f,regtype,regid,i): + if (hex_common.is_pair(regid)): + gen_helper_dest_decl_pair(f,regtype,regid,i) + elif (hex_common.is_single(regid)): + gen_helper_dest_decl(f,regtype,regid,i) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + +def gen_helper_return(f,regtype,regid,regno): + f.write(" return %s%sV;\n" % (regtype,regid)) + +def gen_helper_return_pair(f,regtype,regid,regno): + f.write(" return %s%sV;\n" % (regtype,regid)) + +def gen_helper_return_opn(f, regtype, regid, i): + if (hex_common.is_pair(regid)): + gen_helper_return_pair(f,regtype,regid,i) + elif (hex_common.is_single(regid)): + gen_helper_return(f,regtype,regid,i) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + +## +## Generate the TCG code to call the helper +## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;} +## We produce: +## int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV) +## { +## uint32_t slot __attribute__(unused)) = 4; +## int32_t RdV = 0; +## { RdV=RsV+RtV;} +## COUNT_HELPER(A2_add); +## return RdV; +## } +## +def gen_helper_function(f, tag, tagregs, tagimms): + regs = tagregs[tag] + imms = tagimms[tag] + + numresults = 0 + numscalarresults = 0 + numscalarreadwrite = 0 + for regtype,regid,toss,numregs in regs: + if (hex_common.is_written(regid)): + numresults += 1 + if (hex_common.is_scalar_reg(regtype)): + numscalarresults += 1 + if (hex_common.is_readwrite(regid)): + if (hex_common.is_scalar_reg(regtype)): + numscalarreadwrite += 1 + + if (numscalarresults > 1): + ## The helper is bogus when there is more than one result + f.write("void HELPER(%s)(CPUHexagonState *env) { BOGUS_HELPER(%s); }\n" + % (tag, tag)) + else: + ## The return type of the function is the type of the destination + ## register + i=0 + for regtype,regid,toss,numregs in regs: + if (hex_common.is_written(regid)): + if (hex_common.is_pair(regid)): + gen_helper_return_type_pair(f,regtype,regid,i) + elif (hex_common.is_single(regid)): + gen_helper_return_type(f,regtype,regid,i) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + i += 1 + + if (numscalarresults == 0): + f.write("void") + f.write(" HELPER(%s)(CPUHexagonState *env" % tag) + + i = 1 + + ## Arguments to the helper function are the source regs and immediates + for regtype,regid,toss,numregs in regs: + if (hex_common.is_read(regid)): + gen_helper_arg_opn(f,regtype,regid,i,tag) + i += 1 + for immlett,bits,immshift in imms: + gen_helper_arg_imm(f,immlett) + i += 1 + if hex_common.need_slot(tag): + if i > 0: f.write(", ") + f.write("uint32_t slot") + i += 1 + if hex_common.need_part1(tag): + if i > 0: f.write(", ") + f.write("uint32_t part1") + f.write(")\n{\n") + if (not hex_common.need_slot(tag)): + f.write(" uint32_t slot __attribute__((unused)) = 4;\n" ) + if hex_common.need_ea(tag): gen_decl_ea(f) + ## Declare the return variable + i=0 + for regtype,regid,toss,numregs in regs: + if (hex_common.is_writeonly(regid)): + gen_helper_dest_decl_opn(f,regtype,regid,i) + i += 1 + + if 'A_FPOP' in hex_common.attribdict[tag]: + f.write(' arch_fpop_start(env);\n'); + + f.write(" %s\n" % hex_common.semdict[tag]) + + if 'A_FPOP' in hex_common.attribdict[tag]: + f.write(' arch_fpop_end(env);\n'); + + ## Save/return the return variable + for regtype,regid,toss,numregs in regs: + if (hex_common.is_written(regid)): + gen_helper_return_opn(f, regtype, regid, i) + f.write("}\n\n") + ## End of the helper definition + +def main(): + hex_common.read_semantics_file(sys.argv[1]) + hex_common.read_attribs_file(sys.argv[2]) + hex_common.read_overrides_file(sys.argv[3]) + hex_common.calculate_attribs() + tagregs = hex_common.get_tagregs() + tagimms = hex_common.get_tagimms() + + with open(sys.argv[4], 'w') as f: + for tag in hex_common.tags: + ## Skip the priv instructions + if ( "A_PRIV" in hex_common.attribdict[tag] ) : + continue + ## Skip the guest instructions + if ( "A_GUEST" in hex_common.attribdict[tag] ) : + continue + ## Skip the diag instructions + if ( tag == "Y6_diag" ) : + continue + if ( tag == "Y6_diag0" ) : + continue + if ( tag == "Y6_diag1" ) : + continue + if ( hex_common.skip_qemu_helper(tag) ): + continue + + gen_helper_function(f, tag, tagregs, tagimms) + +if __name__ == "__main__": + main() diff --git a/target/hexagon/gen_helper_protos.py b/target/hexagon/gen_helper_protos.py new file mode 100755 index 0000000000..ea41007ec9 --- /dev/null +++ b/target/hexagon/gen_helper_protos.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sys +import re +import string +import hex_common + +## +## Helpers for gen_helper_prototype +## +def_helper_types = { + 'N' : 's32', + 'O' : 's32', + 'P' : 's32', + 'M' : 's32', + 'C' : 's32', + 'R' : 's32', + 'V' : 'ptr', + 'Q' : 'ptr' +} + +def_helper_types_pair = { + 'R' : 's64', + 'C' : 's64', + 'S' : 's64', + 'G' : 's64', + 'V' : 'ptr', + 'Q' : 'ptr' +} + +def gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i): + if (hex_common.is_pair(regid)): + f.write(", %s" % (def_helper_types_pair[regtype])) + elif (hex_common.is_single(regid)): + f.write(", %s" % (def_helper_types[regtype])) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + +## +## Generate the DEF_HELPER prototype for an instruction +## For A2_add: Rd32=add(Rs32,Rt32) +## We produce: +## DEF_HELPER_3(A2_add, s32, env, s32, s32) +## +def gen_helper_prototype(f, tag, tagregs, tagimms): + regs = tagregs[tag] + imms = tagimms[tag] + + numresults = 0 + numscalarresults = 0 + numscalarreadwrite = 0 + for regtype,regid,toss,numregs in regs: + if (hex_common.is_written(regid)): + numresults += 1 + if (hex_common.is_scalar_reg(regtype)): + numscalarresults += 1 + if (hex_common.is_readwrite(regid)): + if (hex_common.is_scalar_reg(regtype)): + numscalarreadwrite += 1 + + if (numscalarresults > 1): + ## The helper is bogus when there is more than one result + f.write('DEF_HELPER_1(%s, void, env)\n' % tag) + else: + ## Figure out how many arguments the helper will take + if (numscalarresults == 0): + def_helper_size = len(regs)+len(imms)+numscalarreadwrite+1 + if hex_common.need_part1(tag): def_helper_size += 1 + if hex_common.need_slot(tag): def_helper_size += 1 + f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) + ## The return type is void + f.write(', void' ) + else: + def_helper_size = len(regs)+len(imms)+numscalarreadwrite + if hex_common.need_part1(tag): def_helper_size += 1 + if hex_common.need_slot(tag): def_helper_size += 1 + f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) + + ## Generate the qemu DEF_HELPER type for each result + i=0 + for regtype,regid,toss,numregs in regs: + if (hex_common.is_written(regid)): + gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) + i += 1 + + ## Put the env between the outputs and inputs + f.write(', env' ) + i += 1 + + ## Generate the qemu type for each input operand (regs and immediates) + for regtype,regid,toss,numregs in regs: + if (hex_common.is_read(regid)): + gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) + i += 1 + for immlett,bits,immshift in imms: + f.write(", s32") + + ## Add the arguments for the instruction slot and part1 (if needed) + if hex_common.need_slot(tag): f.write(', i32' ) + if hex_common.need_part1(tag): f.write(' , i32' ) + f.write(')\n') + +def main(): + hex_common.read_semantics_file(sys.argv[1]) + hex_common.read_attribs_file(sys.argv[2]) + hex_common.read_overrides_file(sys.argv[3]) + hex_common.calculate_attribs() + tagregs = hex_common.get_tagregs() + tagimms = hex_common.get_tagimms() + + with open(sys.argv[4], 'w') as f: + for tag in hex_common.tags: + ## Skip the priv instructions + if ( "A_PRIV" in hex_common.attribdict[tag] ) : + continue + ## Skip the guest instructions + if ( "A_GUEST" in hex_common.attribdict[tag] ) : + continue + ## Skip the diag instructions + if ( tag == "Y6_diag" ) : + continue + if ( tag == "Y6_diag0" ) : + continue + if ( tag == "Y6_diag1" ) : + continue + + if ( hex_common.skip_qemu_helper(tag) ): + continue + + gen_helper_prototype(f, tag, tagregs, tagimms) + +if __name__ == "__main__": + main() diff --git a/target/hexagon/gen_op_attribs.py b/target/hexagon/gen_op_attribs.py new file mode 100755 index 0000000000..6a1a1ca21d --- /dev/null +++ b/target/hexagon/gen_op_attribs.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sys +import re +import string +import hex_common + +def main(): + hex_common.read_semantics_file(sys.argv[1]) + hex_common.read_attribs_file(sys.argv[2]) + hex_common.calculate_attribs() + + ## + ## Generate all the attributes associated with each instruction + ## + with open(sys.argv[3], 'w') as f: + for tag in hex_common.tags: + f.write('OP_ATTRIB(%s,ATTRIBS(%s))\n' % \ + (tag, ','.join(sorted(hex_common.attribdict[tag])))) + +if __name__ == "__main__": + main() diff --git a/target/hexagon/gen_op_regs.py b/target/hexagon/gen_op_regs.py new file mode 100755 index 0000000000..e8137d4a12 --- /dev/null +++ b/target/hexagon/gen_op_regs.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sys +import re +import string +import hex_common + +## +## Generate the register and immediate operands for each instruction +## +def calculate_regid_reg(tag): + def letter_inc(x): return chr(ord(x)+1) + ordered_implregs = [ 'SP','FP','LR' ] + srcdst_lett = 'X' + src_lett = 'S' + dst_lett = 'D' + retstr = "" + mapdict = {} + for reg in ordered_implregs: + reg_rd = 0 + reg_wr = 0 + if ('A_IMPLICIT_WRITES_'+reg) in hex_common.attribdict[tag]: reg_wr = 1 + if reg_rd and reg_wr: + retstr += srcdst_lett + mapdict[srcdst_lett] = reg + srcdst_lett = letter_inc(srcdst_lett) + elif reg_rd: + retstr += src_lett + mapdict[src_lett] = reg + src_lett = letter_inc(src_lett) + elif reg_wr: + retstr += dst_lett + mapdict[dst_lett] = reg + dst_lett = letter_inc(dst_lett) + return retstr,mapdict + +def calculate_regid_letters(tag): + retstr,mapdict = calculate_regid_reg(tag) + return retstr + +def strip_reg_prefix(x): + y=x.replace('UREG.','') + y=y.replace('MREG.','') + return y.replace('GREG.','') + +def main(): + hex_common.read_semantics_file(sys.argv[1]) + hex_common.read_attribs_file(sys.argv[2]) + tagregs = hex_common.get_tagregs() + tagimms = hex_common.get_tagimms() + + with open(sys.argv[3], 'w') as f: + for tag in hex_common.tags: + regs = tagregs[tag] + rregs = [] + wregs = [] + regids = "" + for regtype,regid,toss,numregs in regs: + if hex_common.is_read(regid): + if regid[0] not in regids: regids += regid[0] + rregs.append(regtype+regid+numregs) + if hex_common.is_written(regid): + wregs.append(regtype+regid+numregs) + if regid[0] not in regids: regids += regid[0] + for attrib in hex_common.attribdict[tag]: + if hex_common.attribinfo[attrib]['rreg']: + rregs.append(strip_reg_prefix(attribinfo[attrib]['rreg'])) + if hex_common.attribinfo[attrib]['wreg']: + wregs.append(strip_reg_prefix(attribinfo[attrib]['wreg'])) + regids += calculate_regid_letters(tag) + f.write('REGINFO(%s,"%s",\t/*RD:*/\t"%s",\t/*WR:*/\t"%s")\n' % \ + (tag,regids,",".join(rregs),",".join(wregs))) + + for tag in hex_common.tags: + imms = tagimms[tag] + f.write( 'IMMINFO(%s' % tag) + if not imms: + f.write(''','u',0,0,'U',0,0''') + for sign,size,shamt in imms: + if sign == 'r': sign = 's' + if not shamt: + shamt = "0" + f.write(''','%s',%s,%s''' % (sign,size,shamt)) + if len(imms) == 1: + if sign.isupper(): + myu = 'u' + else: + myu = 'U' + f.write(''','%s',0,0''' % myu) + f.write(')\n') + +if __name__ == "__main__": + main() diff --git a/target/hexagon/gen_opcodes_def.py b/target/hexagon/gen_opcodes_def.py new file mode 100755 index 0000000000..fa604a8db9 --- /dev/null +++ b/target/hexagon/gen_opcodes_def.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sys +import re +import string +import hex_common + +def main(): + hex_common.read_semantics_file(sys.argv[1]) + + ## + ## Generate a list of all the opcodes + ## + with open(sys.argv[3], 'w') as f: + for tag in hex_common.tags: + f.write ( "OPCODE(%s),\n" % (tag) ) + +if __name__ == "__main__": + main() diff --git a/target/hexagon/gen_printinsn.py b/target/hexagon/gen_printinsn.py new file mode 100755 index 0000000000..12737bf8a0 --- /dev/null +++ b/target/hexagon/gen_printinsn.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sys +import re +import string +import hex_common + +## +## Generate data for printing each instruction (format string + operands) +## +def regprinter(m): + str = m.group(1) + str += ":".join(["%d"]*len(m.group(2))) + str += m.group(3) + if ('S' in m.group(1)) and (len(m.group(2)) == 1): + str += "/%s" + elif ('C' in m.group(1)) and (len(m.group(2)) == 1): + str += "/%s" + return str + +def spacify(s): + # Regular expression that matches any operator that contains '=' character: + opswithequal_re = '[-+^&|!<>=]?=' + # Regular expression that matches any assignment operator. + assignment_re = '[-+^&|]?=' + + # Out of the operators that contain the = sign, if the operator is also an + # assignment, spaces will be added around it, unless it's enclosed within + # parentheses, or spaces are already present. + + equals = re.compile(opswithequal_re) + assign = re.compile(assignment_re) + + slen = len(s) + paren_count = {} + i = 0 + pc = 0 + while i < slen: + c = s[i] + if c == '(': + pc += 1 + elif c == ')': + pc -= 1 + paren_count[i] = pc + i += 1 + + # Iterate over all operators that contain the equal sign. If any + # match is also an assignment operator, add spaces around it if + # the parenthesis count is 0. + pos = 0 + out = [] + for m in equals.finditer(s): + ms = m.start() + me = m.end() + # t is the string that matched opswithequal_re. + t = m.string[ms:me] + out += s[pos:ms] + pos = me + if paren_count[ms] == 0: + # Check if the entire string t is an assignment. + am = assign.match(t) + if am and len(am.group(0)) == me-ms: + # Don't add spaces if they are already there. + if ms > 0 and s[ms-1] != ' ': + out.append(' ') + out += t + if me < slen and s[me] != ' ': + out.append(' ') + continue + # If this is not an assignment, just append it to the output + # string. + out += t + + # Append the remaining part of the string. + out += s[pos:len(s)] + return ''.join(out) + +def main(): + hex_common.read_semantics_file(sys.argv[1]) + hex_common.read_attribs_file(sys.argv[2]) + + immext_casere = re.compile(r'IMMEXT\(([A-Za-z])') + + with open(sys.argv[3], 'w') as f: + for tag in hex_common.tags: + if not hex_common.behdict[tag]: continue + extendable_upper_imm = False + extendable_lower_imm = False + m = immext_casere.search(hex_common.semdict[tag]) + if m: + if m.group(1).isupper(): + extendable_upper_imm = True + else: + extendable_lower_imm = True + beh = hex_common.behdict[tag] + beh = hex_common.regre.sub(regprinter,beh) + beh = hex_common.absimmre.sub(r"#%s0x%x",beh) + beh = hex_common.relimmre.sub(r"PC+%s%d",beh) + beh = spacify(beh) + # Print out a literal "%s" at the end, used to match empty string + # so C won't complain at us + if ("A_VECX" in hex_common.attribdict[tag]): + macname = "DEF_VECX_PRINTINFO" + else: macname = "DEF_PRINTINFO" + f.write('%s(%s,"%s%%s"' % (macname,tag,beh)) + regs_or_imms = \ + hex_common.reg_or_immre.findall(hex_common.behdict[tag]) + ri = 0 + seenregs = {} + for allregs,a,b,c,d,allimm,immlett,bits,immshift in regs_or_imms: + if a: + #register + if b in seenregs: + regno = seenregs[b] + else: + regno = ri + if len(b) == 1: + f.write(', insn->regno[%d]' % regno) + if 'S' in a: + f.write(', sreg2str(insn->regno[%d])' % regno) + elif 'C' in a: + f.write(', creg2str(insn->regno[%d])' % regno) + elif len(b) == 2: + f.write(', insn->regno[%d] + 1, insn->regno[%d]' % \ + (regno,regno)) + else: + print("Put some stuff to handle quads here") + if b not in seenregs: + seenregs[b] = ri + ri += 1 + else: + #immediate + if (immlett.isupper()): + if extendable_upper_imm: + if immlett in 'rR': + f.write(',insn->extension_valid?"##":""') + else: + f.write(',insn->extension_valid?"#":""') + else: + f.write(',""') + ii = 1 + else: + if extendable_lower_imm: + if immlett in 'rR': + f.write(',insn->extension_valid?"##":""') + else: + f.write(',insn->extension_valid?"#":""') + else: + f.write(',""') + ii = 0 + f.write(', insn->immed[%d]' % ii) + # append empty string so there is at least one more arg + f.write(',"")\n') + +if __name__ == "__main__": + main() diff --git a/target/hexagon/gen_shortcode.py b/target/hexagon/gen_shortcode.py new file mode 100755 index 0000000000..9b589d0189 --- /dev/null +++ b/target/hexagon/gen_shortcode.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sys +import re +import string +import hex_common + +def gen_shortcode(f, tag): + f.write('DEF_SHORTCODE(%s, %s)\n' % (tag, hex_common.semdict[tag])) + +def main(): + hex_common.read_semantics_file(sys.argv[1]) + hex_common.read_attribs_file(sys.argv[2]) + hex_common.calculate_attribs() + tagregs = hex_common.get_tagregs() + tagimms = hex_common.get_tagimms() + + with open(sys.argv[3], 'w') as f: + f.write("#ifndef DEF_SHORTCODE\n") + f.write("#define DEF_SHORTCODE(TAG,SHORTCODE) /* Nothing */\n") + f.write("#endif\n") + + for tag in hex_common.tags: + ## Skip the priv instructions + if ( "A_PRIV" in hex_common.attribdict[tag] ) : + continue + ## Skip the guest instructions + if ( "A_GUEST" in hex_common.attribdict[tag] ) : + continue + ## Skip the diag instructions + if ( tag == "Y6_diag" ) : + continue + if ( tag == "Y6_diag0" ) : + continue + if ( tag == "Y6_diag1" ) : + continue + + gen_shortcode(f, tag) + + f.write("#undef DEF_SHORTCODE\n") + +if __name__ == "__main__": + main() diff --git a/target/hexagon/gen_tcg_func_table.py b/target/hexagon/gen_tcg_func_table.py new file mode 100755 index 0000000000..4809d3273e --- /dev/null +++ b/target/hexagon/gen_tcg_func_table.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sys +import re +import string +import hex_common + +def main(): + hex_common.read_semantics_file(sys.argv[1]) + hex_common.read_attribs_file(sys.argv[2]) + hex_common.calculate_attribs() + tagregs = hex_common.get_tagregs() + tagimms = hex_common.get_tagimms() + + with open(sys.argv[3], 'w') as f: + f.write("#ifndef HEXAGON_FUNC_TABLE_H\n") + f.write("#define HEXAGON_FUNC_TABLE_H\n\n") + + f.write("const SemanticInsn opcode_genptr[XX_LAST_OPCODE] = {\n") + for tag in hex_common.tags: + ## Skip the priv instructions + if ( "A_PRIV" in hex_common.attribdict[tag] ) : + continue + ## Skip the guest instructions + if ( "A_GUEST" in hex_common.attribdict[tag] ) : + continue + ## Skip the diag instructions + if ( tag == "Y6_diag" ) : + continue + if ( tag == "Y6_diag0" ) : + continue + if ( tag == "Y6_diag1" ) : + continue + + f.write(" [%s] = generate_%s,\n" % (tag, tag)) + f.write("};\n\n") + + f.write("#endif /* HEXAGON_FUNC_TABLE_H */\n") + +if __name__ == "__main__": + main() diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py new file mode 100755 index 0000000000..fe4d8e5730 --- /dev/null +++ b/target/hexagon/gen_tcg_funcs.py @@ -0,0 +1,485 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sys +import re +import string +import hex_common + +## +## Helpers for gen_tcg_func +## +def gen_decl_ea_tcg(f, tag): + if ('A_CONDEXEC' in hex_common.attribdict[tag] or + 'A_LOAD' in hex_common.attribdict[tag]): + f.write(" TCGv EA = tcg_temp_local_new();\n") + else: + f.write(" TCGv EA = tcg_temp_new();\n") + +def gen_free_ea_tcg(f): + f.write(" tcg_temp_free(EA);\n") + +def genptr_decl_pair_writeble(f, tag, regtype, regid, regno): + regN="%s%sN" % (regtype,regid) + f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \ + (regtype, regid)) + if (regtype == "C"): + f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \ + (regN, regno)) + else: + f.write(" const int %s = insn->regno[%d];\n" % (regN, regno)) + if ('A_CONDEXEC' in hex_common.attribdict[tag]): + f.write(" if (!is_preloaded(ctx, %s)) {\n" % regN) + f.write(" tcg_gen_mov_tl(hex_new_value[%s], hex_gpr[%s]);\n" % \ + (regN, regN)) + f.write(" }\n") + f.write(" if (!is_preloaded(ctx, %s + 1)) {\n" % regN) + f.write(" tcg_gen_mov_tl(hex_new_value[%s + 1], hex_gpr[%s + 1]);\n" % \ + (regN, regN)) + f.write(" }\n") + +def genptr_decl_writeble(f, tag, regtype, regid, regno): + regN="%s%sN" % (regtype,regid) + f.write(" TCGv %s%sV = tcg_temp_local_new();\n" % \ + (regtype, regid)) + if (regtype == "C"): + f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \ + (regN, regno)) + else: + f.write(" const int %s = insn->regno[%d];\n" % (regN, regno)) + if ('A_CONDEXEC' in hex_common.attribdict[tag]): + f.write(" if (!is_preloaded(ctx, %s)) {\n" % regN) + f.write(" tcg_gen_mov_tl(hex_new_value[%s], hex_gpr[%s]);\n" % \ + (regN, regN)) + f.write(" }\n") + +def genptr_decl(f, tag, regtype, regid, regno): + regN="%s%sN" % (regtype,regid) + if (regtype == "R"): + if (regid in {"ss", "tt"}): + f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \ + (regtype, regid)) + f.write(" const int %s = insn->regno[%d];\n" % \ + (regN, regno)) + elif (regid in {"dd", "ee", "xx", "yy"}): + genptr_decl_pair_writeble(f, tag, regtype, regid, regno) + elif (regid in {"s", "t", "u", "v"}): + f.write(" TCGv %s%sV = hex_gpr[insn->regno[%d]];\n" % \ + (regtype, regid, regno)) + elif (regid in {"d", "e", "x", "y"}): + genptr_decl_writeble(f, tag, regtype, regid, regno) + else: + print("Bad register parse: ", regtype, regid) + elif (regtype == "P"): + if (regid in {"s", "t", "u", "v"}): + f.write(" TCGv %s%sV = hex_pred[insn->regno[%d]];\n" % \ + (regtype, regid, regno)) + elif (regid in {"d", "e", "x"}): + genptr_decl_writeble(f, tag, regtype, regid, regno) + else: + print("Bad register parse: ", regtype, regid) + elif (regtype == "C"): + if (regid == "ss"): + f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \ + (regtype, regid)) + f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \ + (regN, regno)) + elif (regid == "dd"): + genptr_decl_pair_writeble(f, tag, regtype, regid, regno) + elif (regid == "s"): + f.write(" TCGv %s%sV = tcg_temp_local_new();\n" % \ + (regtype, regid)) + f.write(" const int %s%sN = insn->regno[%d] + HEX_REG_SA0;\n" % \ + (regtype, regid, regno)) + elif (regid == "d"): + genptr_decl_writeble(f, tag, regtype, regid, regno) + else: + print("Bad register parse: ", regtype, regid) + elif (regtype == "M"): + if (regid == "u"): + f.write(" const int %s%sN = insn->regno[%d];\n"% \ + (regtype, regid, regno)) + f.write(" TCGv %s%sV = hex_gpr[%s%sN + HEX_REG_M0];\n" % \ + (regtype, regid, regtype, regid)) + else: + print("Bad register parse: ", regtype, regid) + else: + print("Bad register parse: ", regtype, regid) + +def genptr_decl_new(f,regtype,regid,regno): + if (regtype == "N"): + if (regid in {"s", "t"}): + f.write(" TCGv %s%sN = hex_new_value[insn->regno[%d]];\n" % \ + (regtype, regid, regno)) + else: + print("Bad register parse: ", regtype, regid) + elif (regtype == "P"): + if (regid in {"t", "u", "v"}): + f.write(" TCGv %s%sN = hex_new_pred_value[insn->regno[%d]];\n" % \ + (regtype, regid, regno)) + else: + print("Bad register parse: ", regtype, regid) + else: + print("Bad register parse: ", regtype, regid) + +def genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i): + if (hex_common.is_pair(regid)): + genptr_decl(f, tag, regtype, regid, i) + elif (hex_common.is_single(regid)): + if hex_common.is_old_val(regtype, regid, tag): + genptr_decl(f,tag, regtype, regid, i) + elif hex_common.is_new_val(regtype, regid, tag): + genptr_decl_new(f,regtype,regid,i) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + +def genptr_decl_imm(f,immlett): + if (immlett.isupper()): + i = 1 + else: + i = 0 + f.write(" int %s = insn->immed[%d];\n" % \ + (hex_common.imm_name(immlett), i)) + +def genptr_free(f,regtype,regid,regno): + if (regtype == "R"): + if (regid in {"dd", "ss", "tt", "xx", "yy"}): + f.write(" tcg_temp_free_i64(%s%sV);\n" % (regtype, regid)) + elif (regid in {"d", "e", "x", "y"}): + f.write(" tcg_temp_free(%s%sV);\n" % (regtype, regid)) + elif (regid not in {"s", "t", "u", "v"}): + print("Bad register parse: ",regtype,regid) + elif (regtype == "P"): + if (regid in {"d", "e", "x"}): + f.write(" tcg_temp_free(%s%sV);\n" % (regtype, regid)) + elif (regid not in {"s", "t", "u", "v"}): + print("Bad register parse: ",regtype,regid) + elif (regtype == "C"): + if (regid in {"dd", "ss"}): + f.write(" tcg_temp_free_i64(%s%sV);\n" % (regtype, regid)) + elif (regid in {"d", "s"}): + f.write(" tcg_temp_free(%s%sV);\n" % (regtype, regid)) + else: + print("Bad register parse: ",regtype,regid) + elif (regtype == "M"): + if (regid != "u"): + print("Bad register parse: ", regtype, regid) + else: + print("Bad register parse: ", regtype, regid) + +def genptr_free_new(f,regtype,regid,regno): + if (regtype == "N"): + if (regid not in {"s", "t"}): + print("Bad register parse: ", regtype, regid) + elif (regtype == "P"): + if (regid not in {"t", "u", "v"}): + print("Bad register parse: ", regtype, regid) + else: + print("Bad register parse: ", regtype, regid) + +def genptr_free_opn(f,regtype,regid,i,tag): + if (hex_common.is_pair(regid)): + genptr_free(f,regtype,regid,i) + elif (hex_common.is_single(regid)): + if hex_common.is_old_val(regtype, regid, tag): + genptr_free(f,regtype,regid,i) + elif hex_common.is_new_val(regtype, regid, tag): + genptr_free_new(f,regtype,regid,i) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + +def genptr_src_read(f,regtype,regid): + if (regtype == "R"): + if (regid in {"ss", "tt", "xx", "yy"}): + f.write(" tcg_gen_concat_i32_i64(%s%sV, hex_gpr[%s%sN],\n" % \ + (regtype, regid, regtype, regid)) + f.write(" hex_gpr[%s%sN + 1]);\n" % \ + (regtype, regid)) + elif (regid in {"x", "y"}): + f.write(" tcg_gen_mov_tl(%s%sV, hex_gpr[%s%sN]);\n" % \ + (regtype,regid,regtype,regid)) + elif (regid not in {"s", "t", "u", "v"}): + print("Bad register parse: ", regtype, regid) + elif (regtype == "P"): + if (regid == "x"): + f.write(" tcg_gen_mov_tl(%s%sV, hex_pred[%s%sN]);\n" % \ + (regtype, regid, regtype, regid)) + elif (regid not in {"s", "t", "u", "v"}): + print("Bad register parse: ", regtype, regid) + elif (regtype == "C"): + if (regid == "ss"): + f.write(" gen_read_ctrl_reg_pair(ctx, %s%sN, %s%sV);\n" % \ + (regtype, regid, regtype, regid)) + elif (regid == "s"): + f.write(" gen_read_ctrl_reg(ctx, %s%sN, %s%sV);\n" % \ + (regtype, regid, regtype, regid)) + else: + print("Bad register parse: ", regtype, regid) + elif (regtype == "M"): + if (regid != "u"): + print("Bad register parse: ", regtype, regid) + else: + print("Bad register parse: ", regtype, regid) + +def genptr_src_read_new(f,regtype,regid): + if (regtype == "N"): + if (regid not in {"s", "t"}): + print("Bad register parse: ", regtype, regid) + elif (regtype == "P"): + if (regid not in {"t", "u", "v"}): + print("Bad register parse: ", regtype, regid) + else: + print("Bad register parse: ", regtype, regid) + +def genptr_src_read_opn(f,regtype,regid,tag): + if (hex_common.is_pair(regid)): + genptr_src_read(f,regtype,regid) + elif (hex_common.is_single(regid)): + if hex_common.is_old_val(regtype, regid, tag): + genptr_src_read(f,regtype,regid) + elif hex_common.is_new_val(regtype, regid, tag): + genptr_src_read_new(f,regtype,regid) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + +def gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i): + if (i > 0): f.write(", ") + if (hex_common.is_pair(regid)): + f.write("%s%sV" % (regtype,regid)) + elif (hex_common.is_single(regid)): + if hex_common.is_old_val(regtype, regid, tag): + f.write("%s%sV" % (regtype,regid)) + elif hex_common.is_new_val(regtype, regid, tag): + f.write("%s%sN" % (regtype,regid)) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + +def gen_helper_decl_imm(f,immlett): + f.write(" TCGv tcgv_%s = tcg_const_tl(%s);\n" % \ + (hex_common.imm_name(immlett), hex_common.imm_name(immlett))) + +def gen_helper_call_imm(f,immlett): + f.write(", tcgv_%s" % hex_common.imm_name(immlett)) + +def gen_helper_free_imm(f,immlett): + f.write(" tcg_temp_free(tcgv_%s);\n" % hex_common.imm_name(immlett)) + +def genptr_dst_write_pair(f, tag, regtype, regid): + if ('A_CONDEXEC' in hex_common.attribdict[tag]): + f.write(" gen_log_predicated_reg_write_pair(%s%sN, %s%sV, insn->slot);\n" % \ + (regtype, regid, regtype, regid)) + else: + f.write(" gen_log_reg_write_pair(%s%sN, %s%sV);\n" % \ + (regtype, regid, regtype, regid)) + f.write(" ctx_log_reg_write_pair(ctx, %s%sN);\n" % \ + (regtype, regid)) + +def genptr_dst_write(f, tag, regtype, regid): + if (regtype == "R"): + if (regid in {"dd", "xx", "yy"}): + genptr_dst_write_pair(f, tag, regtype, regid) + elif (regid in {"d", "e", "x", "y"}): + if ('A_CONDEXEC' in hex_common.attribdict[tag]): + f.write(" gen_log_predicated_reg_write(%s%sN, %s%sV,\n" % \ + (regtype, regid, regtype, regid)) + f.write(" insn->slot);\n") + else: + f.write(" gen_log_reg_write(%s%sN, %s%sV);\n" % \ + (regtype, regid, regtype, regid)) + f.write(" ctx_log_reg_write(ctx, %s%sN);\n" % \ + (regtype, regid)) + else: + print("Bad register parse: ", regtype, regid) + elif (regtype == "P"): + if (regid in {"d", "e", "x"}): + f.write(" gen_log_pred_write(%s%sN, %s%sV);\n" % \ + (regtype, regid, regtype, regid)) + f.write(" ctx_log_pred_write(ctx, %s%sN);\n" % \ + (regtype, regid)) + else: + print("Bad register parse: ", regtype, regid) + elif (regtype == "C"): + if (regid == "dd"): + f.write(" gen_write_ctrl_reg_pair(ctx, %s%sN, %s%sV);\n" % \ + (regtype, regid, regtype, regid)) + elif (regid == "d"): + f.write(" gen_write_ctrl_reg(ctx, %s%sN, %s%sV);\n" % \ + (regtype, regid, regtype, regid)) + else: + print("Bad register parse: ", regtype, regid) + else: + print("Bad register parse: ", regtype, regid) + +def genptr_dst_write_opn(f,regtype, regid, tag): + if (hex_common.is_pair(regid)): + genptr_dst_write(f, tag, regtype, regid) + elif (hex_common.is_single(regid)): + genptr_dst_write(f, tag, regtype, regid) + else: + print("Bad register parse: ",regtype,regid,toss,numregs) + +## +## Generate the TCG code to call the helper +## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;} +## We produce: +## static void generate_A2_add() +## CPUHexagonState *env +## DisasContext *ctx, +## Insn *insn, +## Packet *pkt) +## { +## TCGv RdV = tcg_temp_local_new(); +## const int RdN = insn->regno[0]; +## TCGv RsV = hex_gpr[insn->regno[1]]; +## TCGv RtV = hex_gpr[insn->regno[2]]; +## +## gen_log_reg_write(RdN, RdV); +## ctx_log_reg_write(ctx, RdN); +## tcg_temp_free(RdV); +## } +## +## where depends on hex_common.skip_qemu_helper(tag) +## if hex_common.skip_qemu_helper(tag) is True +## is fGEN_TCG_A2_add({ RdV=RsV+RtV;}); +## if hex_common.skip_qemu_helper(tag) is False +## is gen_helper_A2_add(RdV, cpu_env, RsV, RtV); +## +def gen_tcg_func(f, tag, regs, imms): + f.write("static void generate_%s(\n" %tag) + f.write(" CPUHexagonState *env,\n") + f.write(" DisasContext *ctx,\n") + f.write(" Insn *insn,\n") + f.write(" Packet *pkt)\n") + f.write('{\n') + if hex_common.need_ea(tag): gen_decl_ea_tcg(f, tag) + i=0 + ## Declare all the operands (regs and immediates) + for regtype,regid,toss,numregs in regs: + genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i) + i += 1 + for immlett,bits,immshift in imms: + genptr_decl_imm(f,immlett) + + if 'A_PRIV' in hex_common.attribdict[tag]: + f.write(' fCHECKFORPRIV();\n') + if 'A_GUEST' in hex_common.attribdict[tag]: + f.write(' fCHECKFORGUEST();\n') + + ## Read all the inputs + for regtype,regid,toss,numregs in regs: + if (hex_common.is_read(regid)): + genptr_src_read_opn(f,regtype,regid,tag) + + if ( hex_common.skip_qemu_helper(tag) ): + f.write(" fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag])) + else: + ## Generate the call to the helper + for immlett,bits,immshift in imms: + gen_helper_decl_imm(f,immlett) + if hex_common.need_part1(tag): + f.write(" TCGv part1 = tcg_const_tl(insn->part1);\n") + if hex_common.need_slot(tag): + f.write(" TCGv slot = tcg_const_tl(insn->slot);\n") + f.write(" gen_helper_%s(" % (tag)) + i=0 + ## If there is a scalar result, it is the return type + for regtype,regid,toss,numregs in regs: + if (hex_common.is_written(regid)): + gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) + i += 1 + if (i > 0): f.write(", ") + f.write("cpu_env") + i=1 + for regtype,regid,toss,numregs in regs: + if (hex_common.is_read(regid)): + gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) + i += 1 + for immlett,bits,immshift in imms: + gen_helper_call_imm(f,immlett) + + if hex_common.need_slot(tag): f.write(", slot") + if hex_common.need_part1(tag): f.write(", part1" ) + f.write(");\n") + if hex_common.need_slot(tag): + f.write(" tcg_temp_free(slot);\n") + if hex_common.need_part1(tag): + f.write(" tcg_temp_free(part1);\n") + for immlett,bits,immshift in imms: + gen_helper_free_imm(f,immlett) + + ## Write all the outputs + for regtype,regid,toss,numregs in regs: + if (hex_common.is_written(regid)): + genptr_dst_write_opn(f,regtype, regid, tag) + + ## Free all the operands (regs and immediates) + if hex_common.need_ea(tag): gen_free_ea_tcg(f) + for regtype,regid,toss,numregs in regs: + genptr_free_opn(f,regtype,regid,i,tag) + i += 1 + + f.write("}\n\n") + +def gen_def_tcg_func(f, tag, tagregs, tagimms): + regs = tagregs[tag] + imms = tagimms[tag] + + gen_tcg_func(f, tag, regs, imms) + +def main(): + hex_common.read_semantics_file(sys.argv[1]) + hex_common.read_attribs_file(sys.argv[2]) + hex_common.read_overrides_file(sys.argv[3]) + hex_common.calculate_attribs() + tagregs = hex_common.get_tagregs() + tagimms = hex_common.get_tagimms() + + with open(sys.argv[4], 'w') as f: + f.write("#ifndef HEXAGON_TCG_FUNCS_H\n") + f.write("#define HEXAGON_TCG_FUNCS_H\n\n") + + for tag in hex_common.tags: + ## Skip the priv instructions + if ( "A_PRIV" in hex_common.attribdict[tag] ) : + continue + ## Skip the guest instructions + if ( "A_GUEST" in hex_common.attribdict[tag] ) : + continue + ## Skip the diag instructions + if ( tag == "Y6_diag" ) : + continue + if ( tag == "Y6_diag0" ) : + continue + if ( tag == "Y6_diag1" ) : + continue + + gen_def_tcg_func(f, tag, tagregs, tagimms) + + f.write("#endif /* HEXAGON_TCG_FUNCS_H */\n") + +if __name__ == "__main__": + main() diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py new file mode 100755 index 0000000000..b3b534057d --- /dev/null +++ b/target/hexagon/hex_common.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import sys +import re +import string + +behdict = {} # tag ->behavior +semdict = {} # tag -> semantics +attribdict = {} # tag -> attributes +macros = {} # macro -> macro information... +attribinfo = {} # Register information and misc +tags = [] # list of all tags +overrides = {} # tags with helper overrides + +# We should do this as a hash for performance, +# but to keep order let's keep it as a list. +def uniquify(seq): + seen = set() + seen_add = seen.add + return [x for x in seq if x not in seen and not seen_add(x)] + +regre = re.compile( + r"((?" % l) + macro.attribs |= expand_macro_attribs( + macros[submacro], allmac_re) + finished_macros.add(macro.key) + return macro.attribs + +# When qemu needs an attribute that isn't in the imported files, +# we'll add it here. +def add_qemu_macro_attrib(name, attrib): + macros[name].attribs.add(attrib) + +immextre = re.compile(r'f(MUST_)?IMMEXT[(]([UuSsRr])') +def calculate_attribs(): + add_qemu_macro_attrib('fREAD_PC', 'A_IMPLICIT_READS_PC') + add_qemu_macro_attrib('fTRAP', 'A_IMPLICIT_READS_PC') + add_qemu_macro_attrib('fWRITE_P0', 'A_WRITES_PRED_REG') + add_qemu_macro_attrib('fWRITE_P1', 'A_WRITES_PRED_REG') + add_qemu_macro_attrib('fWRITE_P2', 'A_WRITES_PRED_REG') + add_qemu_macro_attrib('fWRITE_P3', 'A_WRITES_PRED_REG') + + # Recurse down macros, find attributes from sub-macros + macroValues = list(macros.values()) + allmacros_restr = "|".join(set([ m.re.pattern for m in macroValues ])) + allmacros_re = re.compile(allmacros_restr) + for macro in macroValues: + expand_macro_attribs(macro,allmacros_re) + # Append attributes to all instructions + for tag in tags: + for macname in allmacros_re.findall(semdict[tag]): + if not macname: continue + macro = macros[macname] + attribdict[tag] |= set(macro.attribs) + # Figure out which instructions write predicate registers + tagregs = get_tagregs() + for tag in tags: + regs = tagregs[tag] + for regtype, regid, toss, numregs in regs: + if regtype == "P" and is_written(regid): + attribdict[tag].add('A_WRITES_PRED_REG') + +def SEMANTICS(tag, beh, sem): + #print tag,beh,sem + behdict[tag] = beh + semdict[tag] = sem + attribdict[tag] = set() + tags.append(tag) # dicts have no order, this is for order + +def ATTRIBUTES(tag, attribstring): + attribstring = \ + attribstring.replace("ATTRIBS","").replace("(","").replace(")","") + if not attribstring: + return + attribs = attribstring.split(",") + for attrib in attribs: + attribdict[tag].add(attrib.strip()) + +class Macro(object): + __slots__ = ['key','name', 'beh', 'attribs', 're'] + def __init__(self, name, beh, attribs): + self.key = name + self.name = name + self.beh = beh + self.attribs = set(attribs) + self.re = re.compile("\\b" + name + "\\b") + +def MACROATTRIB(macname,beh,attribstring): + attribstring = attribstring.replace("(","").replace(")","") + if attribstring: + attribs = attribstring.split(",") + else: + attribs = [] + macros[macname] = Macro(macname,beh,attribs) + +def compute_tag_regs(tag): + return uniquify(regre.findall(behdict[tag])) + +def compute_tag_immediates(tag): + return uniquify(immre.findall(behdict[tag])) + +## +## tagregs is the main data structure we'll use +## tagregs[tag] will contain the registers used by an instruction +## Within each entry, we'll use the regtype and regid fields +## regtype can be one of the following +## C control register +## N new register value +## P predicate register +## R GPR register +## M modifier register +## regid can be one of the following +## d, e destination register +## dd destination register pair +## s, t, u, v, w source register +## ss, tt, uu, vv source register pair +## x, y read-write register +## xx, yy read-write register pair +## +def get_tagregs(): + return dict(zip(tags, list(map(compute_tag_regs, tags)))) + +def get_tagimms(): + return dict(zip(tags, list(map(compute_tag_immediates, tags)))) + +def is_pair(regid): + return len(regid) == 2 + +def is_single(regid): + return len(regid) == 1 + +def is_written(regid): + return regid[0] in "dexy" + +def is_writeonly(regid): + return regid[0] in "de" + +def is_read(regid): + return regid[0] in "stuvwxy" + +def is_readwrite(regid): + return regid[0] in "xy" + +def is_scalar_reg(regtype): + return regtype in "RPC" + +def is_old_val(regtype, regid, tag): + return regtype+regid+'V' in semdict[tag] + +def is_new_val(regtype, regid, tag): + return regtype+regid+'N' in semdict[tag] + +def need_slot(tag): + if ('A_CONDEXEC' in attribdict[tag] or + 'A_STORE' in attribdict[tag] or + 'A_LOAD' in attribdict[tag]): + return 1 + else: + return 0 + +def need_part1(tag): + return re.compile(r"fPART1").search(semdict[tag]) + +def need_ea(tag): + return re.compile(r"\bEA\b").search(semdict[tag]) + +def skip_qemu_helper(tag): + return tag in overrides.keys() + +def imm_name(immlett): + return "%siV" % immlett + +def read_semantics_file(name): + eval_line = "" + for line in open(name, 'rt').readlines(): + if not line.startswith("#"): + eval_line += line + if line.endswith("\\\n"): + eval_line.rstrip("\\\n") + else: + eval(eval_line.strip()) + eval_line = "" + +def read_attribs_file(name): + attribre = re.compile(r'DEF_ATTRIB\(([A-Za-z0-9_]+), ([^,]*), ' + + r'"([A-Za-z0-9_\.]*)", "([A-Za-z0-9_\.]*)"\)') + for line in open(name, 'rt').readlines(): + if not attribre.match(line): + continue + (attrib_base,descr,rreg,wreg) = attribre.findall(line)[0] + attrib_base = 'A_' + attrib_base + attribinfo[attrib_base] = {'rreg':rreg, 'wreg':wreg, 'descr':descr} + +def read_overrides_file(name): + overridere = re.compile("#define fGEN_TCG_([A-Za-z0-9_]+)\(.*") + for line in open(name, 'rt').readlines(): + if not overridere.match(line): + continue + tag = overridere.findall(line)[0] + overrides[tag] = True From patchwork Wed Feb 17 23:40:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 383939 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3221690jao; Wed, 17 Feb 2021 15:49:25 -0800 (PST) X-Google-Smtp-Source: ABdhPJxKDQzI9s3fA+zd63G58f9WppKYxG2cht3k4MM9hM6pxLTf0IluZf6+Bfy4scYd22bN9oQC X-Received: by 2002:a25:9b88:: with SMTP id v8mr2906289ybo.338.1613605765032; Wed, 17 Feb 2021 15:49:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613605765; cv=none; d=google.com; s=arc-20160816; b=h1WE4BLYqWf7s4g7F75+Tr32XS8AXyM1f9m0HTXYGLgai0WvVG//0nm+XMlqqlxihE h4sOBiD4tMQygfbfh8k3n7XhRO/LkED+VLevoBfP3iE0QxHI7rq/dS6sOydfWNNtqc6b tz6Xm6pZfuvGVMH6LStbmZNWy3r1xCuOU5jnEp5VBq4nN5SC8yDZhJyfsuDsPVUg1raQ 6NycYteuvSBeqFRqfC9GsrftMY3QZE7aIX3+ia0IwTVxUOKfSHaaUvmssCkTcm2Ei/Hh 8UznG6gYc8Mq4rnZ1HzBvBHabLAodU8ajWlKE0iH+9eXgIo9qdv/bhMT4I7kT09mOF+E zKtQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=fu/TR1IVvSb6dKMp4A2TQfufe4q9OBagOWhl4/lILBg=; b=cIoUWLaRE9rKXB1r1K4/OwBGjrt+w1M6FWD+aV/v4/vMiwQQe4TxdgMhix+lQldw1V tmUmOBLF0Wv9gW+4nVKdVa49qY+Fi+nOQPpPo4JYfznO/Gkwkat6IAKixl05OnXvVCr4 Oamp0ski22INKoY4vrcIvBH4xng841Jh8WCQfVTfR4WAVt9pZ0iy2FOyMNjpjJ5NZ9NF rK4IDtCKtcQC3UdFhg8sCc2/y/klKyyP8g+6wWB29RvSLHfzocp3vSDt0kgIiE7Z5kTC I+fXDdS1pq4/k+vr7kknea84+lIoq+j5bSQ3mrNm/o+yePtRYkH/PPnkcz+7tUsv4uae rP6w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LYWjHzQN; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id h66si3794683ybh.54.2021.02.17.15.49.24 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:49:25 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LYWjHzQN; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:58144 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWZP-0001D6-Ux for patch@linaro.org; Wed, 17 Feb 2021 18:49:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50918) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRh-00013A-Lf for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:25 -0500 Received: from mail-pg1-x52f.google.com ([2607:f8b0:4864:20::52f]:33644) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRf-0004lU-EM for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:25 -0500 Received: by mail-pg1-x52f.google.com with SMTP id z68so6698pgz.0 for ; Wed, 17 Feb 2021 15:41:22 -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 :mime-version:content-transfer-encoding; bh=fu/TR1IVvSb6dKMp4A2TQfufe4q9OBagOWhl4/lILBg=; b=LYWjHzQN5d9jp5sggv/RN+C4reTcwbUrWgtX4vBlO2ruW5bsbRZ2eRM+X+fqYQVeYp 82FG2d1ckTM0EezFpMzkgC6jiciAUVEtUk79ZTZvrNkCKkvH3J30nh9q9/u79oGqLhrV JIhHQIq/0dBb2YT2RqFHjbEp5mEOtM/du9J2ZE58LtxvpLKDIKa3HBfZMRsGmQPJNmkO bRhetNFnh7Vy5DRS66qDzAk8WiyjDA0D/EcnpW0bfrnI0tDvcDZu8vxrFUpctYlZxCi+ /8PUq5HqX2pmBAx5SVCt9e1EeYnoMA4QDijF9KFnwVj7JMIBvkastvwl4pv42PAxUmID x9lQ== 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:mime-version:content-transfer-encoding; bh=fu/TR1IVvSb6dKMp4A2TQfufe4q9OBagOWhl4/lILBg=; b=BsqqxFn07JwAf8d1LYtht/IZKqu0AhC0Sp6QiEKex96U1xXVv0W1PBS3pt6b+jECDC arQ70AAFEGLm/sKXuW/BpVgn2aI1z13LOw34tWePcQvKe1cnQS0gjq/Om5CRyGZjS7cf leMTdsXyX7UF1+mV/44YGU5HMbWMn7M1FO+y/MsRwP9rcJl1Rb7iaY2XCl+aN5ctISXr jT4i3drHDNwXU2qarrHE4N+nNdkSCaruZM4RxD3tm577/RJTW13ZxadLQd1gPXz5zpQl sL+aU5PXtYaUgx6od/ICgYIhUq8dNxz9w6wxPA8i+V+mm3XBFcNc8SwyyGdwGZ1pFTeA exKQ== X-Gm-Message-State: AOAM533g0UEPZGx1q4NArx/NpJEJmbYlQEYKGohCvfNIJbfYbqFyKwoS WH1sMfSO3csQyZkyJafQv3DeSMVVqsZ0iw== X-Received: by 2002:a62:7808:0:b029:1df:1e0c:3263 with SMTP id t8-20020a6278080000b02901df1e0c3263mr1505398pfc.21.1613605281893; Wed, 17 Feb 2021 15:41:21 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:21 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 22/35] Hexagon (target/hexagon) generator phase 3 - C preprocessor for decode tree Date: Wed, 17 Feb 2021 15:40:10 -0800 Message-Id: <20210217234023.1742406-23-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52f; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Run the C preprocessor across the instruction definition and encoding files to expand macros and prepare the iset.py file. The resulting fill contains python data structures used to build the decode tree. Signed-off-by: Taylor Simpson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-22-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/gen_dectree_import.c | 188 ++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 target/hexagon/gen_dectree_import.c -- 2.25.1 diff --git a/target/hexagon/gen_dectree_import.c b/target/hexagon/gen_dectree_import.c new file mode 100644 index 0000000000..5b7ecfc6b3 --- /dev/null +++ b/target/hexagon/gen_dectree_import.c @@ -0,0 +1,188 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * This program generates the encodings file that is processed by + * the dectree.py script to produce the decoding tree. We use the C + * preprocessor to manipulate the files imported from the Hexagon + * architecture library. + */ +#include +#include +#include "opcodes.h" + +#define STRINGIZE(X) #X + +const char * const opcode_names[] = { +#define OPCODE(IID) STRINGIZE(IID) +#include "opcodes_def_generated.h.inc" + NULL +#undef OPCODE +}; + +/* + * Process the instruction definitions + * Scalar core instructions have the following form + * Q6INSN(A2_add,"Rd32=add(Rs32,Rt32)",ATTRIBS(), + * "Add 32-bit registers", + * { RdV=RsV+RtV;}) + */ +const char * const opcode_syntax[XX_LAST_OPCODE] = { +#define Q6INSN(TAG, BEH, ATTRIBS, DESCR, SEM) \ + [TAG] = BEH, +#define EXTINSN(TAG, BEH, ATTRIBS, DESCR, SEM) \ + [TAG] = BEH, +#include "imported/allidefs.def" +#undef Q6INSN +#undef EXTINSN +}; + +const char * const opcode_rregs[] = { +#define REGINFO(TAG, REGINFO, RREGS, WREGS) RREGS, +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#include "op_regs_generated.h.inc" + NULL +#undef REGINFO +#undef IMMINFO +}; + +const char * const opcode_wregs[] = { +#define REGINFO(TAG, REGINFO, RREGS, WREGS) WREGS, +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#include "op_regs_generated.h.inc" + NULL +#undef REGINFO +#undef IMMINFO +}; + +const OpcodeEncoding opcode_encodings[] = { +#define DEF_ENC32(TAG, ENCSTR) \ + [TAG] = { .encoding = ENCSTR }, +#define DEF_ENC_SUBINSN(TAG, CLASS, ENCSTR) \ + [TAG] = { .encoding = ENCSTR, .enc_class = CLASS }, +#define DEF_EXT_ENC(TAG, CLASS, ENCSTR) \ + [TAG] = { .encoding = ENCSTR, .enc_class = CLASS }, +#include "imported/encode.def" +#undef DEF_ENC32 +#undef DEF_ENC_SUBINSN +#undef DEF_EXT_ENC +}; + +static const char * const opcode_enc_class_names[XX_LAST_ENC_CLASS] = { + "NORMAL", + "16BIT", + "SUBINSN_A", + "SUBINSN_L1", + "SUBINSN_L2", + "SUBINSN_S1", + "SUBINSN_S2", + "EXT_noext", + "EXT_mmvec", +}; + +static const char *get_opcode_enc(int opcode) +{ + const char *tmp = opcode_encodings[opcode].encoding; + if (tmp == NULL) { + tmp = "MISSING ENCODING"; + } + return tmp; +} + +static const char *get_opcode_enc_class(int opcode) +{ + return opcode_enc_class_names[opcode_encodings[opcode].enc_class]; +} + +static void gen_iset_table(FILE *out) +{ + int i; + + fprintf(out, "iset = {\n"); + for (i = 0; i < XX_LAST_OPCODE; i++) { + fprintf(out, "\t\'%s\' : {\n", opcode_names[i]); + fprintf(out, "\t\t\'tag\' : \'%s\',\n", opcode_names[i]); + fprintf(out, "\t\t\'syntax\' : \'%s\',\n", opcode_syntax[i]); + fprintf(out, "\t\t\'rregs\' : \'%s\',\n", opcode_rregs[i]); + fprintf(out, "\t\t\'wregs\' : \'%s\',\n", opcode_wregs[i]); + fprintf(out, "\t\t\'enc\' : \'%s\',\n", get_opcode_enc(i)); + fprintf(out, "\t\t\'enc_class\' : \'%s\',\n", get_opcode_enc_class(i)); + fprintf(out, "\t},\n"); + } + fprintf(out, "};\n\n"); +} + +static void gen_tags_list(FILE *out) +{ + int i; + + fprintf(out, "tags = [\n"); + for (i = 0; i < XX_LAST_OPCODE; i++) { + fprintf(out, "\t\'%s\',\n", opcode_names[i]); + } + fprintf(out, "];\n\n"); +} + +static void gen_enc_ext_spaces_table(FILE *out) +{ + fprintf(out, "enc_ext_spaces = {\n"); +#define DEF_EXT_SPACE(SPACEID, ENCSTR) \ + fprintf(out, "\t\'%s\' : \'%s\',\n", #SPACEID, ENCSTR); +#include "imported/encode.def" +#undef DEF_EXT_SPACE + fprintf(out, "};\n\n"); +} + +static void gen_subinsn_groupings_table(FILE *out) +{ + fprintf(out, "subinsn_groupings = {\n"); +#define DEF_PACKED32(TAG, TYPEA, TYPEB, ENCSTR) \ + do { \ + fprintf(out, "\t\'%s\' : {\n", #TAG); \ + fprintf(out, "\t\t\'name\' : \'%s\',\n", #TAG); \ + fprintf(out, "\t\t\'class_a\' : \'%s\',\n", #TYPEA); \ + fprintf(out, "\t\t\'class_b\' : \'%s\',\n", #TYPEB); \ + fprintf(out, "\t\t\'enc\' : \'%s\',\n", ENCSTR); \ + fprintf(out, "\t},\n"); \ + } while (0); +#include "imported/encode.def" +#undef DEF_PACKED32 + fprintf(out, "};\n\n"); +} + +int main(int argc, char *argv[]) +{ + FILE *outfile; + + if (argc != 2) { + fprintf(stderr, "Usage: gen_dectree_import ouptputfile\n"); + return 1; + } + outfile = fopen(argv[1], "w"); + if (outfile == NULL) { + fprintf(stderr, "Cannot open %s for writing\n", argv[1]); + return 1; + } + + gen_iset_table(outfile); + gen_tags_list(outfile); + gen_enc_ext_spaces_table(outfile); + gen_subinsn_groupings_table(outfile); + + fclose(outfile); + return 0; +} From patchwork Wed Feb 17 23:40:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384143 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3224837jao; Wed, 17 Feb 2021 15:55:55 -0800 (PST) X-Google-Smtp-Source: ABdhPJwjI1VmgV87kOrsHXvFl7ujPUYW0JQP4eaUqIKWY3vVyqOKbH6zULMYZuvMOwQIZW3/biF0 X-Received: by 2002:a25:e68c:: with SMTP id d134mr3001423ybh.94.1613606154878; Wed, 17 Feb 2021 15:55:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606154; cv=none; d=google.com; s=arc-20160816; b=dmID1IFE0PjWInaAF2g4/cf0q6rjmnAZBORw4irmHKOsvnaDYNrMub7q9XWTCspX05 FapgiKNfRmSHortz5W23t7ZYjwk6+x4oI7CH1ypQ4l0NDkrp0JiwseVNnLARzF7Y+MZo ZxmQxMGPYXRkxPvAKzmGNwtrXRXiH25EtFnFAYcSVEIYJsW+kIkRWG62MBEVeMFLv5Al PM+sqZjgi6IDGu/8XGT779pQLnS69vi6r2VjNbQWxS9zyaqQJ6mX3cBijLkxChz91yQp BWTe30AtxtmLhWE87K2J6IdBHOP1ckq5gd5Toqr4VbvsZ++MWMgge10NhSL5CXBLtkKx MuAQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=RQJo3a2YquNCgK0VXq81wl7cHG+zRnkr9mYcghGogZQ=; b=Ax1nZ/6eXsJPdMSA2wIEIGweCAlrRm97LWqjnSU9hXBIrl/FtbqZh/AVrM2rWZ3fFn ARfgqKd5e81Il9fepRECpLJbzDpMlnu7fMAFUflF9Gich3rSy8bFqtXomDKkrYYd2ZhZ pptYkzi2RFKPY3Acn7lBVC2BZwyV5XloR2owv6GslyK97uVtScudxanhU2ttaIs9CWj/ NVxAnTIexzbEOzZTNnjkiq4wQoaUfvURV50k7seCiZXHsGhDV5F4NPrf+J/cpMiM2mwN 1FRWDzzgYE13M3gELf1fTeI3XCA2Mu/nLewwdgBbV8iTITfK38mSfE4LoDRpV6ZEN6iq y5Gg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=qFlYh0RN; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id w1si3684641ybp.206.2021.02.17.15.55.54 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:55:54 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=qFlYh0RN; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:47048 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWfi-0008S9-As for patch@linaro.org; Wed, 17 Feb 2021 18:55:54 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:50966) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRk-00016b-HA for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:28 -0500 Received: from mail-pg1-x531.google.com ([2607:f8b0:4864:20::531]:34614) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRh-0004lk-BL for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:28 -0500 Received: by mail-pg1-x531.google.com with SMTP id o7so3709pgl.1 for ; Wed, 17 Feb 2021 15:41:24 -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 :mime-version:content-transfer-encoding; bh=RQJo3a2YquNCgK0VXq81wl7cHG+zRnkr9mYcghGogZQ=; b=qFlYh0RNWmw7tJkOHltvQWkAg00PBUly9yGKv4RxFFfHyH8B6Oo28ODTeAF1Za9ryC 61OT2GFyBIsOpgZm0T+lsWJ+pXXQKqlFzXdqLuFnAPhxJIFPV6IHMFC8Bf7oLDZKuPTN bMcXrKarvA+Kf3iInDrrlO0qBgiTjZGfP2Jif9+MRM/tIFUYNPpJzXBfKgqZ/39j9PJC 8OWj/QXZ9PETYvipUFYv627ai2hgBZR/7PyK0TrXbWbkCTst82L5kyf6h7cAIKErehIX EA8nIxPQsZcE6Lt+5m9L70r4ydw3Qwljv2S1FogUEvneoZXydgFVeR/wTqwi6ldzxTuF s/Sw== 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:mime-version:content-transfer-encoding; bh=RQJo3a2YquNCgK0VXq81wl7cHG+zRnkr9mYcghGogZQ=; b=JB5lWA7Vgo0e/AUT91WDz/nsNPISEZ7yYiuB52PBB8bOfk6xUhSQWqIsPrOWl5cZ5g OXG7EJoFcxO79C6Kfo+An/nMjEljIE2dlguCjR71EgGg6t5P9F40q0JArTyfXZ1Yu0rK eigX2zQutfMQjNJPtzO2GSWXHNt63sitUKXL1o1htJvVEJ4gjdF/uPYDAulqeBQkAqMz NF8s/wV+u+bcaB8mcno+T2Z9dkjj7kcDwlMF+q4bvfmzYVtCaFyytTnBFer8LE0JcdU5 Mnz/gansUA+oTnixJsV2MN6FnyXubprrWhVPXStMjb62zbgWmQqMH66ZbIjwKTRSmAcS xWcg== X-Gm-Message-State: AOAM530nnw6JkFbDpAOoOb/2e7AFS4PksxoleBlpDGhOTX7nbWlXBuEG XW1suvjcv2PSfi5RioaojMIzCMNLh2o+ug== X-Received: by 2002:a05:6a00:1a03:b029:1d3:1fa3:4a5d with SMTP id g3-20020a056a001a03b02901d31fa34a5dmr1612869pfv.1.1613605283763; Wed, 17 Feb 2021 15:41:23 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:23 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 23/35] Hexagon (target/hexagon) generater phase 4 - decode tree Date: Wed, 17 Feb 2021 15:40:11 -0800 Message-Id: <20210217234023.1742406-24-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::531; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x531.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Python script that emits the decode tree in dectree_generated.h. Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-23-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/dectree.py | 351 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) create mode 100755 target/hexagon/dectree.py -- 2.25.1 diff --git a/target/hexagon/dectree.py b/target/hexagon/dectree.py new file mode 100755 index 0000000000..29467ec7d7 --- /dev/null +++ b/target/hexagon/dectree.py @@ -0,0 +1,351 @@ +#!/usr/bin/env python3 + +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +import io +import re + +import sys +import iset + +encs = {tag : ''.join(reversed(iset.iset[tag]['enc'].replace(' ', ''))) + for tag in iset.tags if iset.iset[tag]['enc'] != 'MISSING ENCODING'} + +enc_classes = set([iset.iset[tag]['enc_class'] for tag in encs.keys()]) +subinsn_enc_classes = \ + set([enc_class for enc_class in enc_classes \ + if enc_class.startswith('SUBINSN_')]) +ext_enc_classes = \ + set([enc_class for enc_class in enc_classes \ + if enc_class not in ('NORMAL', '16BIT') and \ + not enc_class.startswith('SUBINSN_')]) + +try: + subinsn_groupings = iset.subinsn_groupings +except AttributeError: + subinsn_groupings = {} + +for (tag, subinsn_grouping) in subinsn_groupings.items(): + encs[tag] = ''.join(reversed(subinsn_grouping['enc'].replace(' ', ''))) + +dectree_normal = {'leaves' : set()} +dectree_16bit = {'leaves' : set()} +dectree_subinsn_groupings = {'leaves' : set()} +dectree_subinsns = {name : {'leaves' : set()} for name in subinsn_enc_classes} +dectree_extensions = {name : {'leaves' : set()} for name in ext_enc_classes} + +for tag in encs.keys(): + if tag in subinsn_groupings: + dectree_subinsn_groupings['leaves'].add(tag) + continue + enc_class = iset.iset[tag]['enc_class'] + if enc_class.startswith('SUBINSN_'): + if len(encs[tag]) != 32: + encs[tag] = encs[tag] + '0' * (32 - len(encs[tag])) + dectree_subinsns[enc_class]['leaves'].add(tag) + elif enc_class == '16BIT': + if len(encs[tag]) != 16: + raise Exception('Tag "{}" has enc_class "{}" and not an encoding ' + + 'width of 16 bits!'.format(tag, enc_class)) + dectree_16bit['leaves'].add(tag) + else: + if len(encs[tag]) != 32: + raise Exception('Tag "{}" has enc_class "{}" and not an encoding ' + + 'width of 32 bits!'.format(tag, enc_class)) + if enc_class == 'NORMAL': + dectree_normal['leaves'].add(tag) + else: + dectree_extensions[enc_class]['leaves'].add(tag) + +faketags = set() +for (tag, enc) in iset.enc_ext_spaces.items(): + faketags.add(tag) + encs[tag] = ''.join(reversed(enc.replace(' ', ''))) + dectree_normal['leaves'].add(tag) + +faketags |= set(subinsn_groupings.keys()) + +def every_bit_counts(bitset): + for i in range(1, len(next(iter(bitset)))): + if len(set([bits[:i] + bits[i+1:] for bits in bitset])) == len(bitset): + return False + return True + +def auto_separate(node): + tags = node['leaves'] + if len(tags) <= 1: + return + enc_width = len(encs[next(iter(tags))]) + opcode_bit_for_all = \ + [all([encs[tag][i] in '01' \ + for tag in tags]) for i in range(enc_width)] + opcode_bit_is_0_for_all = \ + [opcode_bit_for_all[i] and all([encs[tag][i] == '0' \ + for tag in tags]) for i in range(enc_width)] + opcode_bit_is_1_for_all = \ + [opcode_bit_for_all[i] and all([encs[tag][i] == '1' \ + for tag in tags]) for i in range(enc_width)] + differentiator_opcode_bit = \ + [opcode_bit_for_all[i] and \ + not (opcode_bit_is_0_for_all[i] or \ + opcode_bit_is_1_for_all[i]) \ + for i in range(enc_width)] + best_width = 0 + for width in range(4, 0, -1): + for lsb in range(enc_width - width, -1, -1): + bitset = set([encs[tag][lsb:lsb+width] for tag in tags]) + if all(differentiator_opcode_bit[lsb:lsb+width]) and \ + (len(bitset) == len(tags) or every_bit_counts(bitset)): + best_width = width + best_lsb = lsb + caught_all_tags = len(bitset) == len(tags) + break + if best_width != 0: + break + if best_width == 0: + raise Exception('Could not find a way to differentiate the encodings ' + + 'of the following tags:\n{}'.format('\n'.join(tags))) + if caught_all_tags: + for width in range(1, best_width): + for lsb in range(enc_width - width, -1, -1): + bitset = set([encs[tag][lsb:lsb+width] for tag in tags]) + if all(differentiator_opcode_bit[lsb:lsb+width]) and \ + len(bitset) == len(tags): + best_width = width + best_lsb = lsb + break + else: + continue + break + node['separator_lsb'] = best_lsb + node['separator_width'] = best_width + node['children'] = [] + for value in range(2 ** best_width): + child = {} + bits = ''.join(reversed('{:0{}b}'.format(value, best_width))) + child['leaves'] = \ + set([tag for tag in tags \ + if encs[tag][best_lsb:best_lsb+best_width] == bits]) + node['children'].append(child) + for child in node['children']: + auto_separate(child) + +auto_separate(dectree_normal) +auto_separate(dectree_16bit) +if subinsn_groupings: + auto_separate(dectree_subinsn_groupings) +for dectree_subinsn in dectree_subinsns.values(): + auto_separate(dectree_subinsn) +for dectree_ext in dectree_extensions.values(): + auto_separate(dectree_ext) + +for tag in faketags: + del encs[tag] + +def table_name(parents, node): + path = parents + [node] + root = path[0] + tag = next(iter(node['leaves'])) + if tag in subinsn_groupings: + enc_width = len(subinsn_groupings[tag]['enc'].replace(' ', '')) + else: + tag = next(iter(node['leaves'] - faketags)) + enc_width = len(encs[tag]) + determining_bits = ['_'] * enc_width + for (parent, child) in zip(path[:-1], path[1:]): + lsb = parent['separator_lsb'] + width = parent['separator_width'] + value = parent['children'].index(child) + determining_bits[lsb:lsb+width] = \ + list(reversed('{:0{}b}'.format(value, width))) + if tag in subinsn_groupings: + name = 'DECODE_ROOT_EE' + else: + enc_class = iset.iset[tag]['enc_class'] + if enc_class in ext_enc_classes: + name = 'DECODE_EXT_{}'.format(enc_class) + elif enc_class in subinsn_enc_classes: + name = 'DECODE_SUBINSN_{}'.format(enc_class) + else: + name = 'DECODE_ROOT_{}'.format(enc_width) + if node != root: + name += '_' + ''.join(reversed(determining_bits)) + return name + +def print_node(f, node, parents): + if len(node['leaves']) <= 1: + return + name = table_name(parents, node) + lsb = node['separator_lsb'] + width = node['separator_width'] + print('DECODE_NEW_TABLE({},{},DECODE_SEPARATOR_BITS({},{}))'.\ + format(name, 2 ** width, lsb, width), file=f) + for child in node['children']: + if len(child['leaves']) == 0: + print('INVALID()', file=f) + elif len(child['leaves']) == 1: + (tag,) = child['leaves'] + if tag in subinsn_groupings: + class_a = subinsn_groupings[tag]['class_a'] + class_b = subinsn_groupings[tag]['class_b'] + enc = subinsn_groupings[tag]['enc'].replace(' ', '') + if 'RESERVED' in tag: + print('INVALID()', file=f) + else: + print('SUBINSNS({},{},{},"{}")'.\ + format(tag, class_a, class_b, enc), file=f) + elif tag in iset.enc_ext_spaces: + enc = iset.enc_ext_spaces[tag].replace(' ', '') + print('EXTSPACE({},"{}")'.format(tag, enc), file=f) + else: + enc = ''.join(reversed(encs[tag])) + print('TERMINAL({},"{}")'.format(tag, enc), file=f) + else: + print('TABLE_LINK({})'.format(table_name(parents + [node], child)), + file=f) + print('DECODE_END_TABLE({},{},DECODE_SEPARATOR_BITS({},{}))'.\ + format(name, 2 ** width, lsb, width), file=f) + print(file=f) + parents.append(node) + for child in node['children']: + print_node(f, child, parents) + parents.pop() + +def print_tree(f, tree): + print_node(f, tree, []) + +def print_match_info(f): + for tag in sorted(encs.keys(), key=iset.tags.index): + enc = ''.join(reversed(encs[tag])) + mask = int(re.sub(r'[^1]', r'0', enc.replace('0', '1')), 2) + match = int(re.sub(r'[^01]', r'0', enc), 2) + suffix = '' + print('DECODE{}_MATCH_INFO({},0x{:x}U,0x{:x}U)'.\ + format(suffix, tag, mask, match), file=f) + +regre = re.compile( + r'((? 1: + raise Exception('Tag "{}" has split register field!'.\ + format(tag)) + reg_enc_field = reg_enc_fields[0] + if 2 ** len(reg_enc_field) != reg_num_choices: + raise Exception('Tag "{}" has incorrect register field width!'.\ + format(tag)) + print(' DECODE_REG({},{},{})'.\ + format(regno, len(reg_enc_field), enc.index(reg_enc_field)), + file=f) + if reg_type in num_registers and \ + reg_num_choices != num_registers[reg_type]: + print(' DECODE_MAPPED_REG({},{})'.\ + format(regno, reg_mapping), file=f) + regno += 1 + def implicit_register_key(reg): + return implicit_registers[reg] + for reg in sorted( + set([r for r in (iset.iset[tag]['rregs'].split(',') + \ + iset.iset[tag]['wregs'].split(',')) \ + if r in implicit_registers]), key=implicit_register_key): + print(' DECODE_IMPL_REG({},{})'.\ + format(regno, implicit_registers[reg]), file=f) + regno += 1 + if imms and imms[0][0].isupper(): + imms = reversed(imms) + for imm in imms: + if imm[0].isupper(): + immno = 1 + else: + immno = 0 + imm_type = imm[0] + imm_width = int(imm[1]) + imm_shift = imm[2] + if imm_shift: + imm_shift = int(imm_shift) + else: + imm_shift = 0 + if imm_type.islower(): + imm_letter = 'i' + else: + imm_letter = 'I' + remainder = imm_width + for m in reversed(list(re.finditer(imm_letter + '+', enc))): + remainder -= m.end() - m.start() + print(' DECODE_IMM({},{},{},{})'.\ + format(immno, m.end() - m.start(), m.start(), remainder), + file=f) + if remainder != 0: + if imm[2]: + imm[2] = ':' + imm[2] + raise Exception('Tag "{}" has an incorrect number of ' + \ + 'encoding bits for immediate "{}"'.\ + format(tag, ''.join(imm))) + if imm_type.lower() in 'sr': + print(' DECODE_IMM_SXT({},{})'.\ + format(immno, imm_width), file=f) + if imm_type.lower() == 'n': + print(' DECODE_IMM_NEG({},{})'.\ + format(immno, imm_width), file=f) + if imm_shift: + print(' DECODE_IMM_SHIFT({},{})'.\ + format(immno, imm_shift), file=f) + print(')', file=f) + +if __name__ == '__main__': + with open(sys.argv[1], 'w') as f: + print_tree(f, dectree_normal) + print_tree(f, dectree_16bit) + if subinsn_groupings: + print_tree(f, dectree_subinsn_groupings) + for (name, dectree_subinsn) in sorted(dectree_subinsns.items()): + print_tree(f, dectree_subinsn) + for (name, dectree_ext) in sorted(dectree_extensions.items()): + print_tree(f, dectree_ext) + print_match_info(f) + print_op_info(f) From patchwork Wed Feb 17 23:40:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384188 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3229774jao; Wed, 17 Feb 2021 16:04:05 -0800 (PST) X-Google-Smtp-Source: ABdhPJyUGnahanHGt4JxP6f72CAMTJOvfUjZtDg6xVITr5ZDVzd/QDCOMcn1aZoHqn7ONaTaaIZ9 X-Received: by 2002:a25:8e07:: with SMTP id p7mr3102675ybl.244.1613606645212; Wed, 17 Feb 2021 16:04:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606645; cv=none; d=google.com; s=arc-20160816; b=sLzH9Uhw480vk/PNmeRJxSO8jNWfS4Oax8TpYmmnS2EFHT1ZN5GahIpEzx7N2ZJCIc lR5MNsneXkg+wOfgE9QzBmQkwSmwkAqkArowDj0xxsokYq5Z+zpitNMjEnuO3Kn+p+QF WFB5HmYQCD2FdZXWZmy22erS02tUX9UiLQIWmcMFXvpv3U20ZGSC4qWVQBpfPIUBcZUa yV7BxPngAzNHoFWUwDJylPwbZ3VDJAQ9zYL0R23imdIQ6WVBoYO3hABNy03l8S7u4WB1 PHkZWXGB894GiOn5m8zyB/QAFZx/fAnQl3wGGUyqvOcmIKYieNQX9zoeft/gkVuB2WBl 0TMg== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=LIEOAUG+JkwvNv25LtjNH0tsK4duimcTBk2bKR0/Buw=; b=Yyd3AG+IkjV727OiUMKaAmOB7S6tFZWB3fZbB8cNsGEm/hyVOwDmPjjU9QnympgQ7c cW3/fXqt1t7gX3CWuWp3jPipU64xh54pZl0PoQ/P8XlaHwT9MYbZZ1EdDA2CigIGJroy n/jvZoeEtACPZ2C+KGJY5meR10GYNXwbPrM2YYe6YCQHytJAJvFGI2jsHjcfvxdqtsRp mA3gspCy1m7QA/bjFP8EQxuQgATE7SBPaCWQn6I8LDYm44dUjiQRMeL4qTwype2SSktc pgc6uSg9c6dKdIhOPD1JGZxUaW5LP41ItcGmsCoyT6IZoT35G3hDLms2zdg2CPqlj30x sVZg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=krgYlL13; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id f23si4452976ybg.356.2021.02.17.16.04.05 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 16:04:05 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=krgYlL13; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:44494 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWna-0002iV-Ug for patch@linaro.org; Wed, 17 Feb 2021 19:04:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51056) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWRz-0001Af-NH for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:46 -0500 Received: from mail-pg1-x52b.google.com ([2607:f8b0:4864:20::52b]:40186) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRj-0004mV-HB for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:38 -0500 Received: by mail-pg1-x52b.google.com with SMTP id b21so9518501pgk.7 for ; Wed, 17 Feb 2021 15:41:26 -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 :mime-version:content-transfer-encoding; bh=LIEOAUG+JkwvNv25LtjNH0tsK4duimcTBk2bKR0/Buw=; b=krgYlL13NzzTk1X70Fk3CSTVMuaOruZ9+OjCq1fSrUpYmxg9RFAciByp1zeevHDvAi Wm44Mp5M4LLEBpiv+OJ50mc1+X38+2Wk8zmpNQa9v3g1K+sByPDTT/llVwwNj0Eq0qhl tnURF3iXoSF7lAkr9O/hDx1hqXbLYpfiB15yteIlIv2jmb+zAUIiBOPONrL27KGVrL83 DCO9oAJkbtu2uP3L7GYU7bndgXj5KvUIWtjYck+acN9tSKwM49oXD1PMw7vqS5dkn95m trK+3Y6oFKccs/R+JemLfQezzIwNkkxUIWrl13k2hmQFV4Q4RCEBjvzPBi0jkDlFy21R bHGg== 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:mime-version:content-transfer-encoding; bh=LIEOAUG+JkwvNv25LtjNH0tsK4duimcTBk2bKR0/Buw=; b=awuk/7h4yPr3e3nGcvQ23YMbv0WnCH0VbLbvrB2p4AdhOlDZqJ/htxitqri+9KDmv/ OE/NpvIi403IUmTeV/GTAn/bq1B2B89Dst+4N89ZUrKRaxOb+pToHVwnTFzzPFs95xGK osk+s2wSjYFhdaStEXCppl2rvRin0EoGonbWP5hyhyFRtWFpNbKFO/P0ElTeWOgaQT3v fVarn6U8qnAbQ5K8fi47+QuHFFkf+KbIOCKg0f8Oc6a41b7eeUVkPbOK9qe0ym+OjahZ sAhTqCnSusYZVXKVm10ZDTgkgd4Vpom9hroEBZhMWmHlv++nru1fgqJHNXV2oLETZzLV hdmQ== X-Gm-Message-State: AOAM531ZBtFM2CiD6nLqjASaEp5dSsJoCdRc2romiRuSzgr7dViupSlO a5L8npNcoW+kHK3nE8boGQkbhsAb8rUikg== X-Received: by 2002:a62:8453:0:b029:1e4:3a6a:d5ba with SMTP id k80-20020a6284530000b02901e43a6ad5bamr1565727pfd.54.1613605285374; Wed, 17 Feb 2021 15:41:25 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:24 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 24/35] Hexagon (target/hexagon) opcode data structures Date: Wed, 17 Feb 2021 15:40:12 -0800 Message-Id: <20210217234023.1742406-25-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52b; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1612763186-18161-24-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/opcodes.h | 58 ++++++++++++++++ target/hexagon/opcodes.c | 142 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 target/hexagon/opcodes.h create mode 100644 target/hexagon/opcodes.c -- 2.25.1 diff --git a/target/hexagon/opcodes.h b/target/hexagon/opcodes.h new file mode 100644 index 0000000000..6e90e00fe2 --- /dev/null +++ b/target/hexagon/opcodes.h @@ -0,0 +1,58 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_OPCODES_H +#define HEXAGON_OPCODES_H + +typedef enum { +#define OPCODE(IID) IID +#include "opcodes_def_generated.h.inc" + XX_LAST_OPCODE +#undef OPCODE +} Opcode; + +typedef enum { + NORMAL, + HALF, + SUBINSN_A, + SUBINSN_L1, + SUBINSN_L2, + SUBINSN_S1, + SUBINSN_S2, + EXT_noext, + EXT_mmvec, + XX_LAST_ENC_CLASS +} EncClass; + +extern const char * const opcode_names[]; + +extern const char * const opcode_reginfo[]; +extern const char * const opcode_rregs[]; +extern const char * const opcode_wregs[]; + +typedef struct { + const char * const encoding; + const EncClass enc_class; +} OpcodeEncoding; + +extern const OpcodeEncoding opcode_encodings[XX_LAST_OPCODE]; + +void opcode_init(void); + +int opcode_which_immediate_is_extended(Opcode opcode); + +#endif diff --git a/target/hexagon/opcodes.c b/target/hexagon/opcodes.c new file mode 100644 index 0000000000..4eef5fc40f --- /dev/null +++ b/target/hexagon/opcodes.c @@ -0,0 +1,142 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * opcodes.c + * + * data tables generated automatically + * Maybe some functions too + */ + +#include "qemu/osdep.h" +#include "attribs.h" +#include "decode.h" + +#define VEC_DESCR(A, B, C) DESCR(A, B, C) +#define DONAME(X) #X + +const char * const opcode_names[] = { +#define OPCODE(IID) DONAME(IID) +#include "opcodes_def_generated.h.inc" + NULL +#undef OPCODE +}; + +const char * const opcode_reginfo[] = { +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#define REGINFO(TAG, REGINFO, RREGS, WREGS) REGINFO, +#include "op_regs_generated.h.inc" + NULL +#undef REGINFO +#undef IMMINFO +}; + + +const char * const opcode_rregs[] = { +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#define REGINFO(TAG, REGINFO, RREGS, WREGS) RREGS, +#include "op_regs_generated.h.inc" + NULL +#undef REGINFO +#undef IMMINFO +}; + + +const char * const opcode_wregs[] = { +#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */ +#define REGINFO(TAG, REGINFO, RREGS, WREGS) WREGS, +#include "op_regs_generated.h.inc" + NULL +#undef REGINFO +#undef IMMINFO +}; + +const char * const opcode_short_semantics[] = { +#define DEF_SHORTCODE(TAG, SHORTCODE) [TAG] = #SHORTCODE, +#include "shortcode_generated.h.inc" +#undef DEF_SHORTCODE + NULL +}; + +DECLARE_BITMAP(opcode_attribs[XX_LAST_OPCODE], A_ZZ_LASTATTRIB); + +static void init_attribs(int tag, ...) +{ + va_list ap; + int attr; + va_start(ap, tag); + while ((attr = va_arg(ap, int)) != 0) { + set_bit(attr, opcode_attribs[tag]); + } +} + +const OpcodeEncoding opcode_encodings[] = { +#define DEF_ENC32(OPCODE, ENCSTR) \ + [OPCODE] = { .encoding = ENCSTR }, + +#define DEF_ENC_SUBINSN(OPCODE, CLASS, ENCSTR) \ + [OPCODE] = { .encoding = ENCSTR, .enc_class = CLASS }, + +#define DEF_EXT_ENC(OPCODE, CLASS, ENCSTR) \ + [OPCODE] = { .encoding = ENCSTR, .enc_class = CLASS }, + +#include "imported/encode.def" + +#undef DEF_ENC32 +#undef DEF_ENC_SUBINSN +#undef DEF_EXT_ENC +}; + +void opcode_init(void) +{ + init_attribs(0, 0); + +#define ATTRIBS(...) , ## __VA_ARGS__, 0 +#define OP_ATTRIB(TAG, ARGS) init_attribs(TAG ARGS); +#include "op_attribs_generated.h.inc" +#undef OP_ATTRIB +#undef ATTRIBS + + decode_init(); +} + + +#define NEEDLE "IMMEXT(" + +int opcode_which_immediate_is_extended(Opcode opcode) +{ + const char *p; + + g_assert(opcode < XX_LAST_OPCODE); + g_assert(GET_ATTRIB(opcode, A_EXTENDABLE)); + + p = opcode_short_semantics[opcode]; + p = strstr(p, NEEDLE); + g_assert(p); + p += strlen(NEEDLE); + while (isspace(*p)) { + p++; + } + /* lower is always imm 0, upper always imm 1. */ + if (islower(*p)) { + return 0; + } else if (isupper(*p)) { + return 1; + } else { + g_assert_not_reached(); + } +} From patchwork Wed Feb 17 23:40:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384134 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3224097jao; Wed, 17 Feb 2021 15:54:23 -0800 (PST) X-Google-Smtp-Source: ABdhPJxV0cZtS6JaQAvdgvMibfwHxD51wdKWgzDOJ/9tX4iervs76yDuNrohU+t+29oyKIIw5w07 X-Received: by 2002:a25:b88d:: with SMTP id w13mr2601089ybj.500.1613606063219; Wed, 17 Feb 2021 15:54:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606063; cv=none; d=google.com; s=arc-20160816; b=S3YuGUq1laZyAMs0csro6rUXds1HFTPBYxugJtOAdj9JZTm+tlogkSgCyiyAQ8XgO/ WoFlYIxjD1VpDTk1A/h8RkpYyyCEz4vow/SwPXXGrWTCLRgOut5I3jHwzMON5yLuDnMT WwHHBufkl4jpFJSLo2RtyYZAA1dZzhGxXQiakNL0C93rZ9WNxZIPFAajxoB9NyOMIjwn 72EzdxqU1zCY2TMunFKDOwkEN0MX5YABjKVHRS8zsTqUcIPFKGWvQv9b2BU1MZPs1dm8 T5KF56sAVwPg0YCz7SM8It+ENJvMnHg7wmUaCr2k4EZf5trUpsL2GYSMzcI1hngRO6Rt kgqw== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=Sa9/UkqLJdUujZPLxSk8Uy/zXCZTvfLyfmkiIQGV7WM=; b=jkQIlR+bGcN9OwdHDRJyzy0WfAd+1CB8NaG1nGZYahUWOqqPpv+bCGq+giM9f0Xakt h/6sC8KT0KH8v/LDkRRK1/kbDn0YFKpp+5aaa8B8riC132uP0YPF/+Aw3rgDA5bCAJcr D9wYK7sqRIoaPiSW69G1Pm3unGAWQ4MD68W13oipxqMe1mJMkXRCsEtHqwWkJYRFMosb 0MRgWvPFcD9ljB0hrUgOu5hwaz3MetJMpebGZYvqsmORXsQJypMl6WDf1FhbW3v6c77s WH/INpcPcYj91jdvZYuQxOgsDUBk0p/xEi47C2ok3T6XttTl77+oIJi/PHolAkR2oBK3 C3ZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RYdvFC7y; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id d16si3667514ybn.137.2021.02.17.15.54.23 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:54:23 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RYdvFC7y; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:44926 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWeE-0007XV-M2 for patch@linaro.org; Wed, 17 Feb 2021 18:54:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51084) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWS2-0001B6-Ed for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:49 -0500 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]:36662) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRm-0004nN-22 for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:44 -0500 Received: by mail-pf1-x435.google.com with SMTP id z15so41841pfc.3 for ; Wed, 17 Feb 2021 15:41:28 -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 :mime-version:content-transfer-encoding; bh=Sa9/UkqLJdUujZPLxSk8Uy/zXCZTvfLyfmkiIQGV7WM=; b=RYdvFC7yj2MB9wpV6fdCpOv5xsakv8c8d4RcYYYYJHJX8+UuSyNOtdHLbiKuxbHHIj LsMRrf/0qG6cq6PQ5gYHMG4a1gaF+IkL7ytrwvsWN7zr7Pf2AL9RhHCaAXzVhdRbO5EG ESWrOF6QMWb3tEHBhenYNzBV5hG8xklO6ZBFJxXlIHk/HtZ7vrKlrKws61X3wlbEUfYW iwzJl2csgM7IIKz125UUNzPG9PxI4+kJ5MRXnr7RX56V3lgBVQBMh+SjtA44Hz4RxxVw Zol7na3Na7CQjK+Pmc47RtiOsmqy9bETxxG4nwPlnHtfgLay4I+OpU/0DPGaSFrlUPf1 RMYg== 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:mime-version:content-transfer-encoding; bh=Sa9/UkqLJdUujZPLxSk8Uy/zXCZTvfLyfmkiIQGV7WM=; b=s/VgkNfPPSbZQmK0KWLth0fiwcnIxoV3GOl/nr6bc5i3qQF4XozTA5/sRfTRtmfNeY ZlxSHz4/dad/6rACj8k9ZSbkufUUt7rqBrKH8yuhjtef93kipjGcU+D9DAFV7lenbM8h HvjA+AN/bX/bIndcpUCuOHrTi4WNcn7ekIzrnx7YX5jh4RDJXaITjb5n3womNWSQAbnU +8lkRuIcknEc+EraOL+114MrUZwmc+/hrM2fdGEC0tI26R2aOIp4o3qcXcj2vBxBdydr 6aiog/jj6itrDDmqg7tuorQMmUEm1M+hEcqqN4xho43G4Wb3odXH5GnI0fDZOieIv7OU CTJw== X-Gm-Message-State: AOAM533uctEqgrQ2fsFKZLERElNFMGMD96uWigjDIQimu4Du2cozaw0q +gy2FQd74pcNdGD8T67UFSeayZBAPC9kfQ== X-Received: by 2002:a63:f21:: with SMTP id e33mr1598812pgl.84.1613605287273; Wed, 17 Feb 2021 15:41:27 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:26 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 25/35] Hexagon (target/hexagon) macros Date: Wed, 17 Feb 2021 15:40:13 -0800 Message-Id: <20210217234023.1742406-26-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::435; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x435.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson macros to interface with the generator macros referenced in instruction semantics Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-25-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/macros.h | 592 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 592 insertions(+) create mode 100644 target/hexagon/macros.h -- 2.25.1 diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h new file mode 100644 index 0000000000..78c4efb5cb --- /dev/null +++ b/target/hexagon/macros.h @@ -0,0 +1,592 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_MACROS_H +#define HEXAGON_MACROS_H + +#include "cpu.h" +#include "hex_regs.h" +#include "reg_fields.h" + +#ifdef QEMU_GENERATE +#define READ_REG(dest, NUM) gen_read_reg(dest, NUM) +#define READ_PREG(dest, NUM) gen_read_preg(dest, (NUM)) +#else +#define READ_REG(NUM) (env->gpr[(NUM)]) +#define READ_PREG(NUM) (env->pred[NUM]) + +#define WRITE_RREG(NUM, VAL) log_reg_write(env, NUM, VAL, slot) +#define WRITE_PREG(NUM, VAL) log_pred_write(env, NUM, VAL) +#endif + +#define PCALIGN 4 +#define PCALIGN_MASK (PCALIGN - 1) + +#define GET_FIELD(FIELD, REGIN) \ + fEXTRACTU_BITS(REGIN, reg_field_info[FIELD].width, \ + reg_field_info[FIELD].offset) + +#ifdef QEMU_GENERATE +#define GET_USR_FIELD(FIELD, DST) \ + tcg_gen_extract_tl(DST, hex_gpr[HEX_REG_USR], \ + reg_field_info[FIELD].offset, \ + reg_field_info[FIELD].width) + +#define TYPE_INT(X) __builtin_types_compatible_p(typeof(X), int) +#define TYPE_TCGV(X) __builtin_types_compatible_p(typeof(X), TCGv) +#define TYPE_TCGV_I64(X) __builtin_types_compatible_p(typeof(X), TCGv_i64) + +#define SET_USR_FIELD_FUNC(X) \ + __builtin_choose_expr(TYPE_INT(X), \ + gen_set_usr_fieldi, \ + __builtin_choose_expr(TYPE_TCGV(X), \ + gen_set_usr_field, (void)0)) +#define SET_USR_FIELD(FIELD, VAL) \ + SET_USR_FIELD_FUNC(VAL)(FIELD, VAL) +#else +#define GET_USR_FIELD(FIELD) \ + fEXTRACTU_BITS(env->gpr[HEX_REG_USR], reg_field_info[FIELD].width, \ + reg_field_info[FIELD].offset) + +#define SET_USR_FIELD(FIELD, VAL) \ + fINSERT_BITS(env->gpr[HEX_REG_USR], reg_field_info[FIELD].width, \ + reg_field_info[FIELD].offset, (VAL)) +#endif + +#ifdef QEMU_GENERATE +/* + * Section 5.5 of the Hexagon V67 Programmer's Reference Manual + * + * Slot 1 store with slot 0 load + * A slot 1 store operation with a slot 0 load operation can appear in a packet. + * The packet attribute :mem_noshuf inhibits the instruction reordering that + * would otherwise be done by the assembler. For example: + * { + * memw(R5) = R2 // slot 1 store + * R3 = memh(R6) // slot 0 load + * }:mem_noshuf + * Unlike most packetized operations, these memory operations are not executed + * in parallel (Section 3.3.1). Instead, the store instruction in Slot 1 + * effectively executes first, followed by the load instruction in Slot 0. If + * the addresses of the two operations are overlapping, the load will receive + * the newly stored data. This feature is supported in processor versions + * V65 or greater. + * + * + * For qemu, we look for a load in slot 0 when there is a store in slot 1 + * in the same packet. When we see this, we call a helper that merges the + * bytes from the store buffer with the value loaded from memory. + */ +#define CHECK_NOSHUF \ + do { \ + if (insn->slot == 0 && pkt->pkt_has_store_s1) { \ + process_store(ctx, pkt, 1); \ + } \ + } while (0) + +#define MEM_LOAD1s(DST, VA) \ + do { \ + CHECK_NOSHUF; \ + tcg_gen_qemu_ld8s(DST, VA, ctx->mem_idx); \ + } while (0) +#define MEM_LOAD1u(DST, VA) \ + do { \ + CHECK_NOSHUF; \ + tcg_gen_qemu_ld8u(DST, VA, ctx->mem_idx); \ + } while (0) +#define MEM_LOAD2s(DST, VA) \ + do { \ + CHECK_NOSHUF; \ + tcg_gen_qemu_ld16s(DST, VA, ctx->mem_idx); \ + } while (0) +#define MEM_LOAD2u(DST, VA) \ + do { \ + CHECK_NOSHUF; \ + tcg_gen_qemu_ld16u(DST, VA, ctx->mem_idx); \ + } while (0) +#define MEM_LOAD4s(DST, VA) \ + do { \ + CHECK_NOSHUF; \ + tcg_gen_qemu_ld32s(DST, VA, ctx->mem_idx); \ + } while (0) +#define MEM_LOAD4u(DST, VA) \ + do { \ + CHECK_NOSHUF; \ + tcg_gen_qemu_ld32s(DST, VA, ctx->mem_idx); \ + } while (0) +#define MEM_LOAD8u(DST, VA) \ + do { \ + CHECK_NOSHUF; \ + tcg_gen_qemu_ld64(DST, VA, ctx->mem_idx); \ + } while (0) +#else +#define MEM_LOAD1s(VA) ((int8_t)mem_load1(env, slot, VA)) +#define MEM_LOAD1u(VA) ((uint8_t)mem_load1(env, slot, VA)) +#define MEM_LOAD2s(VA) ((int16_t)mem_load2(env, slot, VA)) +#define MEM_LOAD2u(VA) ((uint16_t)mem_load2(env, slot, VA)) +#define MEM_LOAD4s(VA) ((int32_t)mem_load4(env, slot, VA)) +#define MEM_LOAD4u(VA) ((uint32_t)mem_load4(env, slot, VA)) +#define MEM_LOAD8s(VA) ((int64_t)mem_load8(env, slot, VA)) +#define MEM_LOAD8u(VA) ((uint64_t)mem_load8(env, slot, VA)) + +#define MEM_STORE1(VA, DATA, SLOT) log_store32(env, VA, DATA, 1, SLOT) +#define MEM_STORE2(VA, DATA, SLOT) log_store32(env, VA, DATA, 2, SLOT) +#define MEM_STORE4(VA, DATA, SLOT) log_store32(env, VA, DATA, 4, SLOT) +#define MEM_STORE8(VA, DATA, SLOT) log_store64(env, VA, DATA, 8, SLOT) +#endif + +#define CANCEL cancel_slot(env, slot) + +#define LOAD_CANCEL(EA) do { CANCEL; } while (0) + +#ifdef QEMU_GENERATE +static inline void gen_pred_cancel(TCGv pred, int slot_num) + { + TCGv slot_mask = tcg_const_tl(1 << slot_num); + TCGv tmp = tcg_temp_new(); + TCGv zero = tcg_const_tl(0); + TCGv one = tcg_const_tl(1); + tcg_gen_or_tl(slot_mask, hex_slot_cancelled, slot_mask); + tcg_gen_andi_tl(tmp, pred, 1); + tcg_gen_movcond_tl(TCG_COND_EQ, hex_slot_cancelled, tmp, zero, + slot_mask, hex_slot_cancelled); + tcg_temp_free(slot_mask); + tcg_temp_free(tmp); + tcg_temp_free(zero); + tcg_temp_free(one); +} +#define PRED_LOAD_CANCEL(PRED, EA) \ + gen_pred_cancel(PRED, insn->is_endloop ? 4 : insn->slot) +#endif + +#define STORE_CANCEL(EA) { env->slot_cancelled |= (1 << slot); } + +#define fMAX(A, B) (((A) > (B)) ? (A) : (B)) + +#define fMIN(A, B) (((A) < (B)) ? (A) : (B)) + +#define fABS(A) (((A) < 0) ? (-(A)) : (A)) +#define fINSERT_BITS(REG, WIDTH, OFFSET, INVAL) \ + REG = ((WIDTH) ? deposit64(REG, (OFFSET), (WIDTH), (INVAL)) : REG) +#define fEXTRACTU_BITS(INREG, WIDTH, OFFSET) \ + ((WIDTH) ? extract64((INREG), (OFFSET), (WIDTH)) : 0LL) +#define fEXTRACTU_BIDIR(INREG, WIDTH, OFFSET) \ + (fZXTN(WIDTH, 32, fBIDIR_LSHIFTR((INREG), (OFFSET), 4_8))) +#define fEXTRACTU_RANGE(INREG, HIBIT, LOWBIT) \ + (((HIBIT) - (LOWBIT) + 1) ? \ + extract64((INREG), (LOWBIT), ((HIBIT) - (LOWBIT) + 1)) : \ + 0LL) + +#define f8BITSOF(VAL) ((VAL) ? 0xff : 0x00) + +#ifdef QEMU_GENERATE +#define fLSBOLD(VAL) tcg_gen_andi_tl(LSB, (VAL), 1) +#else +#define fLSBOLD(VAL) ((VAL) & 1) +#endif + +#ifdef QEMU_GENERATE +#define fLSBNEW(PVAL) tcg_gen_mov_tl(LSB, (PVAL)) +#define fLSBNEW0 tcg_gen_mov_tl(LSB, hex_new_pred_value[0]) +#define fLSBNEW1 tcg_gen_mov_tl(LSB, hex_new_pred_value[1]) +#else +#define fLSBNEW(PVAL) (PVAL) +#define fLSBNEW0 new_pred_value(env, 0) +#define fLSBNEW1 new_pred_value(env, 1) +#endif + +#ifdef QEMU_GENERATE +static inline void gen_logical_not(TCGv dest, TCGv src) +{ + TCGv one = tcg_const_tl(1); + TCGv zero = tcg_const_tl(0); + + tcg_gen_movcond_tl(TCG_COND_NE, dest, src, zero, zero, one); + + tcg_temp_free(one); + tcg_temp_free(zero); +} +#define fLSBOLDNOT(VAL) \ + do { \ + tcg_gen_andi_tl(LSB, (VAL), 1); \ + tcg_gen_xori_tl(LSB, LSB, 1); \ + } while (0) +#define fLSBNEWNOT(PNUM) \ + gen_logical_not(LSB, (PNUM)) +#else +#define fLSBNEWNOT(PNUM) (!fLSBNEW(PNUM)) +#define fLSBOLDNOT(VAL) (!fLSBOLD(VAL)) +#define fLSBNEW0NOT (!fLSBNEW0) +#define fLSBNEW1NOT (!fLSBNEW1) +#endif + +#define fNEWREG(VAL) ((int32_t)(VAL)) + +#define fNEWREG_ST(VAL) (VAL) + +#define fSATUVALN(N, VAL) \ + ({ \ + fSET_OVERFLOW(); \ + ((VAL) < 0) ? 0 : ((1LL << (N)) - 1); \ + }) +#define fSATVALN(N, VAL) \ + ({ \ + fSET_OVERFLOW(); \ + ((VAL) < 0) ? (-(1LL << ((N) - 1))) : ((1LL << ((N) - 1)) - 1); \ + }) +#define fZXTN(N, M, VAL) (((N) != 0) ? extract64((VAL), 0, (N)) : 0LL) +#define fSXTN(N, M, VAL) (((N) != 0) ? sextract64((VAL), 0, (N)) : 0LL) +#define fSATN(N, VAL) \ + ((fSXTN(N, 64, VAL) == (VAL)) ? (VAL) : fSATVALN(N, VAL)) +#define fADDSAT64(DST, A, B) \ + do { \ + uint64_t __a = fCAST8u(A); \ + uint64_t __b = fCAST8u(B); \ + uint64_t __sum = __a + __b; \ + uint64_t __xor = __a ^ __b; \ + const uint64_t __mask = 0x8000000000000000ULL; \ + if (__xor & __mask) { \ + DST = __sum; \ + } \ + else if ((__a ^ __sum) & __mask) { \ + if (__sum & __mask) { \ + DST = 0x7FFFFFFFFFFFFFFFLL; \ + fSET_OVERFLOW(); \ + } else { \ + DST = 0x8000000000000000LL; \ + fSET_OVERFLOW(); \ + } \ + } else { \ + DST = __sum; \ + } \ + } while (0) +#define fSATUN(N, VAL) \ + ((fZXTN(N, 64, VAL) == (VAL)) ? (VAL) : fSATUVALN(N, VAL)) +#define fSATH(VAL) (fSATN(16, VAL)) +#define fSATUH(VAL) (fSATUN(16, VAL)) +#define fSATUB(VAL) (fSATUN(8, VAL)) +#define fSATB(VAL) (fSATN(8, VAL)) +#define fIMMEXT(IMM) (IMM = IMM) +#define fMUST_IMMEXT(IMM) fIMMEXT(IMM) + +#define fPCALIGN(IMM) IMM = (IMM & ~PCALIGN_MASK) + +#define fREAD_LR() (READ_REG(HEX_REG_LR)) + +#define fWRITE_LR(A) WRITE_RREG(HEX_REG_LR, A) +#define fWRITE_FP(A) WRITE_RREG(HEX_REG_FP, A) +#define fWRITE_SP(A) WRITE_RREG(HEX_REG_SP, A) + +#define fREAD_SP() (READ_REG(HEX_REG_SP)) +#define fREAD_LC0 (READ_REG(HEX_REG_LC0)) +#define fREAD_LC1 (READ_REG(HEX_REG_LC1)) +#define fREAD_SA0 (READ_REG(HEX_REG_SA0)) +#define fREAD_SA1 (READ_REG(HEX_REG_SA1)) +#define fREAD_FP() (READ_REG(HEX_REG_FP)) +#ifdef FIXME +/* Figure out how to get insn->extension_valid to helper */ +#define fREAD_GP() \ + (insn->extension_valid ? 0 : READ_REG(HEX_REG_GP)) +#else +#define fREAD_GP() READ_REG(HEX_REG_GP) +#endif +#define fREAD_PC() (READ_REG(HEX_REG_PC)) + +#define fREAD_NPC() (env->next_PC & (0xfffffffe)) + +#define fREAD_P0() (READ_PREG(0)) +#define fREAD_P3() (READ_PREG(3)) + +#define fCHECK_PCALIGN(A) + +#define fWRITE_NPC(A) write_new_pc(env, A) + +#define fBRANCH(LOC, TYPE) fWRITE_NPC(LOC) +#define fJUMPR(REGNO, TARGET, TYPE) fBRANCH(TARGET, COF_TYPE_JUMPR) +#define fHINTJR(TARGET) { /* Not modelled in qemu */} +#define fCALL(A) \ + do { \ + fWRITE_LR(fREAD_NPC()); \ + fBRANCH(A, COF_TYPE_CALL); \ + } while (0) +#define fCALLR(A) \ + do { \ + fWRITE_LR(fREAD_NPC()); \ + fBRANCH(A, COF_TYPE_CALLR); \ + } while (0) +#define fWRITE_LOOP_REGS0(START, COUNT) \ + do { \ + WRITE_RREG(HEX_REG_LC0, COUNT); \ + WRITE_RREG(HEX_REG_SA0, START); \ + } while (0) +#define fWRITE_LOOP_REGS1(START, COUNT) \ + do { \ + WRITE_RREG(HEX_REG_LC1, COUNT); \ + WRITE_RREG(HEX_REG_SA1, START);\ + } while (0) +#define fWRITE_LC0(VAL) WRITE_RREG(HEX_REG_LC0, VAL) +#define fWRITE_LC1(VAL) WRITE_RREG(HEX_REG_LC1, VAL) + +#define fCARRY_FROM_ADD(A, B, C) carry_from_add64(A, B, C) + +#define fSET_OVERFLOW() SET_USR_FIELD(USR_OVF, 1) +#define fSET_LPCFG(VAL) SET_USR_FIELD(USR_LPCFG, (VAL)) +#define fGET_LPCFG (GET_USR_FIELD(USR_LPCFG)) +#define fWRITE_P0(VAL) WRITE_PREG(0, VAL) +#define fWRITE_P1(VAL) WRITE_PREG(1, VAL) +#define fWRITE_P2(VAL) WRITE_PREG(2, VAL) +#define fWRITE_P3(VAL) WRITE_PREG(3, VAL) +#define fPART1(WORK) if (part1) { WORK; return; } +#define fCAST4u(A) ((uint32_t)(A)) +#define fCAST4s(A) ((int32_t)(A)) +#define fCAST8u(A) ((uint64_t)(A)) +#define fCAST8s(A) ((int64_t)(A)) +#define fCAST4_4s(A) ((int32_t)(A)) +#define fCAST4_4u(A) ((uint32_t)(A)) +#define fCAST4_8s(A) ((int64_t)((int32_t)(A))) +#define fCAST4_8u(A) ((uint64_t)((uint32_t)(A))) +#define fCAST8_8s(A) ((int64_t)(A)) +#define fCAST8_8u(A) ((uint64_t)(A)) +#define fCAST2_8s(A) ((int64_t)((int16_t)(A))) +#define fCAST2_8u(A) ((uint64_t)((uint16_t)(A))) +#define fZE8_16(A) ((int16_t)((uint8_t)(A))) +#define fSE8_16(A) ((int16_t)((int8_t)(A))) +#define fSE16_32(A) ((int32_t)((int16_t)(A))) +#define fZE16_32(A) ((uint32_t)((uint16_t)(A))) +#define fSE32_64(A) ((int64_t)((int32_t)(A))) +#define fZE32_64(A) ((uint64_t)((uint32_t)(A))) +#define fSE8_32(A) ((int32_t)((int8_t)(A))) +#define fZE8_32(A) ((int32_t)((uint8_t)(A))) +#define fMPY8UU(A, B) (int)(fZE8_16(A) * fZE8_16(B)) +#define fMPY8US(A, B) (int)(fZE8_16(A) * fSE8_16(B)) +#define fMPY8SU(A, B) (int)(fSE8_16(A) * fZE8_16(B)) +#define fMPY8SS(A, B) (int)((short)(A) * (short)(B)) +#define fMPY16SS(A, B) fSE32_64(fSE16_32(A) * fSE16_32(B)) +#define fMPY16UU(A, B) fZE32_64(fZE16_32(A) * fZE16_32(B)) +#define fMPY16SU(A, B) fSE32_64(fSE16_32(A) * fZE16_32(B)) +#define fMPY16US(A, B) fMPY16SU(B, A) +#define fMPY32SS(A, B) (fSE32_64(A) * fSE32_64(B)) +#define fMPY32UU(A, B) (fZE32_64(A) * fZE32_64(B)) +#define fMPY32SU(A, B) (fSE32_64(A) * fZE32_64(B)) +#define fMPY3216SS(A, B) (fSE32_64(A) * fSXTN(16, 64, B)) +#define fMPY3216SU(A, B) (fSE32_64(A) * fZXTN(16, 64, B)) +#define fROUND(A) (A + 0x8000) +#define fCLIP(DST, SRC, U) \ + do { \ + int32_t maxv = (1 << U) - 1; \ + int32_t minv = -(1 << U); \ + DST = fMIN(maxv, fMAX(SRC, minv)); \ + } while (0) +#define fCRND(A) ((((A) & 0x3) == 0x3) ? ((A) + 1) : ((A))) +#define fRNDN(A, N) ((((N) == 0) ? (A) : (((fSE32_64(A)) + (1 << ((N) - 1)))))) +#define fCRNDN(A, N) (conv_round(A, N)) +#define fADD128(A, B) (int128_add(A, B)) +#define fSUB128(A, B) (int128_sub(A, B)) +#define fSHIFTR128(A, B) (int128_rshift(A, B)) +#define fSHIFTL128(A, B) (int128_lshift(A, B)) +#define fAND128(A, B) (int128_and(A, B)) +#define fCAST8S_16S(A) (int128_exts64(A)) +#define fCAST16S_8S(A) (int128_getlo(A)) + +#define fEA_RI(REG, IMM) \ + do { \ + EA = REG + IMM; \ + } while (0) +#define fEA_RRs(REG, REG2, SCALE) \ + do { \ + EA = REG + (REG2 << SCALE); \ + } while (0) +#define fEA_IRs(IMM, REG, SCALE) \ + do { \ + EA = IMM + (REG << SCALE); \ + } while (0) + +#ifdef QEMU_GENERATE +#define fEA_IMM(IMM) tcg_gen_movi_tl(EA, IMM) +#define fEA_REG(REG) tcg_gen_mov_tl(EA, REG) +#define fPM_I(REG, IMM) tcg_gen_addi_tl(REG, REG, IMM) +#define fPM_M(REG, MVAL) tcg_gen_add_tl(REG, REG, MVAL) +#else +#define fEA_IMM(IMM) do { EA = (IMM); } while (0) +#define fEA_REG(REG) do { EA = (REG); } while (0) +#define fEA_GPI(IMM) do { EA = (fREAD_GP() + (IMM)); } while (0) +#define fPM_I(REG, IMM) do { REG = REG + (IMM); } while (0) +#define fPM_M(REG, MVAL) do { REG = REG + (MVAL); } while (0) +#endif +#define fSCALE(N, A) (((int64_t)(A)) << N) +#define fSATW(A) fSATN(32, ((long long)A)) +#define fSAT(A) fSATN(32, (A)) +#define fSAT_ORIG_SHL(A, ORIG_REG) \ + ((((int32_t)((fSAT(A)) ^ ((int32_t)(ORIG_REG)))) < 0) \ + ? fSATVALN(32, ((int32_t)(ORIG_REG))) \ + : ((((ORIG_REG) > 0) && ((A) == 0)) ? fSATVALN(32, (ORIG_REG)) \ + : fSAT(A))) +#define fPASS(A) A +#define fBIDIR_SHIFTL(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) >> ((-(SHAMT)) - 1)) >> 1) \ + : (fCAST##REGSTYPE(SRC) << (SHAMT))) +#define fBIDIR_ASHIFTL(SRC, SHAMT, REGSTYPE) \ + fBIDIR_SHIFTL(SRC, SHAMT, REGSTYPE##s) +#define fBIDIR_LSHIFTL(SRC, SHAMT, REGSTYPE) \ + fBIDIR_SHIFTL(SRC, SHAMT, REGSTYPE##u) +#define fBIDIR_ASHIFTL_SAT(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) < 0) ? ((fCAST##REGSTYPE##s(SRC) >> ((-(SHAMT)) - 1)) >> 1) \ + : fSAT_ORIG_SHL(fCAST##REGSTYPE##s(SRC) << (SHAMT), (SRC))) +#define fBIDIR_SHIFTR(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) << ((-(SHAMT)) - 1)) << 1) \ + : (fCAST##REGSTYPE(SRC) >> (SHAMT))) +#define fBIDIR_ASHIFTR(SRC, SHAMT, REGSTYPE) \ + fBIDIR_SHIFTR(SRC, SHAMT, REGSTYPE##s) +#define fBIDIR_LSHIFTR(SRC, SHAMT, REGSTYPE) \ + fBIDIR_SHIFTR(SRC, SHAMT, REGSTYPE##u) +#define fBIDIR_ASHIFTR_SAT(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) < 0) ? fSAT_ORIG_SHL((fCAST##REGSTYPE##s(SRC) \ + << ((-(SHAMT)) - 1)) << 1, (SRC)) \ + : (fCAST##REGSTYPE##s(SRC) >> (SHAMT))) +#define fASHIFTR(SRC, SHAMT, REGSTYPE) (fCAST##REGSTYPE##s(SRC) >> (SHAMT)) +#define fLSHIFTR(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) >= 64) ? 0 : (fCAST##REGSTYPE##u(SRC) >> (SHAMT))) +#define fROTL(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) == 0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) << (SHAMT)) | \ + ((fCAST##REGSTYPE##u(SRC) >> \ + ((sizeof(SRC) * 8) - (SHAMT)))))) +#define fROTR(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) == 0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) >> (SHAMT)) | \ + ((fCAST##REGSTYPE##u(SRC) << \ + ((sizeof(SRC) * 8) - (SHAMT)))))) +#define fASHIFTL(SRC, SHAMT, REGSTYPE) \ + (((SHAMT) >= 64) ? 0 : (fCAST##REGSTYPE##s(SRC) << (SHAMT))) + +#ifdef QEMU_GENERATE +#define fLOAD(NUM, SIZE, SIGN, EA, DST) MEM_LOAD##SIZE##SIGN(DST, EA) +#else +#define fLOAD(NUM, SIZE, SIGN, EA, DST) \ + DST = (size##SIZE##SIGN##_t)MEM_LOAD##SIZE##SIGN(EA) +#endif + +#define fMEMOP(NUM, SIZE, SIGN, EA, FNTYPE, VALUE) + +#define fGET_FRAMEKEY() READ_REG(HEX_REG_FRAMEKEY) +#define fFRAME_SCRAMBLE(VAL) ((VAL) ^ (fCAST8u(fGET_FRAMEKEY()) << 32)) +#define fFRAME_UNSCRAMBLE(VAL) fFRAME_SCRAMBLE(VAL) + +#ifdef CONFIG_USER_ONLY +#define fFRAMECHECK(ADDR, EA) do { } while (0) /* Not modelled in linux-user */ +#else +/* System mode not implemented yet */ +#define fFRAMECHECK(ADDR, EA) g_assert_not_reached(); +#endif + +#ifdef QEMU_GENERATE +#define fLOAD_LOCKED(NUM, SIZE, SIGN, EA, DST) \ + gen_load_locked##SIZE##SIGN(DST, EA, ctx->mem_idx); +#endif + +#define fSTORE(NUM, SIZE, EA, SRC) MEM_STORE##SIZE(EA, SRC, slot) + +#ifdef QEMU_GENERATE +#define fSTORE_LOCKED(NUM, SIZE, EA, SRC, PRED) \ + gen_store_conditional##SIZE(env, ctx, PdN, PRED, EA, SRC); +#endif + +#define fGETBYTE(N, SRC) ((int8_t)((SRC >> ((N) * 8)) & 0xff)) +#define fGETUBYTE(N, SRC) ((uint8_t)((SRC >> ((N) * 8)) & 0xff)) + +#define fSETBYTE(N, DST, VAL) \ + do { \ + DST = (DST & ~(0x0ffLL << ((N) * 8))) | \ + (((uint64_t)((VAL) & 0x0ffLL)) << ((N) * 8)); \ + } while (0) +#define fGETHALF(N, SRC) ((int16_t)((SRC >> ((N) * 16)) & 0xffff)) +#define fGETUHALF(N, SRC) ((uint16_t)((SRC >> ((N) * 16)) & 0xffff)) +#define fSETHALF(N, DST, VAL) \ + do { \ + DST = (DST & ~(0x0ffffLL << ((N) * 16))) | \ + (((uint64_t)((VAL) & 0x0ffff)) << ((N) * 16)); \ + } while (0) +#define fSETHALFw fSETHALF +#define fSETHALFd fSETHALF + +#define fGETWORD(N, SRC) \ + ((int64_t)((int32_t)((SRC >> ((N) * 32)) & 0x0ffffffffLL))) +#define fGETUWORD(N, SRC) \ + ((uint64_t)((uint32_t)((SRC >> ((N) * 32)) & 0x0ffffffffLL))) + +#define fSETWORD(N, DST, VAL) \ + do { \ + DST = (DST & ~(0x0ffffffffLL << ((N) * 32))) | \ + (((VAL) & 0x0ffffffffLL) << ((N) * 32)); \ + } while (0) + +#define fSETBIT(N, DST, VAL) \ + do { \ + DST = (DST & ~(1ULL << (N))) | (((uint64_t)(VAL)) << (N)); \ + } while (0) + +#define fGETBIT(N, SRC) (((SRC) >> N) & 1) +#define fSETBITS(HI, LO, DST, VAL) \ + do { \ + int j; \ + for (j = LO; j <= HI; j++) { \ + fSETBIT(j, DST, VAL); \ + } \ + } while (0) +#define fCOUNTONES_4(VAL) ctpop32(VAL) +#define fCOUNTONES_8(VAL) ctpop64(VAL) +#define fBREV_8(VAL) revbit64(VAL) +#define fBREV_4(VAL) revbit32(VAL) +#define fCL1_8(VAL) clo64(VAL) +#define fCL1_4(VAL) clo32(VAL) +#define fINTERLEAVE(ODD, EVEN) interleave(ODD, EVEN) +#define fDEINTERLEAVE(MIXED) deinterleave(MIXED) +#define fHIDE(A) A +#define fCONSTLL(A) A##LL +#define fECHO(A) (A) + +#define fTRAP(TRAPTYPE, IMM) helper_raise_exception(env, HEX_EXCP_TRAP0) +#define fPAUSE(IMM) + +#define fALIGN_REG_FIELD_VALUE(FIELD, VAL) \ + ((VAL) << reg_field_info[FIELD].offset) +#define fGET_REG_FIELD_MASK(FIELD) \ + (((1 << reg_field_info[FIELD].width) - 1) << reg_field_info[FIELD].offset) +#define fREAD_REG_FIELD(REG, FIELD) \ + fEXTRACTU_BITS(env->gpr[HEX_REG_##REG], \ + reg_field_info[FIELD].width, \ + reg_field_info[FIELD].offset) +#define fGET_FIELD(VAL, FIELD) +#define fSET_FIELD(VAL, FIELD, NEWVAL) +#define fBARRIER() +#define fSYNCH() +#define fISYNC() +#define fDCFETCH(REG) \ + do { (void)REG; } while (0) /* Nothing to do in qemu */ +#define fICINVA(REG) \ + do { (void)REG; } while (0) /* Nothing to do in qemu */ +#define fL2FETCH(ADDR, HEIGHT, WIDTH, STRIDE, FLAGS) +#define fDCCLEANA(REG) \ + do { (void)REG; } while (0) /* Nothing to do in qemu */ +#define fDCCLEANINVA(REG) \ + do { (void)REG; } while (0) /* Nothing to do in qemu */ + +#define fDCZEROA(REG) do { env->dczero_addr = (REG); } while (0) + +#define fBRANCH_SPECULATE_STALL(DOTNEWVAL, JUMP_COND, SPEC_DIR, HINTBITNUM, \ + STRBITNUM) /* Nothing */ + + +#endif From patchwork Wed Feb 17 23:40:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384178 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3225806jao; Wed, 17 Feb 2021 15:57:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJxVvjQwdmfdHltROsL4F91ZzM7nhvFkHSocOF180hncpJNdZ6kWqUWcCK3OsinmkNUPH/OM X-Received: by 2002:a25:2f97:: with SMTP id v145mr2921868ybv.221.1613606249368; Wed, 17 Feb 2021 15:57:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606249; cv=none; d=google.com; s=arc-20160816; b=JwH4uTTAHs5AaUenWVOfDYC4UG81CM7t/+ubX7dvAT3SGPELcnGuIQsi+Bvo+yzlNC TK0K++joYcN2PjYX2fnr3JeMu7sGSDRRx3/f+rndiIw1b09AA6T1B15g/h8TmsD2Ea2f gJF/h8Wj/t8+KBII4MnL4Gg7iJOt1kcTZruGIhDY+6k5JLzoom45ux7bK0xWOOQ+572H D9uksA2mhM9m8cdH5f8r1TakNmdAH2FR2bHlhD05I+M1GCAEkvpE7E5Uo7isD8K5/kK7 RlDOozo6WDOwciwkql/cC9cdw2XdiuKegvksYimJDbdfYyAVR81O9mSKlEvvXmEuHFRr 7Dog== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=Pub1cw4RCa7xktMR4FG9lmGr2Lg5MrccZBgr+bN6ao8=; b=N2UT++tJDPhYFDwywbUcpKBX48ZFpmMYsjlrDrwrLVaRJAMtjFMWSZ+tZ6eem9IGQk OyClpA+abmn1BC5yROCAZfzuYB1oUyF01PJFjycsY1uLg5shyFgfXI3gmpTPnQ59AZKm yKUKijrIk/mZTs0XhbzqD2O9zqaNALFUMlWRbhx5OOj3bUfWxCvEsMBaJdqbks+f2Oih 5wlY9ZexSFE7myxuzsTF9Bfr8dsYJCB74mCPJWcqHG/9t5ZOHYs3VLlRegwXb8JhfX0B HGLNcaeLscTZif1tkiVXqQjbFO0rdC8kfwykVV1v5iHTHUVN7YsxQ0qeWLZAF0KmcfVm sxgQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VffgVpqM; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id w190si3780525ybg.90.2021.02.17.15.57.29 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:57:29 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VffgVpqM; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:51630 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWhE-00024G-QS for patch@linaro.org; Wed, 17 Feb 2021 18:57:28 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51098) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWS3-0001BB-Ce for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:49 -0500 Received: from mail-pf1-x430.google.com ([2607:f8b0:4864:20::430]:33027) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRo-0004oF-8d for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:45 -0500 Received: by mail-pf1-x430.google.com with SMTP id z6so52889pfq.0 for ; Wed, 17 Feb 2021 15:41:29 -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 :mime-version:content-transfer-encoding; bh=Pub1cw4RCa7xktMR4FG9lmGr2Lg5MrccZBgr+bN6ao8=; b=VffgVpqMeXbBZDscd9OEHtBOv49G7KRn87PiuJKW5QtdjYeJ8X67oEEB95ZULKrSCl ENPrVfFrQAG4MSNrsJ6ikH0onkAtxjbVpyVlx7U+Z82brWbWn8uIP1NemdyJwncyPb/C KRqsjMdg/1eA8hOo4G/ftKD5/+nsFhz/W+Jd2MOsNler8YcHXheFVLbPsNQ5oKW0+PH6 pwNnQbbqbhJXGhi7pd0hff1w2laKO8YwV/DJ09PPgh1Kaf+HEwkFEE3Pjcws/Z8fkzRa P4djjN8IW1Br/FL5uKQj/ksDFO8PZGngjhXDYMyQ5u4qmhFwnVQi6cnEWJ4TCwFYBPUH LBOQ== 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:mime-version:content-transfer-encoding; bh=Pub1cw4RCa7xktMR4FG9lmGr2Lg5MrccZBgr+bN6ao8=; b=NBbyBJmwD/HOLgvC8vCatP/CD41B+6ixM5CyN5jU5c5oUDFsocWdhGOJG1a3Yi6tPv QAbfs670BQru1lrGynptzsYr3LcuLH8g25J81KnnXFy4MO1FP75Eb3Lp7zi49D2rby3l mPg5LprpBJqqD8XTop4WX08soGu0jXK9U8JTBT/q4ZiyoL+n6L45RNlNsmioqsgsHWuB BWZiCbNaM1bWC/4s8HZWs0E0v1yZsKWkMyqj/bkoGm5skZpoOHYQ0xukPixilci1geLc uud3Vja3vLOSASNhREA19IYfFzlBUgYdcqftHXvYe0wGOX5HuXvqCjrFGPiAlp2xM/FO lZzw== X-Gm-Message-State: AOAM530dvCt2/BH0r5OtNe7u98g4osAxorlDnAeZJtMNokfjMIi9HJq6 cixs5pyjYydLQilog+uIFIO1Mh8mgm4lHQ== X-Received: by 2002:a63:fe13:: with SMTP id p19mr1569289pgh.119.1613605288795; Wed, 17 Feb 2021 15:41:28 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:28 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 26/35] Hexagon (target/hexagon) instruction classes Date: Wed, 17 Feb 2021 15:40:14 -0800 Message-Id: <20210217234023.1742406-27-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::430; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Determine legal VLIW slots for each instruction Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-26-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/iclass.h | 50 ++++++++++++++++++++ target/hexagon/iclass.c | 73 ++++++++++++++++++++++++++++++ target/hexagon/imported/iclass.def | 51 +++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 target/hexagon/iclass.h create mode 100644 target/hexagon/iclass.c create mode 100644 target/hexagon/imported/iclass.def -- 2.25.1 diff --git a/target/hexagon/iclass.h b/target/hexagon/iclass.h new file mode 100644 index 0000000000..78d372621a --- /dev/null +++ b/target/hexagon/iclass.h @@ -0,0 +1,50 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_ICLASS_H +#define HEXAGON_ICLASS_H + +#include "attribs.h" + +#define ICLASS_FROM_TYPE(TYPE) ICLASS_##TYPE + +enum { + +#define DEF_PP_ICLASS32(TYPE, SLOTS, UNITS) ICLASS_FROM_TYPE(TYPE), +#define DEF_EE_ICLASS32(TYPE, SLOTS, UNITS) ICLASS_FROM_TYPE(TYPE), +#include "imported/iclass.def" +#undef DEF_PP_ICLASS32 +#undef DEF_EE_ICLASS32 + + ICLASS_FROM_TYPE(COPROC_VX), + ICLASS_FROM_TYPE(COPROC_VMEM), + NUM_ICLASSES +}; + +typedef enum { + SLOTS_0 = (1 << 0), + SLOTS_1 = (1 << 1), + SLOTS_2 = (1 << 2), + SLOTS_3 = (1 << 3), + SLOTS_01 = SLOTS_0 | SLOTS_1, + SLOTS_23 = SLOTS_2 | SLOTS_3, + SLOTS_0123 = SLOTS_0 | SLOTS_1 | SLOTS_2 | SLOTS_3, +} SlotMask; + +SlotMask find_iclass_slots(Opcode opcode, int itype); + +#endif diff --git a/target/hexagon/iclass.c b/target/hexagon/iclass.c new file mode 100644 index 0000000000..378d8a6a75 --- /dev/null +++ b/target/hexagon/iclass.c @@ -0,0 +1,73 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "iclass.h" + +static const SlotMask iclass_info[] = { + +#define DEF_PP_ICLASS32(TYPE, SLOTS, UNITS) \ + [ICLASS_FROM_TYPE(TYPE)] = SLOTS_##SLOTS, +#define DEF_EE_ICLASS32(TYPE, SLOTS, UNITS) \ + [ICLASS_FROM_TYPE(TYPE)] = SLOTS_##SLOTS, +#include "imported/iclass.def" +#undef DEF_PP_ICLASS32 +#undef DEF_EE_ICLASS32 +}; + +SlotMask find_iclass_slots(Opcode opcode, int itype) +{ + /* There are some exceptions to what the iclass dictates */ + if (GET_ATTRIB(opcode, A_ICOP)) { + return SLOTS_2; + } else if (GET_ATTRIB(opcode, A_RESTRICT_SLOT0ONLY)) { + return SLOTS_0; + } else if (GET_ATTRIB(opcode, A_RESTRICT_SLOT1ONLY)) { + return SLOTS_1; + } else if (GET_ATTRIB(opcode, A_RESTRICT_SLOT2ONLY)) { + return SLOTS_2; + } else if (GET_ATTRIB(opcode, A_RESTRICT_SLOT3ONLY)) { + return SLOTS_3; + } else if (GET_ATTRIB(opcode, A_COF) && + GET_ATTRIB(opcode, A_INDIRECT) && + !GET_ATTRIB(opcode, A_MEMLIKE) && + !GET_ATTRIB(opcode, A_MEMLIKE_PACKET_RULES)) { + return SLOTS_2; + } else if (GET_ATTRIB(opcode, A_RESTRICT_NOSLOT1)) { + return SLOTS_0; + } else if ((opcode == J2_trap0) || + (opcode == Y2_isync) || + (opcode == J2_pause) || (opcode == J4_hintjumpr)) { + return SLOTS_2; + } else if ((itype == ICLASS_V2LDST) && (GET_ATTRIB(opcode, A_STORE))) { + return SLOTS_01; + } else if ((itype == ICLASS_V2LDST) && (!GET_ATTRIB(opcode, A_STORE))) { + return SLOTS_01; + } else if (GET_ATTRIB(opcode, A_CRSLOT23)) { + return SLOTS_23; + } else if (GET_ATTRIB(opcode, A_RESTRICT_PREFERSLOT0)) { + return SLOTS_0; + } else if (GET_ATTRIB(opcode, A_SUBINSN)) { + return SLOTS_01; + } else if (GET_ATTRIB(opcode, A_CALL)) { + return SLOTS_23; + } else if ((opcode == J4_jumpseti) || (opcode == J4_jumpsetr)) { + return SLOTS_23; + } else { + return iclass_info[itype]; + } +} diff --git a/target/hexagon/imported/iclass.def b/target/hexagon/imported/iclass.def new file mode 100644 index 0000000000..fb57968c6c --- /dev/null +++ b/target/hexagon/imported/iclass.def @@ -0,0 +1,51 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* DEF_*(TYPE,SLOTS,UNITS) */ +DEF_PP_ICLASS32(EXTENDER,0123,LDST|SUNIT|MUNIT) /* 0 */ +DEF_PP_ICLASS32(CJ,0123,CTRLFLOW) /* 1 */ +DEF_PP_ICLASS32(NCJ,01,LDST|CTRLFLOW) /* 2 */ +DEF_PP_ICLASS32(V4LDST,01,LDST) /* 3 */ +DEF_PP_ICLASS32(V2LDST,01,LDST) /* 4 */ +DEF_PP_ICLASS32(J,0123,CTRLFLOW) /* 5 */ +DEF_PP_ICLASS32(CR,3,SUNIT) /* 6 */ +DEF_PP_ICLASS32(ALU32_2op,0123,LDST|SUNIT|MUNIT) /* 7 */ +DEF_PP_ICLASS32(S_2op,23,SUNIT|MUNIT) /* 8 */ +DEF_PP_ICLASS32(LD,01,LDST) /* 9 */ +DEF_PP_ICLASS32(ST,01,LDST) /* 10 */ +DEF_PP_ICLASS32(ALU32_ADDI,0123,LDST|SUNIT|MUNIT) /* 11 */ +DEF_PP_ICLASS32(S_3op,23,SUNIT|MUNIT) /* 12 */ +DEF_PP_ICLASS32(ALU64,23,SUNIT|MUNIT) /* 13 */ +DEF_PP_ICLASS32(M,23,SUNIT|MUNIT) /* 14 */ +DEF_PP_ICLASS32(ALU32_3op,0123,LDST|SUNIT|MUNIT) /* 15 */ + +DEF_EE_ICLASS32(EE0,01,INVALID) /* 0 */ +DEF_EE_ICLASS32(EE1,01,INVALID) /* 1 */ +DEF_EE_ICLASS32(EE2,01,INVALID) /* 2 */ +DEF_EE_ICLASS32(EE3,01,INVALID) /* 3 */ +DEF_EE_ICLASS32(EE4,01,INVALID) /* 4 */ +DEF_EE_ICLASS32(EE5,01,INVALID) /* 5 */ +DEF_EE_ICLASS32(EE6,01,INVALID) /* 6 */ +DEF_EE_ICLASS32(EE7,01,INVALID) /* 7 */ +DEF_EE_ICLASS32(EE8,01,INVALID) /* 8 */ +DEF_EE_ICLASS32(EE9,01,INVALID) /* 9 */ +DEF_EE_ICLASS32(EEA,01,INVALID) /* 10 */ +DEF_EE_ICLASS32(EEB,01,INVALID) /* 11 */ +DEF_EE_ICLASS32(EEC,01,INVALID) /* 12 */ +DEF_EE_ICLASS32(EED,01,INVALID) /* 13 */ +DEF_EE_ICLASS32(EEE,01,INVALID) /* 14 */ +DEF_EE_ICLASS32(EEF,01,INVALID) /* 15 */ From patchwork Wed Feb 17 23:40:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384146 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3225465jao; Wed, 17 Feb 2021 15:57:01 -0800 (PST) X-Google-Smtp-Source: ABdhPJx16d/A1ky4wAxiMVUVOINGi1yi0lGjMn6RowRTTw22lfzFTJSYnkUMZfv9abhpcbtkPT1z X-Received: by 2002:a25:cc4b:: with SMTP id l72mr2707373ybf.455.1613606221073; Wed, 17 Feb 2021 15:57:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606221; cv=none; d=google.com; s=arc-20160816; b=dlOaj6RpkVS1qN0vxQ6fvfxW+L6zWmFDgrJDoq0FJk9ozTtsYd+M5CwdXnQfJV2hyj uAR6tSyt5yOGPzivqLgDzv6g79zFKuBhnUobM1Dj2q0hmWCOdJ8U3jYUNSDE6UfoSO11 6o+uUNGu1FEQzdUp+fHvmux0o8CE0m2aPVhPpa/OsdfDvgIDwySJraHzk4+8aHjcFgm1 V+oWKYY/eprzBajOO/VcaSckpGLSED4y8SJpGtPtlo52CeQvKPAe3ukHe9jwyYJGqgQE 5ZJhrX/AuzjsyVWfnne0twqCVeYxA9MtjYCW4XOsfRD+CXn1whwRPAamFj3JhpYI2RhC 2GHQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=C7OXmlTY2oJFnwsCJ9njAy0mLj9unuWAipSamkyriOo=; b=FqRJYvtZGU7qgyxDYdbeSi2w0sXown4AcZXRZZCTzYoT3+VlXxvVpexSqyxmWEfQn9 XZzNQFgQ1omblGu2S8EOFJGrnASW6Kf2p1fiwFl2+ChfbOmG8uoJUB8vPFlZgcYpgCe5 tv4n0gtIoToqUnbd5d1gwNj71F2EhUVcDNNW2J5IUTG2wKS6UkuXcYy64x4Zw6OO6FXu kirWcfgsyXSAw/4kzxEje/9nFhBBuZrkhnkAGwKKy1VuEv2BLIK/vj61rnf77exMhQkT vJP6eqVVOZxx+PQhmOQG51vnsvIgMJg3cw0P1MPSqF8P1Y88VZ9UnUhTt5F8tUeUi9as zJ3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=pdPVsxzz; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id a11si3578907ybl.52.2021.02.17.15.57.00 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:57:01 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=pdPVsxzz; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52916 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWgm-0002cC-DM for patch@linaro.org; Wed, 17 Feb 2021 18:57:00 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51100) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWS3-0001BC-EE for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:49 -0500 Received: from mail-pf1-x42d.google.com ([2607:f8b0:4864:20::42d]:37196) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRp-0004ps-LU for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:46 -0500 Received: by mail-pf1-x42d.google.com with SMTP id b145so39877pfb.4 for ; Wed, 17 Feb 2021 15:41:31 -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 :mime-version:content-transfer-encoding; bh=C7OXmlTY2oJFnwsCJ9njAy0mLj9unuWAipSamkyriOo=; b=pdPVsxzz3H5WN6S+5QSd58G9+U6JnNa3Vm4Dg7EMXeVfcVxr+AN22sqZMGi68Ox1Pe QkCJA8XE5QSjEyyN/ikIq2kw+r2nUVN3YXbRyFhQ0P4WjOlr2nCbnewtka/05uBGzhTz bWIcGOGCIjs7WjfmlsTiGq9ToZhZVZxr3rAQMo9WolqZU17dSq8+ZX9yeA3tgL+SbiWL YGQBlLQYjP1OtrW5ULSgcuuSewHAc0Ectb8Eibcvf9KOfEmHcJ62DC9tEiwM86CPSgzp 8rwYqxPziM82UHecLBK28Phu7YE3O50YMsfFEP1bvrTavXNwl7rKTsbDWcyQpb3xmlwV zREQ== 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:mime-version:content-transfer-encoding; bh=C7OXmlTY2oJFnwsCJ9njAy0mLj9unuWAipSamkyriOo=; b=CvDKLaRaPnWyGmrvb8rogKusY0WlTyTAL943MuJwl96a9lQqjUWGGMCz6i23ua/10q HaZTYdzfwN9RH6/fe86A/cvdnHem7MFNFI9cvVGtpoR7oq8DxyiHr3uJfsJkwfpld5zK PmJbjzHZvR/jiIQB7+aoKQnYEtefOIcJpFSni7WGRN71rMl3jaBthndXqwDZE1ehWU7E ir1H+ctAu+2b2fUYK6A4oyTPi+1vUL7qbdkW3nEZxhDqiaglsD/Au+B8gt23nX/7921K GZMyDex9sxyH53Z+KwSEOPaYN2Y9oirou4EA+sKNAzcIiLM58YJQ+AMtUwZ7qaSLmHMz c+qQ== X-Gm-Message-State: AOAM5336cFp4lQaDOuv4brrdC8MNtpwT4SkGXUQsLhAD0riuy+v6hX2w Rf5hI6dLctugLmAEflvhyf+G+r4S942sAA== X-Received: by 2002:a63:ed57:: with SMTP id m23mr1638105pgk.28.1613605290276; Wed, 17 Feb 2021 15:41:30 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:29 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 27/35] Hexagon (target/hexagon) TCG generation Date: Wed, 17 Feb 2021 15:40:15 -0800 Message-Id: <20210217234023.1742406-28-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42d; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Include the generated files and set up the data structures Signed-off-by: Taylor Simpson Message-Id: <1612763186-18161-27-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/genptr.h | 25 +++ target/hexagon/genptr.c | 331 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 target/hexagon/genptr.h create mode 100644 target/hexagon/genptr.c -- 2.25.1 diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h new file mode 100644 index 0000000000..c158005d2a --- /dev/null +++ b/target/hexagon/genptr.h @@ -0,0 +1,25 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_GENPTR_H +#define HEXAGON_GENPTR_H + +#include "insn.h" + +extern const SemanticInsn opcode_genptr[]; + +#endif diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c new file mode 100644 index 0000000000..7481f4c1dd --- /dev/null +++ b/target/hexagon/genptr.c @@ -0,0 +1,331 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#define QEMU_GENERATE +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "cpu.h" +#include "internal.h" +#include "tcg/tcg-op.h" +#include "insn.h" +#include "opcodes.h" +#include "translate.h" +#include "macros.h" +#include "gen_tcg.h" + +static inline TCGv gen_read_preg(TCGv pred, uint8_t num) +{ + tcg_gen_mov_tl(pred, hex_pred[num]); + return pred; +} + +static inline void gen_log_predicated_reg_write(int rnum, TCGv val, int slot) +{ + TCGv one = tcg_const_tl(1); + TCGv zero = tcg_const_tl(0); + TCGv slot_mask = tcg_temp_new(); + + tcg_gen_andi_tl(slot_mask, hex_slot_cancelled, 1 << slot); + tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum], slot_mask, zero, + val, hex_new_value[rnum]); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movcond_tl(TCG_COND_EQ, hex_reg_written[rnum], slot_mask, zero, + one, hex_reg_written[rnum]); +#endif + + tcg_temp_free(one); + tcg_temp_free(zero); + tcg_temp_free(slot_mask); +} + +static inline void gen_log_reg_write(int rnum, TCGv val) +{ + tcg_gen_mov_tl(hex_new_value[rnum], val); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movi_tl(hex_reg_written[rnum], 1); +#endif +} + +static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val, int slot) +{ + TCGv val32 = tcg_temp_new(); + TCGv one = tcg_const_tl(1); + TCGv zero = tcg_const_tl(0); + TCGv slot_mask = tcg_temp_new(); + + tcg_gen_andi_tl(slot_mask, hex_slot_cancelled, 1 << slot); + /* Low word */ + tcg_gen_extrl_i64_i32(val32, val); + tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum], slot_mask, zero, + val32, hex_new_value[rnum]); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movcond_tl(TCG_COND_EQ, hex_reg_written[rnum], + slot_mask, zero, + one, hex_reg_written[rnum]); +#endif + + /* High word */ + tcg_gen_extrh_i64_i32(val32, val); + tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum + 1], + slot_mask, zero, + val32, hex_new_value[rnum + 1]); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movcond_tl(TCG_COND_EQ, hex_reg_written[rnum + 1], + slot_mask, zero, + one, hex_reg_written[rnum + 1]); +#endif + + tcg_temp_free(val32); + tcg_temp_free(one); + tcg_temp_free(zero); + tcg_temp_free(slot_mask); +} + +static void gen_log_reg_write_pair(int rnum, TCGv_i64 val) +{ + /* Low word */ + tcg_gen_extrl_i64_i32(hex_new_value[rnum], val); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movi_tl(hex_reg_written[rnum], 1); +#endif + + /* High word */ + tcg_gen_extrh_i64_i32(hex_new_value[rnum + 1], val); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_movi_tl(hex_reg_written[rnum + 1], 1); +#endif +} + +static inline void gen_log_pred_write(int pnum, TCGv val) +{ + TCGv zero = tcg_const_tl(0); + TCGv base_val = tcg_temp_new(); + TCGv and_val = tcg_temp_new(); + TCGv pred_written = tcg_temp_new(); + + /* Multiple writes to the same preg are and'ed together */ + tcg_gen_andi_tl(base_val, val, 0xff); + tcg_gen_and_tl(and_val, base_val, hex_new_pred_value[pnum]); + tcg_gen_andi_tl(pred_written, hex_pred_written, 1 << pnum); + tcg_gen_movcond_tl(TCG_COND_NE, hex_new_pred_value[pnum], + pred_written, zero, + and_val, base_val); + tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << pnum); + + tcg_temp_free(zero); + tcg_temp_free(base_val); + tcg_temp_free(and_val); + tcg_temp_free(pred_written); +} + +static inline void gen_read_p3_0(TCGv control_reg) +{ + tcg_gen_movi_tl(control_reg, 0); + for (int i = 0; i < NUM_PREGS; i++) { + tcg_gen_deposit_tl(control_reg, control_reg, hex_pred[i], i * 8, 8); + } +} + +/* + * Certain control registers require special handling on read + * HEX_REG_P3_0 aliased to the predicate registers + * -> concat the 4 predicate registers together + * HEX_REG_PC actual value stored in DisasContext + * -> assign from ctx->base.pc_next + * HEX_REG_QEMU_*_CNT changes in current TB in DisasContext + * -> add current TB changes to existing reg value + */ +static inline void gen_read_ctrl_reg(DisasContext *ctx, const int reg_num, + TCGv dest) +{ + if (reg_num == HEX_REG_P3_0) { + gen_read_p3_0(dest); + } else if (reg_num == HEX_REG_PC) { + tcg_gen_movi_tl(dest, ctx->base.pc_next); + } else if (reg_num == HEX_REG_QEMU_PKT_CNT) { + tcg_gen_addi_tl(dest, hex_gpr[HEX_REG_QEMU_PKT_CNT], + ctx->num_packets); + } else if (reg_num == HEX_REG_QEMU_INSN_CNT) { + tcg_gen_addi_tl(dest, hex_gpr[HEX_REG_QEMU_INSN_CNT], + ctx->num_insns); + } else { + tcg_gen_mov_tl(dest, hex_gpr[reg_num]); + } +} + +static inline void gen_read_ctrl_reg_pair(DisasContext *ctx, const int reg_num, + TCGv_i64 dest) +{ + if (reg_num == HEX_REG_P3_0) { + TCGv p3_0 = tcg_temp_new(); + gen_read_p3_0(p3_0); + tcg_gen_concat_i32_i64(dest, p3_0, hex_gpr[reg_num + 1]); + tcg_temp_free(p3_0); + } else if (reg_num == HEX_REG_PC - 1) { + TCGv pc = tcg_const_tl(ctx->base.pc_next); + tcg_gen_concat_i32_i64(dest, hex_gpr[reg_num], pc); + tcg_temp_free(pc); + } else if (reg_num == HEX_REG_QEMU_PKT_CNT) { + TCGv pkt_cnt = tcg_temp_new(); + TCGv insn_cnt = tcg_temp_new(); + tcg_gen_addi_tl(pkt_cnt, hex_gpr[HEX_REG_QEMU_PKT_CNT], + ctx->num_packets); + tcg_gen_addi_tl(insn_cnt, hex_gpr[HEX_REG_QEMU_INSN_CNT], + ctx->num_insns); + tcg_gen_concat_i32_i64(dest, pkt_cnt, insn_cnt); + tcg_temp_free(pkt_cnt); + tcg_temp_free(insn_cnt); + } else { + tcg_gen_concat_i32_i64(dest, + hex_gpr[reg_num], + hex_gpr[reg_num + 1]); + } +} + +static inline void gen_write_p3_0(TCGv control_reg) +{ + for (int i = 0; i < NUM_PREGS; i++) { + tcg_gen_extract_tl(hex_pred[i], control_reg, i * 8, 8); + } +} + +/* + * Certain control registers require special handling on write + * HEX_REG_P3_0 aliased to the predicate registers + * -> break the value across 4 predicate registers + * HEX_REG_QEMU_*_CNT changes in current TB in DisasContext + * -> clear the changes + */ +static inline void gen_write_ctrl_reg(DisasContext *ctx, int reg_num, + TCGv val) +{ + if (reg_num == HEX_REG_P3_0) { + gen_write_p3_0(val); + } else { + gen_log_reg_write(reg_num, val); + ctx_log_reg_write(ctx, reg_num); + if (reg_num == HEX_REG_QEMU_PKT_CNT) { + ctx->num_packets = 0; + } + if (reg_num == HEX_REG_QEMU_INSN_CNT) { + ctx->num_insns = 0; + } + } +} + +static inline void gen_write_ctrl_reg_pair(DisasContext *ctx, int reg_num, + TCGv_i64 val) +{ + if (reg_num == HEX_REG_P3_0) { + TCGv val32 = tcg_temp_new(); + tcg_gen_extrl_i64_i32(val32, val); + gen_write_p3_0(val32); + tcg_gen_extrh_i64_i32(val32, val); + gen_log_reg_write(reg_num + 1, val32); + tcg_temp_free(val32); + ctx_log_reg_write(ctx, reg_num + 1); + } else { + gen_log_reg_write_pair(reg_num, val); + ctx_log_reg_write_pair(ctx, reg_num); + if (reg_num == HEX_REG_QEMU_PKT_CNT) { + ctx->num_packets = 0; + ctx->num_insns = 0; + } + } +} + +static inline void gen_load_locked4u(TCGv dest, TCGv vaddr, int mem_index) +{ + tcg_gen_qemu_ld32u(dest, vaddr, mem_index); + tcg_gen_mov_tl(hex_llsc_addr, vaddr); + tcg_gen_mov_tl(hex_llsc_val, dest); +} + +static inline void gen_load_locked8u(TCGv_i64 dest, TCGv vaddr, int mem_index) +{ + tcg_gen_qemu_ld64(dest, vaddr, mem_index); + tcg_gen_mov_tl(hex_llsc_addr, vaddr); + tcg_gen_mov_i64(hex_llsc_val_i64, dest); +} + +static inline void gen_store_conditional4(CPUHexagonState *env, + DisasContext *ctx, int prednum, + TCGv pred, TCGv vaddr, TCGv src) +{ + TCGLabel *fail = gen_new_label(); + TCGLabel *done = gen_new_label(); + TCGv one, zero, tmp; + + tcg_gen_brcond_tl(TCG_COND_NE, vaddr, hex_llsc_addr, fail); + + one = tcg_const_tl(0xff); + zero = tcg_const_tl(0); + tmp = tcg_temp_new(); + tcg_gen_atomic_cmpxchg_tl(tmp, hex_llsc_addr, hex_llsc_val, src, + ctx->mem_idx, MO_32); + tcg_gen_movcond_tl(TCG_COND_EQ, hex_pred[prednum], tmp, hex_llsc_val, + one, zero); + tcg_temp_free(one); + tcg_temp_free(zero); + tcg_temp_free(tmp); + tcg_gen_br(done); + + gen_set_label(fail); + tcg_gen_movi_tl(pred, 0); + + gen_set_label(done); + tcg_gen_movi_tl(hex_llsc_addr, ~0); +} + +static inline void gen_store_conditional8(CPUHexagonState *env, + DisasContext *ctx, int prednum, + TCGv pred, TCGv vaddr, TCGv_i64 src) +{ + TCGLabel *fail = gen_new_label(); + TCGLabel *done = gen_new_label(); + TCGv_i64 one, zero, tmp; + + tcg_gen_brcond_tl(TCG_COND_NE, vaddr, hex_llsc_addr, fail); + + one = tcg_const_i64(0xff); + zero = tcg_const_i64(0); + tmp = tcg_temp_new_i64(); + tcg_gen_atomic_cmpxchg_i64(tmp, hex_llsc_addr, hex_llsc_val_i64, src, + ctx->mem_idx, MO_64); + tcg_gen_movcond_i64(TCG_COND_EQ, tmp, tmp, hex_llsc_val_i64, + one, zero); + tcg_gen_extrl_i64_i32(hex_pred[prednum], tmp); + tcg_temp_free_i64(one); + tcg_temp_free_i64(zero); + tcg_temp_free_i64(tmp); + tcg_gen_br(done); + + gen_set_label(fail); + tcg_gen_movi_tl(pred, 0); + + gen_set_label(done); + tcg_gen_movi_tl(hex_llsc_addr, ~0); +} + +#include "tcg_funcs_generated.c.inc" +#include "tcg_func_table_generated.c.inc" From patchwork Wed Feb 17 23:40:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384182 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3226898jao; Wed, 17 Feb 2021 15:59:44 -0800 (PST) X-Google-Smtp-Source: ABdhPJzkxaME7RCT1LzP/CJ0GLvDeRIEuF8pmD4LPXbJxnYHOLJb5tfNdZERJlbY9FacFHC69GJV X-Received: by 2002:a25:807:: with SMTP id 7mr2667875ybi.503.1613606384904; Wed, 17 Feb 2021 15:59:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606384; cv=none; d=google.com; s=arc-20160816; b=oOmHD7AozcXchGdfBFyTpy9gw7MWA33YPOm7PzLlsBS5FRKgKLFr8uzGvAhwZFNdD5 SotFANytmT9X3J0Qi52wpiS0l/pz/jRHk41Z5wkdxr1ItZorWkCeKRWa5EZwmJqM9HIP mhpCXliWbmZyhBaDlVsIPsRD/1/8D0DKqcg/MvuR0xfe1cDwjp5hjePOlfhEiCEi/Txe yRTHIRKpyywe04ftT8+uWscahI8IPEy8mMzUm1Xw8hv0n3J2HDWnZUIlAKwS3MQ3FEx/ dO25iGibH4k5A65S/e6TyNrI3v9G32RfpuAjshg5PAXHhYhVHWnUt2hfCIsQf1yvN9vm GVCw== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=AQLjsVxe265YNzQ3sjeGms3Bg8DyABIrQ53FVnjy4b0=; b=UwhdQYAEULlBXlaEy8Sg9UCasgXfX9XB6fiXWqYRnJkkVhq1oADg2QyFVwR9tS5V9g J3ehx9SEKGWlyqrQyAdD6ukd7yWxf74bM2poS6RZMPSXaZBLSkX7vOCem0VX75IWKRL8 FA/hvqCZT8I9BUYthe84nxB9EkdaPw8fZ2dQ1RyWQyqVgDZBe+7rDg3QIxtKH+xgaOhg 299V3WX2ZJ92lXstFK1xVSuHZwWEGHvbAp/nSmLg/q+bD5demdfBiYgXrSc8iNEqUjhl K5vNj10zIaTGoAwcAZ1FntTv32q8JfHSFJPdZWhVLhPFMCHZxefJgR0H+xIy44SZLnak 2JBw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=PNuJajGE; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id v10si4180423ybq.162.2021.02.17.15.59.44 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 15:59:44 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=PNuJajGE; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:60132 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWjQ-0005gb-Ab for patch@linaro.org; Wed, 17 Feb 2021 18:59:44 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51086) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWS2-0001B7-EE for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:49 -0500 Received: from mail-pf1-x434.google.com ([2607:f8b0:4864:20::434]:38943) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRp-0004sE-LN for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:45 -0500 Received: by mail-pf1-x434.google.com with SMTP id 189so33304pfy.6 for ; Wed, 17 Feb 2021 15:41:32 -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 :mime-version:content-transfer-encoding; bh=AQLjsVxe265YNzQ3sjeGms3Bg8DyABIrQ53FVnjy4b0=; b=PNuJajGEYiSIcVcvUVbauOdsbUDnrERxnvEQASr0FiYlJoqHmX4fcdhdp+A46AO/ej h/O2aB9ej/UHQY0aU+ryyrBs4WzhvsmWkT3dUoL5B8rjlFrYAShvH25IjRhBbStq2DGX QBKbQpbwTXM1mH3quekhDojFs9Q6zeYyi6dxIuxmt92HU8S2ThLSQknc0gD5W41mPaaa LWr4LifyLrS4LeB9zS9hBYbmcdEPtu/6F6wnSj4rcFQLZpWkbLpwBL/Y59jziEf/DiRu Ecld4Z5+vZJYNDIhrKIe7BvPhKBOQbPo0wFpMgLHJYOsWtHgV7xK7abWpqvM/UpwFlF/ 5D2Q== 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:mime-version:content-transfer-encoding; bh=AQLjsVxe265YNzQ3sjeGms3Bg8DyABIrQ53FVnjy4b0=; b=AhVmjfDTnJ3rTm63bLXvdV9RL4Enks/fnphbGeqIqXEvBW6APg1otDBpsfMVPbOOxi aF0mNXoC46/Zo+dYEIiXxoQ+YEStdBjApa4Tnecx2vi9R4VhIKzkyOYLD01QRLkLjIkl WLp37sUXNGCbgZjzUdsn0JhO78MRLMv5AzGccXZnx7dsJSLcfyqf7jNul5nRMqt72CrF p+g5Yi2/LHbYy9meaE+Mwor+MdmEqmJi5KFHkupnUYmYN4bYHBIu7Wb/Lf9o+Dvbg45K WLdmsUWVN08fMeLdt0mXBYe9erW9ZwA0J0+880kBxysfjHgzle9Oxr2m/I/uGHssR0n0 KcMA== X-Gm-Message-State: AOAM531YyjI0IOGt8zGvZZ2sLYyD0VLRDjWOb8FXdTbWB+8l4xXfLXUe bFLn/IHx4qqPRRfiI0Z3R81pADY0I8oWBA== X-Received: by 2002:a65:404a:: with SMTP id h10mr1493734pgp.367.1613605291592; Wed, 17 Feb 2021 15:41:31 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:31 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 28/35] Hexagon (target/hexagon) TCG for instructions with multiple definitions Date: Wed, 17 Feb 2021 15:40:16 -0800 Message-Id: <20210217234023.1742406-29-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::434; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x434.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Helpers won't work if there are multiple definitions, so we override these instructions using #define fGEN_TCG_. Signed-off-by: Taylor Simpson Message-Id: <1612763186-18161-28-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/gen_tcg.h | 198 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 target/hexagon/gen_tcg.h -- 2.25.1 diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h new file mode 100644 index 0000000000..a8d9321b42 --- /dev/null +++ b/target/hexagon/gen_tcg.h @@ -0,0 +1,198 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_GEN_TCG_H +#define HEXAGON_GEN_TCG_H + +/* + * Here is a primer to understand the tag names for load/store instructions + * + * Data types + * b signed byte r0 = memb(r2+#0) + * ub unsigned byte r0 = memub(r2+#0) + * h signed half word (16 bits) r0 = memh(r2+#0) + * uh unsigned half word r0 = memuh(r2+#0) + * i integer (32 bits) r0 = memw(r2+#0) + * d double word (64 bits) r1:0 = memd(r2+#0) + * + * Addressing modes + * _io indirect with offset r0 = memw(r1+#4) + * _ur absolute with register offset r0 = memw(r1<<#4+##variable) + * _rr indirect with register offset r0 = memw(r1+r4<<#2) + * gp global pointer relative r0 = memw(gp+#200) + * _sp stack pointer relative r0 = memw(r29+#12) + * _ap absolute set r0 = memw(r1=##variable) + * _pr post increment register r0 = memw(r1++m1) + * _pi post increment immediate r0 = memb(r1++#1) + */ + +/* Macros for complex addressing modes */ +#define GET_EA_ap \ + do { \ + fEA_IMM(UiV); \ + tcg_gen_movi_tl(ReV, UiV); \ + } while (0) +#define GET_EA_pr \ + do { \ + fEA_REG(RxV); \ + fPM_M(RxV, MuV); \ + } while (0) +#define GET_EA_pi \ + do { \ + fEA_REG(RxV); \ + fPM_I(RxV, siV); \ + } while (0) + + +/* Instructions with multiple definitions */ +#define fGEN_TCG_LOAD_AP(RES, SIZE, SIGN) \ + do { \ + fMUST_IMMEXT(UiV); \ + fEA_IMM(UiV); \ + fLOAD(1, SIZE, SIGN, EA, RES); \ + tcg_gen_movi_tl(ReV, UiV); \ + } while (0) + +#define fGEN_TCG_L4_loadrub_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RdV, 1, u) +#define fGEN_TCG_L4_loadrb_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RdV, 1, s) +#define fGEN_TCG_L4_loadruh_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RdV, 2, u) +#define fGEN_TCG_L4_loadrh_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RdV, 2, s) +#define fGEN_TCG_L4_loadri_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RdV, 4, u) +#define fGEN_TCG_L4_loadrd_ap(SHORTCODE) \ + fGEN_TCG_LOAD_AP(RddV, 8, u) + +#define fGEN_TCG_L2_loadrub_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrub_pi(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrb_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrb_pi(SHORTCODE) SHORTCODE; +#define fGEN_TCG_L2_loadruh_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadruh_pi(SHORTCODE) SHORTCODE; +#define fGEN_TCG_L2_loadrh_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrh_pi(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadri_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadri_pi(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrd_pr(SHORTCODE) SHORTCODE +#define fGEN_TCG_L2_loadrd_pi(SHORTCODE) SHORTCODE + +/* + * Predicated loads + * Here is a primer to understand the tag names + * + * Predicate used + * t true "old" value if (p0) r0 = memb(r2+#0) + * f false "old" value if (!p0) r0 = memb(r2+#0) + * tnew true "new" value if (p0.new) r0 = memb(r2+#0) + * fnew false "new" value if (!p0.new) r0 = memb(r2+#0) + */ +#define fGEN_TCG_PRED_LOAD(GET_EA, PRED, SIZE, SIGN) \ + do { \ + TCGv LSB = tcg_temp_local_new(); \ + TCGLabel *label = gen_new_label(); \ + GET_EA; \ + PRED; \ + PRED_LOAD_CANCEL(LSB, EA); \ + tcg_gen_movi_tl(RdV, 0); \ + tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, label); \ + fLOAD(1, SIZE, SIGN, EA, RdV); \ + gen_set_label(label); \ + tcg_temp_free(LSB); \ + } while (0) + +#define fGEN_TCG_L2_ploadrubt_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 1, u) +#define fGEN_TCG_L2_ploadrubf_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 1, u) +#define fGEN_TCG_L2_ploadrubtnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 1, u) +#define fGEN_TCG_L2_ploadrubfnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 1, u) +#define fGEN_TCG_L2_ploadrbt_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 1, s) +#define fGEN_TCG_L2_ploadrbf_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 1, s) +#define fGEN_TCG_L2_ploadrbtnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 1, s) +#define fGEN_TCG_L2_ploadrbfnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD({ fEA_REG(RxV); fPM_I(RxV, siV); }, \ + fLSBNEWNOT(PtN), 1, s) + +#define fGEN_TCG_L2_ploadruht_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 2, u) +#define fGEN_TCG_L2_ploadruhf_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 2, u) +#define fGEN_TCG_L2_ploadruhtnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 2, u) +#define fGEN_TCG_L2_ploadruhfnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 2, u) +#define fGEN_TCG_L2_ploadrht_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 2, s) +#define fGEN_TCG_L2_ploadrhf_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 2, s) +#define fGEN_TCG_L2_ploadrhtnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 2, s) +#define fGEN_TCG_L2_ploadrhfnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 2, s) + +#define fGEN_TCG_L2_ploadrit_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 4, u) +#define fGEN_TCG_L2_ploadrif_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 4, u) +#define fGEN_TCG_L2_ploadritnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 4, u) +#define fGEN_TCG_L2_ploadrifnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 4, u) + +/* Predicated loads into a register pair */ +#define fGEN_TCG_PRED_LOAD_PAIR(GET_EA, PRED) \ + do { \ + TCGv LSB = tcg_temp_local_new(); \ + TCGLabel *label = gen_new_label(); \ + GET_EA; \ + PRED; \ + PRED_LOAD_CANCEL(LSB, EA); \ + tcg_gen_movi_i64(RddV, 0); \ + tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, label); \ + fLOAD(1, 8, u, EA, RddV); \ + gen_set_label(label); \ + tcg_temp_free(LSB); \ + } while (0) + +#define fGEN_TCG_L2_ploadrdt_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBOLD(PtV)) +#define fGEN_TCG_L2_ploadrdf_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBOLDNOT(PtV)) +#define fGEN_TCG_L2_ploadrdtnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBNEW(PtN)) +#define fGEN_TCG_L2_ploadrdfnew_pi(SHORTCODE) \ + fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBNEWNOT(PtN)) + +/* load-locked and store-locked */ +#define fGEN_TCG_L2_loadw_locked(SHORTCODE) \ + SHORTCODE +#define fGEN_TCG_L4_loadd_locked(SHORTCODE) \ + SHORTCODE +#define fGEN_TCG_S2_storew_locked(SHORTCODE) \ + do { SHORTCODE; READ_PREG(PdV, PdN); } while (0) +#define fGEN_TCG_S4_stored_locked(SHORTCODE) \ + do { SHORTCODE; READ_PREG(PdV, PdN); } while (0) + +#endif From patchwork Wed Feb 17 23:40:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384187 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3229204jao; Wed, 17 Feb 2021 16:03:15 -0800 (PST) X-Google-Smtp-Source: ABdhPJyMiGrr5xOr/9l9qfXkPzMOkgDmFyGOem70kSkJcJZ/2E9z7FSF5TFGW0M561Htl89Ra4W0 X-Received: by 2002:a25:e047:: with SMTP id x68mr2723043ybg.19.1613606595395; Wed, 17 Feb 2021 16:03:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606595; cv=none; d=google.com; s=arc-20160816; b=paEEBbu1XFks8Da+S5Sz23TArqXjJ5VzdeDZkZto4nvkpAzHqh+nld1O1RubbYgHe4 OTH1MFKiw3imbRtWwX+Vegnc88j1ojRqROTS3EWARXD7bvkNuVbYypuSug6RNQ0SCSjo WcSesQy6vvF55sGZjetWaXdYCbuUI4zZN3ylPFRSha8u9E3fpXY1qvCCktycW42xVcIx BM6kB6J9jOXHBN0BwZG8dVckKRWxa7Q6sdMAmyw9dICK1pNIwi8/lTOfD/PC0e2dZY23 F+qfN7XV1/Ev5LhkKc1j73u8i4irhzyFus4xQHph2u9wJ7qYVEB8qn+WQEPYgwh4R+0+ GQWQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=GBwUcmkwQvfre4JuFgSFF6OMjobUWB5hLAO/aWmrkOE=; b=KmtRBjyZOU5W3DpVZEykQsqXhuDRUdaZXMzfRhxffyt7j3UcInVtzfSH3OsWDGQoMn AwSrLqAhlfLX59bLoG/86+6qla6ZhmPBJY4GHOvPEEHJANAJnYG6tjsiCq63CGSME+Vy HqL4n2z/ftloa+ZnQgSvE77fbymhqLnkAZuW1hfq5U/5RNP8aw7xDDLBr+UNRx5tSj/8 DgACMnVSTCDvaFGfML+WyjTZVnyE4Gye6x9S8hAUTvd06seIElNPPs80Tkd1thuywgoS bk44v+zhIwOEkN2Gw1tMaIj8/cO9d0kf8qaJQXtpFrAyXhAV7xFUloXCKX/8tob4Fd7H 8nLA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jruEYfhC; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id c62si4006629yba.181.2021.02.17.16.03.15 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 16:03:15 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jruEYfhC; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:40526 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWmo-00011M-Q0 for patch@linaro.org; Wed, 17 Feb 2021 19:03:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51106) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWS3-0001BE-JA for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:50 -0500 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]:35937) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRu-0004tP-Rt for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:47 -0500 Received: by mail-pl1-x62a.google.com with SMTP id e9so213460plh.3 for ; Wed, 17 Feb 2021 15:41: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 :mime-version:content-transfer-encoding; bh=GBwUcmkwQvfre4JuFgSFF6OMjobUWB5hLAO/aWmrkOE=; b=jruEYfhCBbeooGWlbHuP/OBob2Utdsrxijbulg2ZU/SlQHTLdTzrK754SFv52pNnbO evn7AlwPybLcRfOQXlwCiiRVRFWBJ56+BaRTVA3QPBRAkwIrswlSEkyYY1D75aquBykP mdVw2AwLtFly+D3Jx9Z4wN+5PL3qyrdHQPW7kvSIn9la8hD58HfOnObysRZHgk9fwjkO 9JwpfenxPky7VHW/qx/AXPpxVGAgOID9vASW+5xWC2zR3EEF6Bq9azVq3rzrJp8hsnvo NWWZe+OCmfshRaaSysZhcBouNsx8inVmCi4Fr6G+U5w/st+F9xpld1WWBP+ZKKytvmTC FKRw== 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:mime-version:content-transfer-encoding; bh=GBwUcmkwQvfre4JuFgSFF6OMjobUWB5hLAO/aWmrkOE=; b=CNKgU5joi+eNstEffRgkIndSUWzr1xxFpThVoABgMtXDi3hEFfN6XR/X41t8+w4qAP kh7/ZOo3z58ny/y3QiEN5zPDBIlmxR9DuctmycnT4zgN8n6FtdMpS5d7UB/cSJVgKS1L ccM86J9lcaFB/4vmpNqus7/Sb+8g0RaIZphrWbkBBCyEpKRtmTpVbTNrvJ1/sUU0Sc/b gc/aSbB/eRBlqcSP6Pk5L6ELrz4hX5EPeni/mWlIZI4YqM9d3EKhLbD6mHZ6JW4zTrN/ s2DKUfrcJNPcw5xd5tMBzRwzyE7AUU6O0khNw4KEBVAxVUOXm5VlL2Jh81BJ9YaK8IVH Rp+w== X-Gm-Message-State: AOAM531KgQqeYUJH1exBHKMyz1j0+3iWVZaXoffCkRqEMpyOcBitnLFu l35nmspcbgw/dhnuxKmRGyJSNfHeXke2Aw== X-Received: by 2002:a17:90b:4d07:: with SMTP id mw7mr1204212pjb.172.1613605293070; Wed, 17 Feb 2021 15:41:33 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:32 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 29/35] Hexagon (target/hexagon) TCG for floating point instructions Date: Wed, 17 Feb 2021 15:40:17 -0800 Message-Id: <20210217234023.1742406-30-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson The imported code uses host floating point. We override them to use qemu softfloat Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-29-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/gen_tcg.h | 121 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) -- 2.25.1 diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h index a8d9321b42..e044deaff2 100644 --- a/target/hexagon/gen_tcg.h +++ b/target/hexagon/gen_tcg.h @@ -195,4 +195,125 @@ #define fGEN_TCG_S4_stored_locked(SHORTCODE) \ do { SHORTCODE; READ_PREG(PdV, PdN); } while (0) +/* Floating point */ +#define fGEN_TCG_F2_conv_sf2df(SHORTCODE) \ + gen_helper_conv_sf2df(RddV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_df2sf(SHORTCODE) \ + gen_helper_conv_df2sf(RdV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_uw2sf(SHORTCODE) \ + gen_helper_conv_uw2sf(RdV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_uw2df(SHORTCODE) \ + gen_helper_conv_uw2df(RddV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_w2sf(SHORTCODE) \ + gen_helper_conv_w2sf(RdV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_w2df(SHORTCODE) \ + gen_helper_conv_w2df(RddV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_ud2sf(SHORTCODE) \ + gen_helper_conv_ud2sf(RdV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_ud2df(SHORTCODE) \ + gen_helper_conv_ud2df(RddV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_d2sf(SHORTCODE) \ + gen_helper_conv_d2sf(RdV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_d2df(SHORTCODE) \ + gen_helper_conv_d2df(RddV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_sf2uw(SHORTCODE) \ + gen_helper_conv_sf2uw(RdV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_sf2w(SHORTCODE) \ + gen_helper_conv_sf2w(RdV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_sf2ud(SHORTCODE) \ + gen_helper_conv_sf2ud(RddV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_sf2d(SHORTCODE) \ + gen_helper_conv_sf2d(RddV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_df2uw(SHORTCODE) \ + gen_helper_conv_df2uw(RdV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_df2w(SHORTCODE) \ + gen_helper_conv_df2w(RdV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_df2ud(SHORTCODE) \ + gen_helper_conv_df2ud(RddV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_df2d(SHORTCODE) \ + gen_helper_conv_df2d(RddV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_sf2uw_chop(SHORTCODE) \ + gen_helper_conv_sf2uw_chop(RdV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_sf2w_chop(SHORTCODE) \ + gen_helper_conv_sf2w_chop(RdV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_sf2ud_chop(SHORTCODE) \ + gen_helper_conv_sf2ud_chop(RddV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_sf2d_chop(SHORTCODE) \ + gen_helper_conv_sf2d_chop(RddV, cpu_env, RsV) +#define fGEN_TCG_F2_conv_df2uw_chop(SHORTCODE) \ + gen_helper_conv_df2uw_chop(RdV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_df2w_chop(SHORTCODE) \ + gen_helper_conv_df2w_chop(RdV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_df2ud_chop(SHORTCODE) \ + gen_helper_conv_df2ud_chop(RddV, cpu_env, RssV) +#define fGEN_TCG_F2_conv_df2d_chop(SHORTCODE) \ + gen_helper_conv_df2d_chop(RddV, cpu_env, RssV) +#define fGEN_TCG_F2_sfadd(SHORTCODE) \ + gen_helper_sfadd(RdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sfsub(SHORTCODE) \ + gen_helper_sfsub(RdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sfcmpeq(SHORTCODE) \ + gen_helper_sfcmpeq(PdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sfcmpgt(SHORTCODE) \ + gen_helper_sfcmpgt(PdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sfcmpge(SHORTCODE) \ + gen_helper_sfcmpge(PdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sfcmpuo(SHORTCODE) \ + gen_helper_sfcmpuo(PdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sfmax(SHORTCODE) \ + gen_helper_sfmax(RdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sfmin(SHORTCODE) \ + gen_helper_sfmin(RdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sfclass(SHORTCODE) \ + do { \ + TCGv imm = tcg_const_tl(uiV); \ + gen_helper_sfclass(PdV, cpu_env, RsV, imm); \ + tcg_temp_free(imm); \ + } while (0) +#define fGEN_TCG_F2_sffixupn(SHORTCODE) \ + gen_helper_sffixupn(RdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sffixupd(SHORTCODE) \ + gen_helper_sffixupd(RdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sffixupr(SHORTCODE) \ + gen_helper_sffixupr(RdV, cpu_env, RsV) +#define fGEN_TCG_F2_dfadd(SHORTCODE) \ + gen_helper_dfadd(RddV, cpu_env, RssV, RttV) +#define fGEN_TCG_F2_dfsub(SHORTCODE) \ + gen_helper_dfsub(RddV, cpu_env, RssV, RttV) +#define fGEN_TCG_F2_dfmax(SHORTCODE) \ + gen_helper_dfmax(RddV, cpu_env, RssV, RttV) +#define fGEN_TCG_F2_dfmin(SHORTCODE) \ + gen_helper_dfmin(RddV, cpu_env, RssV, RttV) +#define fGEN_TCG_F2_dfcmpeq(SHORTCODE) \ + gen_helper_dfcmpeq(PdV, cpu_env, RssV, RttV) +#define fGEN_TCG_F2_dfcmpgt(SHORTCODE) \ + gen_helper_dfcmpgt(PdV, cpu_env, RssV, RttV) +#define fGEN_TCG_F2_dfcmpge(SHORTCODE) \ + gen_helper_dfcmpge(PdV, cpu_env, RssV, RttV) +#define fGEN_TCG_F2_dfcmpuo(SHORTCODE) \ + gen_helper_dfcmpuo(PdV, cpu_env, RssV, RttV) +#define fGEN_TCG_F2_dfclass(SHORTCODE) \ + do { \ + TCGv imm = tcg_const_tl(uiV); \ + gen_helper_dfclass(PdV, cpu_env, RssV, imm); \ + tcg_temp_free(imm); \ + } while (0) +#define fGEN_TCG_F2_sfmpy(SHORTCODE) \ + gen_helper_sfmpy(RdV, cpu_env, RsV, RtV) +#define fGEN_TCG_F2_sffma(SHORTCODE) \ + gen_helper_sffma(RxV, cpu_env, RxV, RsV, RtV) +#define fGEN_TCG_F2_sffma_sc(SHORTCODE) \ + gen_helper_sffma_sc(RxV, cpu_env, RxV, RsV, RtV, PuV) +#define fGEN_TCG_F2_sffms(SHORTCODE) \ + gen_helper_sffms(RxV, cpu_env, RxV, RsV, RtV) +#define fGEN_TCG_F2_sffma_lib(SHORTCODE) \ + gen_helper_sffma_lib(RxV, cpu_env, RxV, RsV, RtV) +#define fGEN_TCG_F2_sffms_lib(SHORTCODE) \ + gen_helper_sffms_lib(RxV, cpu_env, RxV, RsV, RtV) + +#define fGEN_TCG_F2_dfmpyfix(SHORTCODE) \ + gen_helper_dfmpyfix(RddV, cpu_env, RssV, RttV) +#define fGEN_TCG_F2_dfmpyhh(SHORTCODE) \ + gen_helper_dfmpyhh(RxxV, cpu_env, RxxV, RssV, RttV) + #endif From patchwork Wed Feb 17 23:40:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384190 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3231342jao; Wed, 17 Feb 2021 16:06:52 -0800 (PST) X-Google-Smtp-Source: ABdhPJxmpY+2VsDl9SrexoclHySOFWuotp/Xy8aK+AG8eE9ImgRPvP0I9J+EuaGJ7qKVhiQgadJ1 X-Received: by 2002:a25:2186:: with SMTP id h128mr2654082ybh.369.1613606812740; Wed, 17 Feb 2021 16:06:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606812; cv=none; d=google.com; s=arc-20160816; b=IyRO64Hqrd57u4GERsZKd45xNaYR6+Eom3oFBOQ4NkcYD6ov/FKNgA6bVIlwouB44V VIKnHAapGPIU1V4SuEyFIRSWuiP7o0YJAntIBxMPdG0CeRAqfA0nNGPWZZ43se23aSoJ Wz77cbtGEr/gkHhhi3a30k36FxOVd9kZvUBdGMzOZOPaReOeUMsVEONFdPNBDDzuAdld OoisAPAOkpCJOQlF13JLuXqde5NPpntX8WmKO08C8GBq8p88YEcpQdU6vQpXg5lrEnXe BmMpflCWqe6kBvhJaWDhZRYtU7YihEO6X47AQEnVK/TNpYnpqZl87EMK7KZMYttPi6Y8 1FLw== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=oJ9LzM24hLl++wL7kv83KW5bFTZqSpuQemA3fET9se8=; b=G72sAtiz9p4ZdHyj9O3/8Gx9M761kfryVEEJWXLOmUAEwoOSXkEhQEBS/4kdygunzN TKGkMinHZD8o6MWGaWQEontJXDOm1X8LMcufwn2H7H3osVSe7SPQl0D0vGtzQWdnCrZc GeowRUTmtbvc5et3k+h4w1SdYw8OoPSTFvxrh8XqFKyIjPJWPur3StmJrAV38A5e4Zbb iEc24NnRFhq3hItcSbgFWzoeX9sBs+3qDtJMc393Z1ibu4jZpkGB3o30yOtVEE05hWas qNomg338fihqXZc/88eNUrsBnb+/AQY3g0NL7bYdiimQKNypRJOWNRHVu58jaNx64xNH F/yQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DXblEJVz; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id d2si4033126ybs.153.2021.02.17.16.06.52 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 16:06:52 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DXblEJVz; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52652 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWqK-0006Hk-5Y for patch@linaro.org; Wed, 17 Feb 2021 19:06:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51180) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWS9-0001C9-Qh for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:56 -0500 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]:42150) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWS2-0004uS-BB for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:53 -0500 Received: by mail-pf1-x435.google.com with SMTP id w18so24602pfu.9 for ; Wed, 17 Feb 2021 15:41:36 -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 :mime-version:content-transfer-encoding; bh=oJ9LzM24hLl++wL7kv83KW5bFTZqSpuQemA3fET9se8=; b=DXblEJVzSH8OXe2oRPAVMP4dXdLpfZg3EZIya8PEzaAbO97V2QN4bJVeYpUJOswlHu mkP63V+Ux4BLb5rN3s0gDnz2eiymRPSAW3QSgVfKw/Pc8SDxGhEcF8WPausmf4UTxM6j Cm4ecuVUUWSVK+PKYjmbzCILLaQ0BGCa5SL19jZNYCQYPkz5S5tIMNyXH7XwrkF3QB/G iTFe+ihpnK+pArnzzfP61T3si7PsiGwS8wSaeT5gNOshHdNqgjLw3n3zi7YX4Mw0b2Rr 4gj0dz70c2aLv7eeHwbCphq6jt8MvI8HEhnifktP5YitToocvITG772JL9CrTqw1Q7FD v85Q== 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:mime-version:content-transfer-encoding; bh=oJ9LzM24hLl++wL7kv83KW5bFTZqSpuQemA3fET9se8=; b=NGQ03be+vbkLaXe4SuwEwdcZSzr7NESIZSNrsrqFS6GW2Aij+rJyZKU8b87QmeHu1C 5n+ZaLsrjm2nxmISoiR0U7NOblojtTNCDOZ4zJPCZdMR9cxx/EegNbhbZPowO07fAPfn fsF7g2EodjBMTFZSKkGISYQo/H5sWTvxnKtt2nn5f9eLlRtpA4Eir3ItoNY0dpn43wJE NO/oizli3Dp6AgRS5oVxS0kNCjhlf0+9toY0sJ+5UBcwmhg1Omw+SAjQYcsQoJhAfgM/ 4JMWIivZcOTHs4Ap878MsEtEzVTpsFAs8y1B0Z4DZRjHvH3xsvla9KJXeg3VleGPWHfg Ufpw== X-Gm-Message-State: AOAM532ETom29EvSz3QjiOjp05IattR2wEqrZiuuheJHIXIGNUZhsgrB V01vU0+ueUJs/DRgSugebdZsBkvgBitQHg== X-Received: by 2002:a62:5b44:0:b029:1ec:da08:ca54 with SMTP id p65-20020a625b440000b02901ecda08ca54mr1577720pfb.47.1613605295090; Wed, 17 Feb 2021 15:41:35 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:34 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 30/35] Hexagon (target/hexagon) translation Date: Wed, 17 Feb 2021 15:40:18 -0800 Message-Id: <20210217234023.1742406-31-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::435; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x435.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Read the instruction memory Create a packet data structure Generate TCG code for the start of the packet Invoke the generate function for each instruction Generate TCG code for the end of the packet Signed-off-by: Taylor Simpson Message-Id: <1612763186-18161-30-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- target/hexagon/translate.h | 93 +++++ target/hexagon/translate.c | 748 +++++++++++++++++++++++++++++++++++++ 2 files changed, 841 insertions(+) create mode 100644 target/hexagon/translate.h create mode 100644 target/hexagon/translate.c -- 2.25.1 diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h new file mode 100644 index 0000000000..938f7fbb9f --- /dev/null +++ b/target/hexagon/translate.h @@ -0,0 +1,93 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_TRANSLATE_H +#define HEXAGON_TRANSLATE_H + +#include "qemu/bitmap.h" +#include "cpu.h" +#include "exec/translator.h" +#include "tcg/tcg-op.h" +#include "internal.h" + +typedef struct DisasContext { + DisasContextBase base; + uint32_t mem_idx; + uint32_t num_packets; + uint32_t num_insns; + int reg_log[REG_WRITES_MAX]; + int reg_log_idx; + DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS); + int preg_log[PRED_WRITES_MAX]; + int preg_log_idx; + uint8_t store_width[STORES_MAX]; + uint8_t s1_store_processed; +} DisasContext; + +static inline void ctx_log_reg_write(DisasContext *ctx, int rnum) +{ +#if HEX_DEBUG + if (test_bit(rnum, ctx->regs_written)) { + HEX_DEBUG_LOG("WARNING: Multiple writes to r%d\n", rnum); + } +#endif + ctx->reg_log[ctx->reg_log_idx] = rnum; + ctx->reg_log_idx++; + set_bit(rnum, ctx->regs_written); +} + +static inline void ctx_log_reg_write_pair(DisasContext *ctx, int rnum) +{ + ctx_log_reg_write(ctx, rnum); + ctx_log_reg_write(ctx, rnum + 1); +} + +static inline void ctx_log_pred_write(DisasContext *ctx, int pnum) +{ + ctx->preg_log[ctx->preg_log_idx] = pnum; + ctx->preg_log_idx++; +} + +static inline bool is_preloaded(DisasContext *ctx, int num) +{ + return test_bit(num, ctx->regs_written); +} + +extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS]; +extern TCGv hex_pred[NUM_PREGS]; +extern TCGv hex_next_PC; +extern TCGv hex_this_PC; +extern TCGv hex_slot_cancelled; +extern TCGv hex_branch_taken; +extern TCGv hex_new_value[TOTAL_PER_THREAD_REGS]; +extern TCGv hex_reg_written[TOTAL_PER_THREAD_REGS]; +extern TCGv hex_new_pred_value[NUM_PREGS]; +extern TCGv hex_pred_written; +extern TCGv hex_store_addr[STORES_MAX]; +extern TCGv hex_store_width[STORES_MAX]; +extern TCGv hex_store_val32[STORES_MAX]; +extern TCGv_i64 hex_store_val64[STORES_MAX]; +extern TCGv hex_dczero_addr; +extern TCGv hex_llsc_addr; +extern TCGv hex_llsc_val; +extern TCGv_i64 hex_llsc_val_i64; + +void gen_exception(int excp); +void gen_exception_debug(void); + +void process_store(DisasContext *ctx, Packet *pkt, int slot_num); +#endif diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c new file mode 100644 index 0000000000..eeaad5f8ba --- /dev/null +++ b/target/hexagon/translate.c @@ -0,0 +1,748 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#define QEMU_GENERATE +#include "qemu/osdep.h" +#include "cpu.h" +#include "tcg/tcg-op.h" +#include "exec/cpu_ldst.h" +#include "exec/log.h" +#include "internal.h" +#include "attribs.h" +#include "insn.h" +#include "decode.h" +#include "translate.h" +#include "printinsn.h" + +TCGv hex_gpr[TOTAL_PER_THREAD_REGS]; +TCGv hex_pred[NUM_PREGS]; +TCGv hex_next_PC; +TCGv hex_this_PC; +TCGv hex_slot_cancelled; +TCGv hex_branch_taken; +TCGv hex_new_value[TOTAL_PER_THREAD_REGS]; +#if HEX_DEBUG +TCGv hex_reg_written[TOTAL_PER_THREAD_REGS]; +#endif +TCGv hex_new_pred_value[NUM_PREGS]; +TCGv hex_pred_written; +TCGv hex_store_addr[STORES_MAX]; +TCGv hex_store_width[STORES_MAX]; +TCGv hex_store_val32[STORES_MAX]; +TCGv_i64 hex_store_val64[STORES_MAX]; +TCGv hex_pkt_has_store_s1; +TCGv hex_dczero_addr; +TCGv hex_llsc_addr; +TCGv hex_llsc_val; +TCGv_i64 hex_llsc_val_i64; + +static const char * const hexagon_prednames[] = { + "p0", "p1", "p2", "p3" +}; + +void gen_exception(int excp) +{ + TCGv_i32 helper_tmp = tcg_const_i32(excp); + gen_helper_raise_exception(cpu_env, helper_tmp); + tcg_temp_free_i32(helper_tmp); +} + +void gen_exception_debug(void) +{ + gen_exception(EXCP_DEBUG); +} + +#if HEX_DEBUG +#define PACKET_BUFFER_LEN 1028 +static void print_pkt(Packet *pkt) +{ + GString *buf = g_string_sized_new(PACKET_BUFFER_LEN); + snprint_a_pkt_debug(buf, pkt); + HEX_DEBUG_LOG("%s", buf->str); + g_string_free(buf, true); +} +#define HEX_DEBUG_PRINT_PKT(pkt) print_pkt(pkt) +#else +#define HEX_DEBUG_PRINT_PKT(pkt) /* nothing */ +#endif + +static int read_packet_words(CPUHexagonState *env, DisasContext *ctx, + uint32_t words[]) +{ + bool found_end = false; + int nwords, max_words; + + memset(words, 0, PACKET_WORDS_MAX * sizeof(uint32_t)); + for (nwords = 0; !found_end && nwords < PACKET_WORDS_MAX; nwords++) { + words[nwords] = cpu_ldl_code(env, + ctx->base.pc_next + nwords * sizeof(uint32_t)); + found_end = is_packet_end(words[nwords]); + } + if (!found_end) { + /* Read too many words without finding the end */ + return 0; + } + + /* Check for page boundary crossing */ + max_words = -(ctx->base.pc_next | TARGET_PAGE_MASK) / sizeof(uint32_t); + if (nwords > max_words) { + /* We can only cross a page boundary at the beginning of a TB */ + g_assert(ctx->base.num_insns == 1); + } + + HEX_DEBUG_LOG("decode_packet: pc = 0x%x\n", ctx->base.pc_next); + HEX_DEBUG_LOG(" words = { "); + for (int i = 0; i < nwords; i++) { + HEX_DEBUG_LOG("0x%x, ", words[i]); + } + HEX_DEBUG_LOG("}\n"); + + return nwords; +} + +static bool check_for_attrib(Packet *pkt, int attrib) +{ + for (int i = 0; i < pkt->num_insns; i++) { + if (GET_ATTRIB(pkt->insn[i].opcode, attrib)) { + return true; + } + } + return false; +} + +static bool need_pc(Packet *pkt) +{ + return check_for_attrib(pkt, A_IMPLICIT_READS_PC); +} + +static bool need_slot_cancelled(Packet *pkt) +{ + return check_for_attrib(pkt, A_CONDEXEC); +} + +static bool need_pred_written(Packet *pkt) +{ + return check_for_attrib(pkt, A_WRITES_PRED_REG); +} + +static void gen_start_packet(DisasContext *ctx, Packet *pkt) +{ + target_ulong next_PC = ctx->base.pc_next + pkt->encod_pkt_size_in_bytes; + int i; + + /* Clear out the disassembly context */ + ctx->reg_log_idx = 0; + bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS); + ctx->preg_log_idx = 0; + for (i = 0; i < STORES_MAX; i++) { + ctx->store_width[i] = 0; + } + tcg_gen_movi_tl(hex_pkt_has_store_s1, pkt->pkt_has_store_s1); + ctx->s1_store_processed = 0; + +#if HEX_DEBUG + /* Handy place to set a breakpoint before the packet executes */ + gen_helper_debug_start_packet(cpu_env); + tcg_gen_movi_tl(hex_this_PC, ctx->base.pc_next); +#endif + + /* Initialize the runtime state for packet semantics */ + if (need_pc(pkt)) { + tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->base.pc_next); + } + if (need_slot_cancelled(pkt)) { + tcg_gen_movi_tl(hex_slot_cancelled, 0); + } + if (pkt->pkt_has_cof) { + tcg_gen_movi_tl(hex_branch_taken, 0); + tcg_gen_movi_tl(hex_next_PC, next_PC); + } + if (need_pred_written(pkt)) { + tcg_gen_movi_tl(hex_pred_written, 0); + } +} + +/* + * The LOG_*_WRITE macros mark most of the writes in a packet + * However, there are some implicit writes marked as attributes + * of the applicable instructions. + */ +static void mark_implicit_reg_write(DisasContext *ctx, Insn *insn, + int attrib, int rnum) +{ + if (GET_ATTRIB(insn->opcode, attrib)) { + int is_predicated = GET_ATTRIB(insn->opcode, A_CONDEXEC); + if (is_predicated && !is_preloaded(ctx, rnum)) { + tcg_gen_mov_tl(hex_new_value[rnum], hex_gpr[rnum]); + } + + ctx_log_reg_write(ctx, rnum); + } +} + +static void mark_implicit_pred_write(DisasContext *ctx, Insn *insn, + int attrib, int pnum) +{ + if (GET_ATTRIB(insn->opcode, attrib)) { + ctx_log_pred_write(ctx, pnum); + } +} + +static void mark_implicit_writes(DisasContext *ctx, Insn *insn) +{ + mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_FP, HEX_REG_FP); + mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SP, HEX_REG_SP); + mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_LR, HEX_REG_LR); + mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_LC0, HEX_REG_LC0); + mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SA0, HEX_REG_SA0); + mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_LC1, HEX_REG_LC1); + mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SA1, HEX_REG_SA1); + + mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P0, 0); + mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P1, 1); + mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P2, 2); + mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P3, 3); +} + +static void gen_insn(CPUHexagonState *env, DisasContext *ctx, + Insn *insn, Packet *pkt) +{ + if (insn->generate) { + mark_implicit_writes(ctx, insn); + insn->generate(env, ctx, insn, pkt); + } else { + gen_exception(HEX_EXCP_INVALID_OPCODE); + ctx->base.is_jmp = DISAS_NORETURN; + } +} + +/* + * Helpers for generating the packet commit + */ +static void gen_reg_writes(DisasContext *ctx) +{ + int i; + + for (i = 0; i < ctx->reg_log_idx; i++) { + int reg_num = ctx->reg_log[i]; + + tcg_gen_mov_tl(hex_gpr[reg_num], hex_new_value[reg_num]); + } +} + +static void gen_pred_writes(DisasContext *ctx, Packet *pkt) +{ + TCGv zero, control_reg, pval; + int i; + + /* Early exit if the log is empty */ + if (!ctx->preg_log_idx) { + return; + } + + zero = tcg_const_tl(0); + control_reg = tcg_temp_new(); + pval = tcg_temp_new(); + + /* + * Only endloop instructions will conditionally + * write a predicate. If there are no endloop + * instructions, we can use the non-conditional + * write of the predicates. + */ + if (pkt->pkt_has_endloop) { + TCGv pred_written = tcg_temp_new(); + for (i = 0; i < ctx->preg_log_idx; i++) { + int pred_num = ctx->preg_log[i]; + + tcg_gen_andi_tl(pred_written, hex_pred_written, 1 << pred_num); + tcg_gen_movcond_tl(TCG_COND_NE, hex_pred[pred_num], + pred_written, zero, + hex_new_pred_value[pred_num], + hex_pred[pred_num]); + } + tcg_temp_free(pred_written); + } else { + for (i = 0; i < ctx->preg_log_idx; i++) { + int pred_num = ctx->preg_log[i]; + tcg_gen_mov_tl(hex_pred[pred_num], hex_new_pred_value[pred_num]); +#if HEX_DEBUG + /* Do this so HELPER(debug_commit_end) will know */ + tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << pred_num); +#endif + } + } + + tcg_temp_free(zero); + tcg_temp_free(control_reg); + tcg_temp_free(pval); +} + +#if HEX_DEBUG +static inline void gen_check_store_width(DisasContext *ctx, int slot_num) +{ + TCGv slot = tcg_const_tl(slot_num); + TCGv check = tcg_const_tl(ctx->store_width[slot_num]); + gen_helper_debug_check_store_width(cpu_env, slot, check); + tcg_temp_free(slot); + tcg_temp_free(check); +} +#define HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num) \ + gen_check_store_width(ctx, slot_num) +#else +#define HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num) /* nothing */ +#endif + +static bool slot_is_predicated(Packet *pkt, int slot_num) +{ + for (int i = 0; i < pkt->num_insns; i++) { + if (pkt->insn[i].slot == slot_num) { + return GET_ATTRIB(pkt->insn[i].opcode, A_CONDEXEC); + } + } + /* If we get to here, we didn't find an instruction in the requested slot */ + g_assert_not_reached(); +} + +void process_store(DisasContext *ctx, Packet *pkt, int slot_num) +{ + bool is_predicated = slot_is_predicated(pkt, slot_num); + TCGLabel *label_end = NULL; + + /* + * We may have already processed this store + * See CHECK_NOSHUF in macros.h + */ + if (slot_num == 1 && ctx->s1_store_processed) { + return; + } + ctx->s1_store_processed = 1; + + if (is_predicated) { + TCGv cancelled = tcg_temp_new(); + label_end = gen_new_label(); + + /* Don't do anything if the slot was cancelled */ + tcg_gen_extract_tl(cancelled, hex_slot_cancelled, slot_num, 1); + tcg_gen_brcondi_tl(TCG_COND_NE, cancelled, 0, label_end); + tcg_temp_free(cancelled); + } + { + TCGv address = tcg_temp_local_new(); + tcg_gen_mov_tl(address, hex_store_addr[slot_num]); + + /* + * If we know the width from the DisasContext, we can + * generate much cleaner code. + * Unfortunately, not all instructions execute the fSTORE + * macro during code generation. Anything that uses the + * generic helper will have this problem. Instructions + * that use fWRAP to generate proper TCG code will be OK. + */ + switch (ctx->store_width[slot_num]) { + case 1: + HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num); + tcg_gen_qemu_st8(hex_store_val32[slot_num], + hex_store_addr[slot_num], + ctx->mem_idx); + break; + case 2: + HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num); + tcg_gen_qemu_st16(hex_store_val32[slot_num], + hex_store_addr[slot_num], + ctx->mem_idx); + break; + case 4: + HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num); + tcg_gen_qemu_st32(hex_store_val32[slot_num], + hex_store_addr[slot_num], + ctx->mem_idx); + break; + case 8: + HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num); + tcg_gen_qemu_st64(hex_store_val64[slot_num], + hex_store_addr[slot_num], + ctx->mem_idx); + break; + default: + { + /* + * If we get to here, we don't know the width at + * TCG generation time, we'll use a helper to + * avoid branching based on the width at runtime. + */ + TCGv slot = tcg_const_tl(slot_num); + gen_helper_commit_store(cpu_env, slot); + tcg_temp_free(slot); + } + } + tcg_temp_free(address); + } + if (is_predicated) { + gen_set_label(label_end); + } +} + +static void process_store_log(DisasContext *ctx, Packet *pkt) +{ + /* + * When a packet has two stores, the hardware processes + * slot 1 and then slot 2. This will be important when + * the memory accesses overlap. + */ + if (pkt->pkt_has_store_s1 && !pkt->pkt_has_dczeroa) { + process_store(ctx, pkt, 1); + } + if (pkt->pkt_has_store_s0 && !pkt->pkt_has_dczeroa) { + process_store(ctx, pkt, 0); + } +} + +/* Zero out a 32-bit cache line */ +static void process_dczeroa(DisasContext *ctx, Packet *pkt) +{ + if (pkt->pkt_has_dczeroa) { + /* Store 32 bytes of zero starting at (addr & ~0x1f) */ + TCGv addr = tcg_temp_new(); + TCGv_i64 zero = tcg_const_i64(0); + + tcg_gen_andi_tl(addr, hex_dczero_addr, ~0x1f); + tcg_gen_qemu_st64(zero, addr, ctx->mem_idx); + tcg_gen_addi_tl(addr, addr, 8); + tcg_gen_qemu_st64(zero, addr, ctx->mem_idx); + tcg_gen_addi_tl(addr, addr, 8); + tcg_gen_qemu_st64(zero, addr, ctx->mem_idx); + tcg_gen_addi_tl(addr, addr, 8); + tcg_gen_qemu_st64(zero, addr, ctx->mem_idx); + + tcg_temp_free(addr); + tcg_temp_free_i64(zero); + } +} + +static void update_exec_counters(DisasContext *ctx, Packet *pkt) +{ + int num_insns = pkt->num_insns; + int num_real_insns = 0; + + for (int i = 0; i < num_insns; i++) { + if (!pkt->insn[i].is_endloop && + !pkt->insn[i].part1 && + !GET_ATTRIB(pkt->insn[i].opcode, A_IT_NOP)) { + num_real_insns++; + } + } + + ctx->num_packets++; + ctx->num_insns += num_real_insns; +} + +static void gen_exec_counters(DisasContext *ctx) +{ + tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_PKT_CNT], + hex_gpr[HEX_REG_QEMU_PKT_CNT], ctx->num_packets); + tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_INSN_CNT], + hex_gpr[HEX_REG_QEMU_INSN_CNT], ctx->num_insns); +} + +static void gen_commit_packet(DisasContext *ctx, Packet *pkt) +{ + gen_reg_writes(ctx); + gen_pred_writes(ctx, pkt); + process_store_log(ctx, pkt); + process_dczeroa(ctx, pkt); + update_exec_counters(ctx, pkt); +#if HEX_DEBUG + { + TCGv has_st0 = + tcg_const_tl(pkt->pkt_has_store_s0 && !pkt->pkt_has_dczeroa); + TCGv has_st1 = + tcg_const_tl(pkt->pkt_has_store_s1 && !pkt->pkt_has_dczeroa); + + /* Handy place to set a breakpoint at the end of execution */ + gen_helper_debug_commit_end(cpu_env, has_st0, has_st1); + + tcg_temp_free(has_st0); + tcg_temp_free(has_st1); + } +#endif + + if (pkt->pkt_has_cof) { + ctx->base.is_jmp = DISAS_NORETURN; + } +} + +static void decode_and_translate_packet(CPUHexagonState *env, DisasContext *ctx) +{ + uint32_t words[PACKET_WORDS_MAX]; + int nwords; + Packet pkt; + int i; + + nwords = read_packet_words(env, ctx, words); + if (!nwords) { + gen_exception(HEX_EXCP_INVALID_PACKET); + ctx->base.is_jmp = DISAS_NORETURN; + return; + } + + if (decode_packet(nwords, words, &pkt, false) > 0) { + HEX_DEBUG_PRINT_PKT(&pkt); + gen_start_packet(ctx, &pkt); + for (i = 0; i < pkt.num_insns; i++) { + gen_insn(env, ctx, &pkt.insn[i], &pkt); + } + gen_commit_packet(ctx, &pkt); + ctx->base.pc_next += pkt.encod_pkt_size_in_bytes; + } else { + gen_exception(HEX_EXCP_INVALID_PACKET); + ctx->base.is_jmp = DISAS_NORETURN; + } +} + +static void hexagon_tr_init_disas_context(DisasContextBase *dcbase, + CPUState *cs) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + ctx->mem_idx = MMU_USER_IDX; + ctx->num_packets = 0; + ctx->num_insns = 0; +} + +static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu) +{ +} + +static void hexagon_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + tcg_gen_insn_start(ctx->base.pc_next); +} + +static bool hexagon_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu, + const CPUBreakpoint *bp) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->base.pc_next); + ctx->base.is_jmp = DISAS_NORETURN; + gen_exception_debug(); + /* + * The address covered by the breakpoint must be included in + * [tb->pc, tb->pc + tb->size) in order to for it to be + * properly cleared -- thus we increment the PC here so that + * the logic setting tb->size below does the right thing. + */ + ctx->base.pc_next += 4; + return true; +} + +static bool pkt_crosses_page(CPUHexagonState *env, DisasContext *ctx) +{ + target_ulong page_start = ctx->base.pc_first & TARGET_PAGE_MASK; + bool found_end = false; + int nwords; + + for (nwords = 0; !found_end && nwords < PACKET_WORDS_MAX; nwords++) { + uint32_t word = cpu_ldl_code(env, + ctx->base.pc_next + nwords * sizeof(uint32_t)); + found_end = is_packet_end(word); + } + uint32_t next_ptr = ctx->base.pc_next + nwords * sizeof(uint32_t); + return found_end && next_ptr - page_start >= TARGET_PAGE_SIZE; +} + +static void hexagon_tr_translate_packet(DisasContextBase *dcbase, CPUState *cpu) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + CPUHexagonState *env = cpu->env_ptr; + + decode_and_translate_packet(env, ctx); + + if (ctx->base.is_jmp == DISAS_NEXT) { + target_ulong page_start = ctx->base.pc_first & TARGET_PAGE_MASK; + target_ulong bytes_max = PACKET_WORDS_MAX * sizeof(target_ulong); + + if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE || + (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE - bytes_max && + pkt_crosses_page(env, ctx))) { + ctx->base.is_jmp = DISAS_TOO_MANY; + } + + /* + * The CPU log is used to compare against LLDB single stepping, + * so end the TLB after every packet. + */ + HexagonCPU *hex_cpu = container_of(env, HexagonCPU, env); + if (hex_cpu->lldb_compat && qemu_loglevel_mask(CPU_LOG_TB_CPU)) { + ctx->base.is_jmp = DISAS_TOO_MANY; + } +#if HEX_DEBUG + /* When debugging, only put one packet per TB */ + ctx->base.is_jmp = DISAS_TOO_MANY; +#endif + } +} + +static void hexagon_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + switch (ctx->base.is_jmp) { + case DISAS_TOO_MANY: + gen_exec_counters(ctx); + tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->base.pc_next); + if (ctx->base.singlestep_enabled) { + gen_exception_debug(); + } else { + tcg_gen_exit_tb(NULL, 0); + } + break; + case DISAS_NORETURN: + gen_exec_counters(ctx); + tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC); + if (ctx->base.singlestep_enabled) { + gen_exception_debug(); + } else { + tcg_gen_exit_tb(NULL, 0); + } + break; + default: + g_assert_not_reached(); + } +} + +static void hexagon_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu) +{ + qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); + log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size); +} + + +static const TranslatorOps hexagon_tr_ops = { + .init_disas_context = hexagon_tr_init_disas_context, + .tb_start = hexagon_tr_tb_start, + .insn_start = hexagon_tr_insn_start, + .breakpoint_check = hexagon_tr_breakpoint_check, + .translate_insn = hexagon_tr_translate_packet, + .tb_stop = hexagon_tr_tb_stop, + .disas_log = hexagon_tr_disas_log, +}; + +void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) +{ + DisasContext ctx; + + translator_loop(&hexagon_tr_ops, &ctx.base, cs, tb, max_insns); +} + +#define NAME_LEN 64 +static char new_value_names[TOTAL_PER_THREAD_REGS][NAME_LEN]; +#if HEX_DEBUG +static char reg_written_names[TOTAL_PER_THREAD_REGS][NAME_LEN]; +#endif +static char new_pred_value_names[NUM_PREGS][NAME_LEN]; +static char store_addr_names[STORES_MAX][NAME_LEN]; +static char store_width_names[STORES_MAX][NAME_LEN]; +static char store_val32_names[STORES_MAX][NAME_LEN]; +static char store_val64_names[STORES_MAX][NAME_LEN]; + +void hexagon_translate_init(void) +{ + int i; + + opcode_init(); + +#if HEX_DEBUG + if (!qemu_logfile) { + qemu_set_log(qemu_loglevel); + } +#endif + + for (i = 0; i < TOTAL_PER_THREAD_REGS; i++) { + hex_gpr[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, gpr[i]), + hexagon_regnames[i]); + + snprintf(new_value_names[i], NAME_LEN, "new_%s", hexagon_regnames[i]); + hex_new_value[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, new_value[i]), + new_value_names[i]); + +#if HEX_DEBUG + snprintf(reg_written_names[i], NAME_LEN, "reg_written_%s", + hexagon_regnames[i]); + hex_reg_written[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, reg_written[i]), + reg_written_names[i]); +#endif + } + for (i = 0; i < NUM_PREGS; i++) { + hex_pred[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, pred[i]), + hexagon_prednames[i]); + + snprintf(new_pred_value_names[i], NAME_LEN, "new_pred_%s", + hexagon_prednames[i]); + hex_new_pred_value[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, new_pred_value[i]), + new_pred_value_names[i]); + } + hex_pred_written = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, pred_written), "pred_written"); + hex_next_PC = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, next_PC), "next_PC"); + hex_this_PC = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, this_PC), "this_PC"); + hex_slot_cancelled = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, slot_cancelled), "slot_cancelled"); + hex_branch_taken = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, branch_taken), "branch_taken"); + hex_pkt_has_store_s1 = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, pkt_has_store_s1), "pkt_has_store_s1"); + hex_dczero_addr = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, dczero_addr), "dczero_addr"); + hex_llsc_addr = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, llsc_addr), "llsc_addr"); + hex_llsc_val = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, llsc_val), "llsc_val"); + hex_llsc_val_i64 = tcg_global_mem_new_i64(cpu_env, + offsetof(CPUHexagonState, llsc_val_i64), "llsc_val_i64"); + for (i = 0; i < STORES_MAX; i++) { + snprintf(store_addr_names[i], NAME_LEN, "store_addr_%d", i); + hex_store_addr[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, mem_log_stores[i].va), + store_addr_names[i]); + + snprintf(store_width_names[i], NAME_LEN, "store_width_%d", i); + hex_store_width[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, mem_log_stores[i].width), + store_width_names[i]); + + snprintf(store_val32_names[i], NAME_LEN, "store_val32_%d", i); + hex_store_val32[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUHexagonState, mem_log_stores[i].data32), + store_val32_names[i]); + + snprintf(store_val64_names[i], NAME_LEN, "store_val64_%d", i); + hex_store_val64[i] = tcg_global_mem_new_i64(cpu_env, + offsetof(CPUHexagonState, mem_log_stores[i].data64), + store_val64_names[i]); + } +} From patchwork Wed Feb 17 23:40:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384186 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3228489jao; Wed, 17 Feb 2021 16:02:06 -0800 (PST) X-Google-Smtp-Source: ABdhPJz2xppqV+lRKccAvy2kQSri/1KemgY6uKkdpig1VGvMKbLc+dGjsiGYtoTtlma51i/SuZU8 X-Received: by 2002:a25:bb8f:: with SMTP id y15mr2725165ybg.139.1613606526040; Wed, 17 Feb 2021 16:02:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606526; cv=none; d=google.com; s=arc-20160816; b=jJHn0IWDDMIDawfs1jn3VBVF1PDYOm0fUw2U8E6unM9JtlEyfoVeBvQhFIEGA0EnWl We+pgOaihBHZcWYHl8hqq5JpIS0+uY4LgrEaeyf+vGHViv4fdGk4I0LsmsdxTWzRnaLa zJXQg8IOJJN7JAHMGXVcjElrBhTt88qO7JG7HRHYdwTHE/cq2AolFxIoh11og8JGFg6r cndhmzJ4EwhHsAcilnOqABkdDP9AwUnpSFy5GdYXv1lgTr9Q8e0Fe7Bmuaf65aR+/89H yGCLSL6JzfIjjhbUHnj6OiCVkvjtNPdMlLqw058RzDTAYM2z8mL1QWcdMiO8fPk1RIXp Senw== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=4EPmjuaGE7ZBBXtu7+OR7f/4m7lqfO4FggB5/JvTrYU=; b=w2FqxzG5vlmfSl3RH/92uiQ46BXwMeSXfjImb7Y5qqsO34wWB75AuZIsmpF+N3/3ah H2c/nb25DBwNSVdVvsNoidrP9tzcevUv+voej19Z6CLrdr4mkXutJpAgJSWuHDRckw0P YAEIZCjAtVOq+AWV47ZYl9xVu2uvygSe1CKlxVwi4oZh6pHzJsyO9t9pPeAeHUOCY8bE M18oTctR7+5bERupKwIirjX3Vcc+pce4mEMUyU3k/gOfKwkNtchQcr7NanQ4LXMvgu3l rCsIsCzEOdBmnPSLOadX1mb/UCfbLEbyf8m7SGIY//OKoY+BvZc8P81Uym17SRQQ6oAE k8sg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Igk+HgTn; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id n137si3835943yba.468.2021.02.17.16.02.05 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 16:02:06 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Igk+HgTn; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:39154 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWlh-0000PS-4s for patch@linaro.org; Wed, 17 Feb 2021 19:02:05 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51200) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWSE-0001Dv-J3 for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:58 -0500 Received: from mail-pf1-x432.google.com ([2607:f8b0:4864:20::432]:43147) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWRy-0004uf-2j for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:58 -0500 Received: by mail-pf1-x432.google.com with SMTP id c11so22277pfp.10 for ; Wed, 17 Feb 2021 15:41:38 -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 :mime-version:content-transfer-encoding; bh=4EPmjuaGE7ZBBXtu7+OR7f/4m7lqfO4FggB5/JvTrYU=; b=Igk+HgTnTVA4GfQIt5CeReajT8e5RmsH18Ejm96CRwDrznNarsdPIPbd0+pCq43hr+ m3q9UwBP+/SywDkA1zgmLIslAZv/nQWeEDfaXIYf7eNB8fWzgIlOkCwJ353nABPNb7bc /6O4vpnyfhFSqO2MOLjOvo4GqLma8xrUNvVSdHoqfYvnnddPQdo8eYYM7uJ7iD9IhKhR PATa24lWYwDxiyLVdXHycofj98Locyf7Pv9K8NsEZgdZkT9bzJnDQYnFjVXwLfWGr2LV 87C7EC/ee+4jtdXsUxdXp5OAzTKjnwdaVZbBTsO9iQOEq9zeX1ZsFGy45Qe1ZB7isW5q 05Kg== 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:mime-version:content-transfer-encoding; bh=4EPmjuaGE7ZBBXtu7+OR7f/4m7lqfO4FggB5/JvTrYU=; b=DT9unz55dFeM2KuzFl6Qp+Ff+uzbW9bC0tZ6iF3GnWJuuL0n7xpaPEt2Poo9lAQ3TP G/DZlk2QhUXqIX2+/qW3iSXDGHKRBPy6P/beUxlDs5FTzIb7n5wslazSTWEmHd859pOa SYND+Wk3+zLOFKCRN09CK+Y+LFyRg9jCORauxYrTxb89NDJZaj7JtBoXV6mkh0W8Qdvc ynqEWZW1JSlN9gYNsdik7CSj3AR85uWIwmz/eojhGmL9owN3QVBwQGiYGsaSEBjajgsB 4dA1n+mX8aRn53hParYwrGewsfPFtYzJLVOmUtNr3/4366x+zW3zgYpoxvU+LQB6fCwz s2mg== X-Gm-Message-State: AOAM5307XZsqqFly7z5RPScuwyRMhwWwvC91c2ogM5MQAxv/8uaylLyo 5HAzOM3UgNVqHcNqIvk62KgAfZWZi805yA== X-Received: by 2002:aa7:991c:0:b029:1e8:b29:cd69 with SMTP id z28-20020aa7991c0000b02901e80b29cd69mr1619827pff.50.1613605297067; Wed, 17 Feb 2021 15:41:37 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:36 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 31/35] Hexagon (linux-user/hexagon) Linux user emulation Date: Wed, 17 Feb 2021 15:40:19 -0800 Message-Id: <20210217234023.1742406-32-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::432; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x432.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , Laurent Vivier Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Implementation of Linux user emulation for Hexagon Some common files modified in addition to new files in linux-user/hexagon Acked-by: Laurent Vivier Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-31-git-send-email-tsimpson@quicinc.com> [rth: Fix termbits.h on review by Laurent] Signed-off-by: Richard Henderson --- linux-user/hexagon/sockbits.h | 18 ++ linux-user/hexagon/syscall_nr.h | 322 ++++++++++++++++++++++++++++ linux-user/hexagon/target_cpu.h | 44 ++++ linux-user/hexagon/target_elf.h | 40 ++++ linux-user/hexagon/target_fcntl.h | 18 ++ linux-user/hexagon/target_signal.h | 34 +++ linux-user/hexagon/target_structs.h | 54 +++++ linux-user/hexagon/target_syscall.h | 36 ++++ linux-user/hexagon/termbits.h | 18 ++ linux-user/qemu.h | 2 + linux-user/syscall_defs.h | 33 +++ linux-user/elfload.c | 16 ++ linux-user/hexagon/cpu_loop.c | 100 +++++++++ linux-user/hexagon/signal.c | 276 ++++++++++++++++++++++++ scripts/gensyscalls.sh | 1 + 15 files changed, 1012 insertions(+) create mode 100644 linux-user/hexagon/sockbits.h create mode 100644 linux-user/hexagon/syscall_nr.h create mode 100644 linux-user/hexagon/target_cpu.h create mode 100644 linux-user/hexagon/target_elf.h create mode 100644 linux-user/hexagon/target_fcntl.h create mode 100644 linux-user/hexagon/target_signal.h create mode 100644 linux-user/hexagon/target_structs.h create mode 100644 linux-user/hexagon/target_syscall.h create mode 100644 linux-user/hexagon/termbits.h create mode 100644 linux-user/hexagon/cpu_loop.c create mode 100644 linux-user/hexagon/signal.c -- 2.25.1 diff --git a/linux-user/hexagon/sockbits.h b/linux-user/hexagon/sockbits.h new file mode 100644 index 0000000000..b7ad5dc60e --- /dev/null +++ b/linux-user/hexagon/sockbits.h @@ -0,0 +1,18 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "../generic/sockbits.h" diff --git a/linux-user/hexagon/syscall_nr.h b/linux-user/hexagon/syscall_nr.h new file mode 100644 index 0000000000..da1314f713 --- /dev/null +++ b/linux-user/hexagon/syscall_nr.h @@ -0,0 +1,322 @@ +/* + * This file contains the system call numbers. + * Do not modify. + * This file is generated by scripts/gensyscalls.sh + */ +#ifndef LINUX_USER_HEXAGON_SYSCALL_NR_H +#define LINUX_USER_HEXAGON_SYSCALL_NR_H + +#define TARGET_NR_io_setup 0 +#define TARGET_NR_io_destroy 1 +#define TARGET_NR_io_submit 2 +#define TARGET_NR_io_cancel 3 +#define TARGET_NR_io_getevents 4 +#define TARGET_NR_setxattr 5 +#define TARGET_NR_lsetxattr 6 +#define TARGET_NR_fsetxattr 7 +#define TARGET_NR_getxattr 8 +#define TARGET_NR_lgetxattr 9 +#define TARGET_NR_fgetxattr 10 +#define TARGET_NR_listxattr 11 +#define TARGET_NR_llistxattr 12 +#define TARGET_NR_flistxattr 13 +#define TARGET_NR_removexattr 14 +#define TARGET_NR_lremovexattr 15 +#define TARGET_NR_fremovexattr 16 +#define TARGET_NR_getcwd 17 +#define TARGET_NR_lookup_dcookie 18 +#define TARGET_NR_eventfd2 19 +#define TARGET_NR_epoll_create1 20 +#define TARGET_NR_epoll_ctl 21 +#define TARGET_NR_epoll_pwait 22 +#define TARGET_NR_dup 23 +#define TARGET_NR_dup3 24 +#define TARGET_NR_fcntl64 25 +#define TARGET_NR_inotify_init1 26 +#define TARGET_NR_inotify_add_watch 27 +#define TARGET_NR_inotify_rm_watch 28 +#define TARGET_NR_ioctl 29 +#define TARGET_NR_ioprio_set 30 +#define TARGET_NR_ioprio_get 31 +#define TARGET_NR_flock 32 +#define TARGET_NR_mknodat 33 +#define TARGET_NR_mkdirat 34 +#define TARGET_NR_unlinkat 35 +#define TARGET_NR_symlinkat 36 +#define TARGET_NR_linkat 37 +#define TARGET_NR_renameat 38 +#define TARGET_NR_umount2 39 +#define TARGET_NR_mount 40 +#define TARGET_NR_pivot_root 41 +#define TARGET_NR_nfsservctl 42 +#define TARGET_NR_statfs64 43 +#define TARGET_NR_fstatfs64 44 +#define TARGET_NR_truncate64 45 +#define TARGET_NR_ftruncate64 46 +#define TARGET_NR_fallocate 47 +#define TARGET_NR_faccessat 48 +#define TARGET_NR_chdir 49 +#define TARGET_NR_fchdir 50 +#define TARGET_NR_chroot 51 +#define TARGET_NR_fchmod 52 +#define TARGET_NR_fchmodat 53 +#define TARGET_NR_fchownat 54 +#define TARGET_NR_fchown 55 +#define TARGET_NR_openat 56 +#define TARGET_NR_close 57 +#define TARGET_NR_vhangup 58 +#define TARGET_NR_pipe2 59 +#define TARGET_NR_quotactl 60 +#define TARGET_NR_getdents64 61 +#define TARGET_NR_llseek 62 +#define TARGET_NR_read 63 +#define TARGET_NR_write 64 +#define TARGET_NR_readv 65 +#define TARGET_NR_writev 66 +#define TARGET_NR_pread64 67 +#define TARGET_NR_pwrite64 68 +#define TARGET_NR_preadv 69 +#define TARGET_NR_pwritev 70 +#define TARGET_NR_sendfile64 71 +#define TARGET_NR_pselect6 72 +#define TARGET_NR_ppoll 73 +#define TARGET_NR_signalfd4 74 +#define TARGET_NR_vmsplice 75 +#define TARGET_NR_splice 76 +#define TARGET_NR_tee 77 +#define TARGET_NR_readlinkat 78 +#define TARGET_NR_fstatat64 79 +#define TARGET_NR_fstat64 80 +#define TARGET_NR_sync 81 +#define TARGET_NR_fsync 82 +#define TARGET_NR_fdatasync 83 +#define TARGET_NR_sync_file_range 84 +#define TARGET_NR_timerfd_create 85 +#define TARGET_NR_timerfd_settime 86 +#define TARGET_NR_timerfd_gettime 87 +#define TARGET_NR_utimensat 88 +#define TARGET_NR_acct 89 +#define TARGET_NR_capget 90 +#define TARGET_NR_capset 91 +#define TARGET_NR_personality 92 +#define TARGET_NR_exit 93 +#define TARGET_NR_exit_group 94 +#define TARGET_NR_waitid 95 +#define TARGET_NR_set_tid_address 96 +#define TARGET_NR_unshare 97 +#define TARGET_NR_futex 98 +#define TARGET_NR_set_robust_list 99 +#define TARGET_NR_get_robust_list 100 +#define TARGET_NR_nanosleep 101 +#define TARGET_NR_getitimer 102 +#define TARGET_NR_setitimer 103 +#define TARGET_NR_kexec_load 104 +#define TARGET_NR_init_module 105 +#define TARGET_NR_delete_module 106 +#define TARGET_NR_timer_create 107 +#define TARGET_NR_timer_gettime 108 +#define TARGET_NR_timer_getoverrun 109 +#define TARGET_NR_timer_settime 110 +#define TARGET_NR_timer_delete 111 +#define TARGET_NR_clock_settime 112 +#define TARGET_NR_clock_gettime 113 +#define TARGET_NR_clock_getres 114 +#define TARGET_NR_clock_nanosleep 115 +#define TARGET_NR_syslog 116 +#define TARGET_NR_ptrace 117 +#define TARGET_NR_sched_setparam 118 +#define TARGET_NR_sched_setscheduler 119 +#define TARGET_NR_sched_getscheduler 120 +#define TARGET_NR_sched_getparam 121 +#define TARGET_NR_sched_setaffinity 122 +#define TARGET_NR_sched_getaffinity 123 +#define TARGET_NR_sched_yield 124 +#define TARGET_NR_sched_get_priority_max 125 +#define TARGET_NR_sched_get_priority_min 126 +#define TARGET_NR_sched_rr_get_interval 127 +#define TARGET_NR_restart_syscall 128 +#define TARGET_NR_kill 129 +#define TARGET_NR_tkill 130 +#define TARGET_NR_tgkill 131 +#define TARGET_NR_sigaltstack 132 +#define TARGET_NR_rt_sigsuspend 133 +#define TARGET_NR_rt_sigaction 134 +#define TARGET_NR_rt_sigprocmask 135 +#define TARGET_NR_rt_sigpending 136 +#define TARGET_NR_rt_sigtimedwait 137 +#define TARGET_NR_rt_sigqueueinfo 138 +#define TARGET_NR_rt_sigreturn 139 +#define TARGET_NR_setpriority 140 +#define TARGET_NR_getpriority 141 +#define TARGET_NR_reboot 142 +#define TARGET_NR_setregid 143 +#define TARGET_NR_setgid 144 +#define TARGET_NR_setreuid 145 +#define TARGET_NR_setuid 146 +#define TARGET_NR_setresuid 147 +#define TARGET_NR_getresuid 148 +#define TARGET_NR_setresgid 149 +#define TARGET_NR_getresgid 150 +#define TARGET_NR_setfsuid 151 +#define TARGET_NR_setfsgid 152 +#define TARGET_NR_times 153 +#define TARGET_NR_setpgid 154 +#define TARGET_NR_getpgid 155 +#define TARGET_NR_getsid 156 +#define TARGET_NR_setsid 157 +#define TARGET_NR_getgroups 158 +#define TARGET_NR_setgroups 159 +#define TARGET_NR_uname 160 +#define TARGET_NR_sethostname 161 +#define TARGET_NR_setdomainname 162 +#define TARGET_NR_getrlimit 163 +#define TARGET_NR_setrlimit 164 +#define TARGET_NR_getrusage 165 +#define TARGET_NR_umask 166 +#define TARGET_NR_prctl 167 +#define TARGET_NR_getcpu 168 +#define TARGET_NR_gettimeofday 169 +#define TARGET_NR_settimeofday 170 +#define TARGET_NR_adjtimex 171 +#define TARGET_NR_getpid 172 +#define TARGET_NR_getppid 173 +#define TARGET_NR_getuid 174 +#define TARGET_NR_geteuid 175 +#define TARGET_NR_getgid 176 +#define TARGET_NR_getegid 177 +#define TARGET_NR_gettid 178 +#define TARGET_NR_sysinfo 179 +#define TARGET_NR_mq_open 180 +#define TARGET_NR_mq_unlink 181 +#define TARGET_NR_mq_timedsend 182 +#define TARGET_NR_mq_timedreceive 183 +#define TARGET_NR_mq_notify 184 +#define TARGET_NR_mq_getsetattr 185 +#define TARGET_NR_msgget 186 +#define TARGET_NR_msgctl 187 +#define TARGET_NR_msgrcv 188 +#define TARGET_NR_msgsnd 189 +#define TARGET_NR_semget 190 +#define TARGET_NR_semctl 191 +#define TARGET_NR_semtimedop 192 +#define TARGET_NR_semop 193 +#define TARGET_NR_shmget 194 +#define TARGET_NR_shmctl 195 +#define TARGET_NR_shmat 196 +#define TARGET_NR_shmdt 197 +#define TARGET_NR_socket 198 +#define TARGET_NR_socketpair 199 +#define TARGET_NR_bind 200 +#define TARGET_NR_listen 201 +#define TARGET_NR_accept 202 +#define TARGET_NR_connect 203 +#define TARGET_NR_getsockname 204 +#define TARGET_NR_getpeername 205 +#define TARGET_NR_sendto 206 +#define TARGET_NR_recvfrom 207 +#define TARGET_NR_setsockopt 208 +#define TARGET_NR_getsockopt 209 +#define TARGET_NR_shutdown 210 +#define TARGET_NR_sendmsg 211 +#define TARGET_NR_recvmsg 212 +#define TARGET_NR_readahead 213 +#define TARGET_NR_brk 214 +#define TARGET_NR_munmap 215 +#define TARGET_NR_mremap 216 +#define TARGET_NR_add_key 217 +#define TARGET_NR_request_key 218 +#define TARGET_NR_keyctl 219 +#define TARGET_NR_clone 220 +#define TARGET_NR_execve 221 +#define TARGET_NR_mmap2 222 +#define TARGET_NR_fadvise64_64 223 +#define TARGET_NR_swapon 224 +#define TARGET_NR_swapoff 225 +#define TARGET_NR_mprotect 226 +#define TARGET_NR_msync 227 +#define TARGET_NR_mlock 228 +#define TARGET_NR_munlock 229 +#define TARGET_NR_mlockall 230 +#define TARGET_NR_munlockall 231 +#define TARGET_NR_mincore 232 +#define TARGET_NR_madvise 233 +#define TARGET_NR_remap_file_pages 234 +#define TARGET_NR_mbind 235 +#define TARGET_NR_get_mempolicy 236 +#define TARGET_NR_set_mempolicy 237 +#define TARGET_NR_migrate_pages 238 +#define TARGET_NR_move_pages 239 +#define TARGET_NR_rt_tgsigqueueinfo 240 +#define TARGET_NR_perf_event_open 241 +#define TARGET_NR_accept4 242 +#define TARGET_NR_recvmmsg 243 +#define TARGET_NR_arch_specific_syscall 244 +#define TARGET_NR_wait4 260 +#define TARGET_NR_prlimit64 261 +#define TARGET_NR_fanotify_init 262 +#define TARGET_NR_fanotify_mark 263 +#define TARGET_NR_name_to_handle_at 264 +#define TARGET_NR_open_by_handle_at 265 +#define TARGET_NR_clock_adjtime 266 +#define TARGET_NR_syncfs 267 +#define TARGET_NR_setns 268 +#define TARGET_NR_sendmmsg 269 +#define TARGET_NR_process_vm_readv 270 +#define TARGET_NR_process_vm_writev 271 +#define TARGET_NR_kcmp 272 +#define TARGET_NR_finit_module 273 +#define TARGET_NR_sched_setattr 274 +#define TARGET_NR_sched_getattr 275 +#define TARGET_NR_renameat2 276 +#define TARGET_NR_seccomp 277 +#define TARGET_NR_getrandom 278 +#define TARGET_NR_memfd_create 279 +#define TARGET_NR_bpf 280 +#define TARGET_NR_execveat 281 +#define TARGET_NR_userfaultfd 282 +#define TARGET_NR_membarrier 283 +#define TARGET_NR_mlock2 284 +#define TARGET_NR_copy_file_range 285 +#define TARGET_NR_preadv2 286 +#define TARGET_NR_pwritev2 287 +#define TARGET_NR_pkey_mprotect 288 +#define TARGET_NR_pkey_alloc 289 +#define TARGET_NR_pkey_free 290 +#define TARGET_NR_statx 291 +#define TARGET_NR_io_pgetevents 292 +#define TARGET_NR_rseq 293 +#define TARGET_NR_kexec_file_load 294 +#define TARGET_NR_clock_gettime64 403 +#define TARGET_NR_clock_settime64 404 +#define TARGET_NR_clock_adjtime64 405 +#define TARGET_NR_clock_getres_time64 406 +#define TARGET_NR_clock_nanosleep_time64 407 +#define TARGET_NR_timer_gettime64 408 +#define TARGET_NR_timer_settime64 409 +#define TARGET_NR_timerfd_gettime64 410 +#define TARGET_NR_timerfd_settime64 411 +#define TARGET_NR_utimensat_time64 412 +#define TARGET_NR_pselect6_time64 413 +#define TARGET_NR_ppoll_time64 414 +#define TARGET_NR_io_pgetevents_time64 416 +#define TARGET_NR_recvmmsg_time64 417 +#define TARGET_NR_mq_timedsend_time64 418 +#define TARGET_NR_mq_timedreceive_time64 419 +#define TARGET_NR_semtimedop_time64 420 +#define TARGET_NR_rt_sigtimedwait_time64 421 +#define TARGET_NR_futex_time64 422 +#define TARGET_NR_sched_rr_get_interval_time64 423 +#define TARGET_NR_pidfd_send_signal 424 +#define TARGET_NR_io_uring_setup 425 +#define TARGET_NR_io_uring_enter 426 +#define TARGET_NR_io_uring_register 427 +#define TARGET_NR_open_tree 428 +#define TARGET_NR_move_mount 429 +#define TARGET_NR_fsopen 430 +#define TARGET_NR_fsconfig 431 +#define TARGET_NR_fsmount 432 +#define TARGET_NR_fspick 433 +#define TARGET_NR_pidfd_open 434 +#define TARGET_NR_syscalls 436 + +#endif /* LINUX_USER_HEXAGON_SYSCALL_NR_H */ diff --git a/linux-user/hexagon/target_cpu.h b/linux-user/hexagon/target_cpu.h new file mode 100644 index 0000000000..ecb76e9268 --- /dev/null +++ b/linux-user/hexagon/target_cpu.h @@ -0,0 +1,44 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_TARGET_CPU_H +#define HEXAGON_TARGET_CPU_H + +static inline void cpu_clone_regs_child(CPUHexagonState *env, + target_ulong newsp, unsigned flags) +{ + if (newsp) { + env->gpr[HEX_REG_SP] = newsp; + } + env->gpr[0] = 0; +} + +static inline void cpu_clone_regs_parent(CPUHexagonState *env, unsigned flags) +{ +} + +static inline void cpu_set_tls(CPUHexagonState *env, target_ulong newtls) +{ + env->gpr[HEX_REG_UGP] = newtls; +} + +static inline abi_ulong get_sp_from_cpustate(CPUHexagonState *state) +{ + return state->gpr[HEX_REG_SP]; +} + +#endif diff --git a/linux-user/hexagon/target_elf.h b/linux-user/hexagon/target_elf.h new file mode 100644 index 0000000000..b4e9f40527 --- /dev/null +++ b/linux-user/hexagon/target_elf.h @@ -0,0 +1,40 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_TARGET_ELF_H +#define HEXAGON_TARGET_ELF_H + +static inline const char *cpu_get_model(uint32_t eflags) +{ + /* For now, treat anything newer than v5 as a v67 */ + /* FIXME - Disable instructions that are newer than the specified arch */ + if (eflags == 0x04 || /* v5 */ + eflags == 0x05 || /* v55 */ + eflags == 0x60 || /* v60 */ + eflags == 0x61 || /* v61 */ + eflags == 0x62 || /* v62 */ + eflags == 0x65 || /* v65 */ + eflags == 0x66 || /* v66 */ + eflags == 0x67 || /* v67 */ + eflags == 0x8067 /* v67t */ + ) { + return "v67"; + } + return "unknown"; +} + +#endif diff --git a/linux-user/hexagon/target_fcntl.h b/linux-user/hexagon/target_fcntl.h new file mode 100644 index 0000000000..2892db8098 --- /dev/null +++ b/linux-user/hexagon/target_fcntl.h @@ -0,0 +1,18 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "../generic/fcntl.h" diff --git a/linux-user/hexagon/target_signal.h b/linux-user/hexagon/target_signal.h new file mode 100644 index 0000000000..345cf1cbb8 --- /dev/null +++ b/linux-user/hexagon/target_signal.h @@ -0,0 +1,34 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_TARGET_SIGNAL_H +#define HEXAGON_TARGET_SIGNAL_H + +typedef struct target_sigaltstack { + abi_ulong ss_sp; + abi_int ss_flags; + abi_ulong ss_size; +} target_stack_t; + +#define TARGET_SS_ONSTACK 1 +#define TARGET_SS_DISABLE 2 + +#define TARGET_MINSIGSTKSZ 2048 + +#include "../generic/signal.h" + +#endif /* TARGET_SIGNAL_H */ diff --git a/linux-user/hexagon/target_structs.h b/linux-user/hexagon/target_structs.h new file mode 100644 index 0000000000..c217d9442a --- /dev/null +++ b/linux-user/hexagon/target_structs.h @@ -0,0 +1,54 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Hexagon specific structures for linux-user + */ +#ifndef HEXAGON_TARGET_STRUCTS_H +#define HEXAGON_TARGET_STRUCTS_H + +struct target_ipc_perm { + abi_int __key; /* Key. */ + abi_uint uid; /* Owner's user ID. */ + abi_uint gid; /* Owner's group ID. */ + abi_uint cuid; /* Creator's user ID. */ + abi_uint cgid; /* Creator's group ID. */ + abi_ushort mode; /* Read/write permission. */ + abi_ushort __pad1; + abi_ushort __seq; /* Sequence number. */ + abi_ushort __pad2; + abi_ulong __unused1; + abi_ulong __unused2; +}; + +struct target_shmid_ds { + struct target_ipc_perm shm_perm; /* operation permission struct */ + abi_long shm_segsz; /* size of segment in bytes */ + abi_ulong shm_atime; /* time of last shmat() */ + abi_ulong __unused1; + abi_ulong shm_dtime; /* time of last shmdt() */ + abi_ulong __unused2; + abi_ulong shm_ctime; /* time of last change by shmctl() */ + abi_ulong __unused3; + abi_int shm_cpid; /* pid of creator */ + abi_int shm_lpid; /* pid of last shmop */ + abi_ulong shm_nattch; /* number of current attaches */ + abi_ulong __unused4; + abi_ulong __unused5; +}; + +#endif diff --git a/linux-user/hexagon/target_syscall.h b/linux-user/hexagon/target_syscall.h new file mode 100644 index 0000000000..7f91a4abc7 --- /dev/null +++ b/linux-user/hexagon/target_syscall.h @@ -0,0 +1,36 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_TARGET_SYSCALL_H +#define HEXAGON_TARGET_SYSCALL_H + +struct target_pt_regs { + abi_long sepc; + abi_long sp; +}; + +#define UNAME_MACHINE "hexagon" +#define UNAME_MINIMUM_RELEASE "4.15.0" + +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 + +#define TARGET_MCL_CURRENT 1 +#define TARGET_MCL_FUTURE 2 +#define TARGET_MCL_ONFAULT 4 + +#endif diff --git a/linux-user/hexagon/termbits.h b/linux-user/hexagon/termbits.h new file mode 100644 index 0000000000..49f974cdde --- /dev/null +++ b/linux-user/hexagon/termbits.h @@ -0,0 +1,18 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "../generic/termbits.h" diff --git a/linux-user/qemu.h b/linux-user/qemu.h index d25a5dafc0..52c981710b 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -718,6 +718,8 @@ static inline int regpairs_aligned(void *cpu_env, int num) } #elif defined(TARGET_XTENSA) static inline int regpairs_aligned(void *cpu_env, int num) { return 1; } +#elif defined(TARGET_HEXAGON) +static inline int regpairs_aligned(void *cpu_env, int num) { return 1; } #else static inline int regpairs_aligned(void *cpu_env, int num) { return 0; } #endif diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 46a960fccb..6823d8646c 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -104,6 +104,14 @@ #define TARGET_IOC_WRITE 2U #define TARGET_IOC_READ 1U +#elif defined(TARGET_HEXAGON) + +#define TARGET_IOC_SIZEBITS 14 + +#define TARGET_IOC_NONE 0U +#define TARGET_IOC_WRITE 1U +#define TARGET_IOC_READ 2U + #else #error unsupported CPU #endif @@ -2253,6 +2261,31 @@ struct target_stat64 { uint64_t st_ino; }; +#elif defined(TARGET_HEXAGON) + +struct target_stat { + unsigned long long st_dev; + unsigned long long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned long long st_rdev; + target_ulong __pad1; + long long st_size; + target_long st_blksize; + int __pad2; + long long st_blocks; + + target_long target_st_atime; + target_long target_st_atime_nsec; + target_long target_st_mtime; + target_long target_st_mtime_nsec; + target_long target_st_ctime; + target_long target_st_ctime_nsec; + int __unused[2]; +}; + #else #error unsupported CPU #endif diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 73d750c809..bab4237e90 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1514,6 +1514,22 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, #endif /* TARGET_XTENSA */ +#ifdef TARGET_HEXAGON + +#define ELF_START_MMAP 0x20000000 + +#define ELF_CLASS ELFCLASS32 +#define ELF_ARCH EM_HEXAGON + +static inline void init_thread(struct target_pt_regs *regs, + struct image_info *infop) +{ + regs->sepc = infop->entry; + regs->sp = infop->start_stack; +} + +#endif /* TARGET_HEXAGON */ + #ifndef ELF_PLATFORM #define ELF_PLATFORM (NULL) #endif diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c new file mode 100644 index 0000000000..9a68ca05c3 --- /dev/null +++ b/linux-user/hexagon/cpu_loop.c @@ -0,0 +1,100 @@ +/* + * qemu user cpu loop + * + * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu.h" +#include "cpu_loop-common.h" +#include "internal.h" + +void cpu_loop(CPUHexagonState *env) +{ + CPUState *cs = CPU(hexagon_env_get_cpu(env)); + int trapnr, signum, sigcode; + target_ulong sigaddr; + target_ulong syscallnum; + target_ulong ret; + + for (;;) { + cpu_exec_start(cs); + trapnr = cpu_exec(cs); + cpu_exec_end(cs); + process_queued_cpu_work(cs); + + signum = 0; + sigcode = 0; + sigaddr = 0; + + switch (trapnr) { + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + case HEX_EXCP_TRAP0: + syscallnum = env->gpr[6]; + env->gpr[HEX_REG_PC] += 4; + ret = do_syscall(env, + syscallnum, + env->gpr[0], + env->gpr[1], + env->gpr[2], + env->gpr[3], + env->gpr[4], + env->gpr[5], + 0, 0); + if (ret == -TARGET_ERESTARTSYS) { + env->gpr[HEX_REG_PC] -= 4; + } else if (ret != -TARGET_QEMU_ESIGRETURN) { + env->gpr[0] = ret; + } + break; + case HEX_EXCP_FETCH_NO_UPAGE: + case HEX_EXCP_PRIV_NO_UREAD: + case HEX_EXCP_PRIV_NO_UWRITE: + signum = TARGET_SIGSEGV; + sigcode = TARGET_SEGV_MAPERR; + break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; + default: + EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n", + trapnr); + exit(EXIT_FAILURE); + } + + if (signum) { + target_siginfo_t info = { + .si_signo = signum, + .si_errno = 0, + .si_code = sigcode, + ._sifields._sigfault._addr = sigaddr + }; + queue_signal(env, info.si_signo, QEMU_SI_KILL, &info); + } + + process_pending_signals(env); + } +} + +void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) +{ + env->gpr[HEX_REG_PC] = regs->sepc; + env->gpr[HEX_REG_SP] = regs->sp; + env->gpr[HEX_REG_USR] = 0x56000; +} diff --git a/linux-user/hexagon/signal.c b/linux-user/hexagon/signal.c new file mode 100644 index 0000000000..fde8dc93b7 --- /dev/null +++ b/linux-user/hexagon/signal.c @@ -0,0 +1,276 @@ +/* + * Emulation of Linux signals + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#include "qemu/osdep.h" +#include "qemu.h" +#include "signal-common.h" +#include "linux-user/trace.h" + +struct target_sigcontext { + target_ulong r0, r1, r2, r3; + target_ulong r4, r5, r6, r7; + target_ulong r8, r9, r10, r11; + target_ulong r12, r13, r14, r15; + target_ulong r16, r17, r18, r19; + target_ulong r20, r21, r22, r23; + target_ulong r24, r25, r26, r27; + target_ulong r28, r29, r30, r31; + target_ulong sa0; + target_ulong lc0; + target_ulong sa1; + target_ulong lc1; + target_ulong m0; + target_ulong m1; + target_ulong usr; + target_ulong p3_0; + target_ulong gp; + target_ulong ugp; + target_ulong pc; + target_ulong cause; + target_ulong badva; + target_ulong pad1; + target_ulong pad2; + target_ulong pad3; +}; + +struct target_ucontext { + unsigned long uc_flags; + target_ulong uc_link; /* target pointer */ + target_stack_t uc_stack; + struct target_sigcontext uc_mcontext; + target_sigset_t uc_sigmask; +}; + +struct target_rt_sigframe { + uint32_t tramp[2]; + struct target_siginfo info; + struct target_ucontext uc; +}; + +static abi_ulong get_sigframe(struct target_sigaction *ka, + CPUHexagonState *regs, size_t framesize) +{ + abi_ulong sp = get_sp_from_cpustate(regs); + + /* This is the X/Open sanctioned signal stack switching. */ + sp = target_sigsp(sp, ka) - framesize; + + sp = QEMU_ALIGN_DOWN(sp, 8); + + return sp; +} + +static void setup_sigcontext(struct target_sigcontext *sc, CPUHexagonState *env) +{ + __put_user(env->gpr[HEX_REG_R00], &sc->r0); + __put_user(env->gpr[HEX_REG_R01], &sc->r1); + __put_user(env->gpr[HEX_REG_R02], &sc->r2); + __put_user(env->gpr[HEX_REG_R03], &sc->r3); + __put_user(env->gpr[HEX_REG_R04], &sc->r4); + __put_user(env->gpr[HEX_REG_R05], &sc->r5); + __put_user(env->gpr[HEX_REG_R06], &sc->r6); + __put_user(env->gpr[HEX_REG_R07], &sc->r7); + __put_user(env->gpr[HEX_REG_R08], &sc->r8); + __put_user(env->gpr[HEX_REG_R09], &sc->r9); + __put_user(env->gpr[HEX_REG_R10], &sc->r10); + __put_user(env->gpr[HEX_REG_R11], &sc->r11); + __put_user(env->gpr[HEX_REG_R12], &sc->r12); + __put_user(env->gpr[HEX_REG_R13], &sc->r13); + __put_user(env->gpr[HEX_REG_R14], &sc->r14); + __put_user(env->gpr[HEX_REG_R15], &sc->r15); + __put_user(env->gpr[HEX_REG_R16], &sc->r16); + __put_user(env->gpr[HEX_REG_R17], &sc->r17); + __put_user(env->gpr[HEX_REG_R18], &sc->r18); + __put_user(env->gpr[HEX_REG_R19], &sc->r19); + __put_user(env->gpr[HEX_REG_R20], &sc->r20); + __put_user(env->gpr[HEX_REG_R21], &sc->r21); + __put_user(env->gpr[HEX_REG_R22], &sc->r22); + __put_user(env->gpr[HEX_REG_R23], &sc->r23); + __put_user(env->gpr[HEX_REG_R24], &sc->r24); + __put_user(env->gpr[HEX_REG_R25], &sc->r25); + __put_user(env->gpr[HEX_REG_R26], &sc->r26); + __put_user(env->gpr[HEX_REG_R27], &sc->r27); + __put_user(env->gpr[HEX_REG_R28], &sc->r28); + __put_user(env->gpr[HEX_REG_R29], &sc->r29); + __put_user(env->gpr[HEX_REG_R30], &sc->r30); + __put_user(env->gpr[HEX_REG_R31], &sc->r31); + __put_user(env->gpr[HEX_REG_SA0], &sc->sa0); + __put_user(env->gpr[HEX_REG_LC0], &sc->lc0); + __put_user(env->gpr[HEX_REG_SA1], &sc->sa1); + __put_user(env->gpr[HEX_REG_LC1], &sc->lc1); + __put_user(env->gpr[HEX_REG_M0], &sc->m0); + __put_user(env->gpr[HEX_REG_M1], &sc->m1); + __put_user(env->gpr[HEX_REG_USR], &sc->usr); + __put_user(env->gpr[HEX_REG_P3_0], &sc->p3_0); + __put_user(env->gpr[HEX_REG_GP], &sc->gp); + __put_user(env->gpr[HEX_REG_UGP], &sc->ugp); + __put_user(env->gpr[HEX_REG_PC], &sc->pc); +} + +static void setup_ucontext(struct target_ucontext *uc, + CPUHexagonState *env, target_sigset_t *set) +{ + __put_user(0, &(uc->uc_flags)); + __put_user(0, &(uc->uc_link)); + + target_save_altstack(&uc->uc_stack, env); + + int i; + for (i = 0; i < TARGET_NSIG_WORDS; i++) { + __put_user(set->sig[i], &(uc->uc_sigmask.sig[i])); + } + + setup_sigcontext(&uc->uc_mcontext, env); +} + +static inline void install_sigtramp(uint32_t *tramp) +{ + __put_user(0x7800d166, tramp + 0); /* { r6=#__NR_rt_sigreturn } */ + __put_user(0x5400c004, tramp + 1); /* { trap0(#1) } */ +} + +void setup_rt_frame(int sig, struct target_sigaction *ka, + target_siginfo_t *info, + target_sigset_t *set, CPUHexagonState *env) +{ + abi_ulong frame_addr; + struct target_rt_sigframe *frame; + + frame_addr = get_sigframe(ka, env, sizeof(*frame)); + trace_user_setup_rt_frame(env, frame_addr); + + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { + goto badframe; + } + + setup_ucontext(&frame->uc, env, set); + tswap_siginfo(&frame->info, info); + install_sigtramp(frame->tramp); + + env->gpr[HEX_REG_PC] = ka->_sa_handler; + env->gpr[HEX_REG_SP] = frame_addr; + env->gpr[HEX_REG_R00] = sig; + env->gpr[HEX_REG_R01] = + frame_addr + offsetof(struct target_rt_sigframe, info); + env->gpr[HEX_REG_R02] = + frame_addr + offsetof(struct target_rt_sigframe, uc); + env->gpr[HEX_REG_LR] = + frame_addr + offsetof(struct target_rt_sigframe, tramp); + + return; + +badframe: + unlock_user_struct(frame, frame_addr, 1); + if (sig == TARGET_SIGSEGV) { + ka->_sa_handler = TARGET_SIG_DFL; + } + force_sig(TARGET_SIGSEGV); +} + +static void restore_sigcontext(CPUHexagonState *env, + struct target_sigcontext *sc) +{ + __get_user(env->gpr[HEX_REG_R00], &sc->r0); + __get_user(env->gpr[HEX_REG_R01], &sc->r1); + __get_user(env->gpr[HEX_REG_R02], &sc->r2); + __get_user(env->gpr[HEX_REG_R03], &sc->r3); + __get_user(env->gpr[HEX_REG_R04], &sc->r4); + __get_user(env->gpr[HEX_REG_R05], &sc->r5); + __get_user(env->gpr[HEX_REG_R06], &sc->r6); + __get_user(env->gpr[HEX_REG_R07], &sc->r7); + __get_user(env->gpr[HEX_REG_R08], &sc->r8); + __get_user(env->gpr[HEX_REG_R09], &sc->r9); + __get_user(env->gpr[HEX_REG_R10], &sc->r10); + __get_user(env->gpr[HEX_REG_R11], &sc->r11); + __get_user(env->gpr[HEX_REG_R12], &sc->r12); + __get_user(env->gpr[HEX_REG_R13], &sc->r13); + __get_user(env->gpr[HEX_REG_R14], &sc->r14); + __get_user(env->gpr[HEX_REG_R15], &sc->r15); + __get_user(env->gpr[HEX_REG_R16], &sc->r16); + __get_user(env->gpr[HEX_REG_R17], &sc->r17); + __get_user(env->gpr[HEX_REG_R18], &sc->r18); + __get_user(env->gpr[HEX_REG_R19], &sc->r19); + __get_user(env->gpr[HEX_REG_R20], &sc->r20); + __get_user(env->gpr[HEX_REG_R21], &sc->r21); + __get_user(env->gpr[HEX_REG_R22], &sc->r22); + __get_user(env->gpr[HEX_REG_R23], &sc->r23); + __get_user(env->gpr[HEX_REG_R24], &sc->r24); + __get_user(env->gpr[HEX_REG_R25], &sc->r25); + __get_user(env->gpr[HEX_REG_R26], &sc->r26); + __get_user(env->gpr[HEX_REG_R27], &sc->r27); + __get_user(env->gpr[HEX_REG_R28], &sc->r28); + __get_user(env->gpr[HEX_REG_R29], &sc->r29); + __get_user(env->gpr[HEX_REG_R30], &sc->r30); + __get_user(env->gpr[HEX_REG_R31], &sc->r31); + __get_user(env->gpr[HEX_REG_SA0], &sc->sa0); + __get_user(env->gpr[HEX_REG_LC0], &sc->lc0); + __get_user(env->gpr[HEX_REG_SA1], &sc->sa1); + __get_user(env->gpr[HEX_REG_LC1], &sc->lc1); + __get_user(env->gpr[HEX_REG_M0], &sc->m0); + __get_user(env->gpr[HEX_REG_M1], &sc->m1); + __get_user(env->gpr[HEX_REG_USR], &sc->usr); + __get_user(env->gpr[HEX_REG_P3_0], &sc->p3_0); + __get_user(env->gpr[HEX_REG_GP], &sc->gp); + __get_user(env->gpr[HEX_REG_UGP], &sc->ugp); + __get_user(env->gpr[HEX_REG_PC], &sc->pc); +} + +static void restore_ucontext(CPUHexagonState *env, struct target_ucontext *uc) +{ + sigset_t blocked; + target_sigset_t target_set; + int i; + + target_sigemptyset(&target_set); + for (i = 0; i < TARGET_NSIG_WORDS; i++) { + __get_user(target_set.sig[i], &(uc->uc_sigmask.sig[i])); + } + + target_to_host_sigset_internal(&blocked, &target_set); + set_sigmask(&blocked); + + restore_sigcontext(env, &uc->uc_mcontext); +} + +long do_rt_sigreturn(CPUHexagonState *env) +{ + struct target_rt_sigframe *frame; + abi_ulong frame_addr; + + frame_addr = env->gpr[HEX_REG_SP]; + trace_user_do_sigreturn(env, frame_addr); + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { + goto badframe; + } + + restore_ucontext(env, &frame->uc); + + if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe, + uc.uc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT) { + goto badframe; + } + + unlock_user_struct(frame, frame_addr, 0); + return -TARGET_QEMU_ESIGRETURN; + +badframe: + unlock_user_struct(frame, frame_addr, 0); + force_sig(TARGET_SIGSEGV); + return 0; +} diff --git a/scripts/gensyscalls.sh b/scripts/gensyscalls.sh index bba9fb052c..8fb450e3c9 100755 --- a/scripts/gensyscalls.sh +++ b/scripts/gensyscalls.sh @@ -98,4 +98,5 @@ generate_syscall_nr openrisc 32 "$output/linux-user/openrisc/syscall_nr.h" generate_syscall_nr riscv 32 "$output/linux-user/riscv/syscall32_nr.h" generate_syscall_nr riscv 64 "$output/linux-user/riscv/syscall64_nr.h" +generate_syscall_nr hexagon 32 "$output/linux-user/hexagon/syscall_nr.h" rm -fr "$TMP" From patchwork Wed Feb 17 23:40:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384198 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3231652jao; Wed, 17 Feb 2021 16:07:22 -0800 (PST) X-Google-Smtp-Source: ABdhPJwIGzorGvGj1x+rPGPTTuRI8Wtu5DOS0WU8m/7PgGLpKl2tun1sNyUvINMvFxvoH4BpwM33 X-Received: by 2002:a5b:38c:: with SMTP id k12mr2876224ybp.441.1613606842155; Wed, 17 Feb 2021 16:07:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606842; cv=none; d=google.com; s=arc-20160816; b=A3yOi6YzGyoIc/2tIpzDRPRqJvpQI2dxahbDAo9ajc+c1ZjvhALVUNH3aRSOQ30XvA DsYqyZLh4+QczkhXKOfMMw0sPgyAhDHOT8vp1/DE815FsrF29tLWmxyfHfp43e2K20BG JpYvu+SfC22I7zimNod7cD8DbNmVvFt6FPqQiuSFj4meT4xHow4scZdlILfvqBrj6cvK wxI54qPISAH68hKWmlXEukzWXQrrnw/no9SSWBgGqHnOBNN4TXS056ZrLRIVsq2C7+rO IbCkZZo2SPpEw/Z1AlYvnkVOXVqcBCGHPouZPW8pupNHER/84yuNUG34gp3c2xjma6iF v4LQ== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=PjIQpV71KcWQpoiMEIllXgOR5oJbj3oKSHBVzRjVzFI=; b=DavP4zMX15He28dKv4EB1GbAeSFaBRM387QzvyKrhAqAHpWdBlkkYRyYRzLHjwxO2f A8j80HSmwkZG842glNpT9FX8SNRDlsNWUooyojUK6IfNuhpUjv7Rfac41CUFp/gM91Ki gxZMPxPcMwCUzpmJuSh1gpp+1EVB8b5Nv2HEq7CLWaRbeegQDuEOFKk/CcJ5xcMJ2Kyj qA9SbHtSDcI1Vq45d/q12jRLdfhG7HeOE2g5Fer+TM4Ek2wtQeER4XiX5HsvpsryKnWx H0I+sx5rCXkUv2Lhg3yKtjUmP9rfSpBto6g2W8wpEc7IdGzDeydZ9HNJnJIbMcPq/Q8b K0Kw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=nF++OB6S; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id t123si3597257ybf.107.2021.02.17.16.07.21 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 16:07:22 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=nF++OB6S; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:55350 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWqn-0007UX-GT for patch@linaro.org; Wed, 17 Feb 2021 19:07:21 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51190) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWSD-0001Ca-3h for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:57 -0500 Received: from mail-pf1-x42f.google.com ([2607:f8b0:4864:20::42f]:38939) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWS1-0004uo-E9 for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:55 -0500 Received: by mail-pf1-x42f.google.com with SMTP id 189so33517pfy.6 for ; Wed, 17 Feb 2021 15:41:42 -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 :mime-version:content-transfer-encoding; bh=PjIQpV71KcWQpoiMEIllXgOR5oJbj3oKSHBVzRjVzFI=; b=nF++OB6Sj/b6DxoPysC/x8fspa6TkZ5DCHrx7qcDru7RTlLSYeJMSKNpHVci1hvtsO VmVA/fPDvtZHX4/vsrx8Q92/cvunrJfWkeggDrRPDkVBcka4yhFe6UApkvj6g0M0hxOQ ap733FWxtzZWGJRtCy35Eu3CgDKCHoJ2GSHdpn25qqKHSikthSymgMKzSdJ+71czEwbX 5Kc+NAIgX0AbedwzZrXvcRFosKJCmuyZI9lQoQl0hhNYPfk5FadVGfQMtIVOobsJPwtJ qZRu2yVWh3MVrThPHNIO5+z9ob/UQ+1UWxkeagwp/JrvExA00RUvMeYsp+AAww8PSGnF C9mA== 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:mime-version:content-transfer-encoding; bh=PjIQpV71KcWQpoiMEIllXgOR5oJbj3oKSHBVzRjVzFI=; b=RB20IIo+2bjGiDLbwjug+3Qw52rkavvHcaSfCdYPYb0YgE2/opEs8CRipIc60qLpUL gbh80yNRd6VSr9orZMJC/7+nEP997+2+vUj9Fv6g3R/iRyFHpvUXHzO9RHYY62lfFZhC gX5bSUqMYYSPB6WWjVeaAnV6QCyKz7CH8HHp4c15ncwoWtB4ApAp7mnbJq+/y5VCEQkv MgakYYyHfnCk2tHKm9v+7IFkW3i8IeHDmcQKBnZq68s36DXotWCqUm7uayntxWxjo9AP Jw9NSob9Ej7066MmyZ3nt3CAyerHpBYRMKYnC5ck6Q8QQmDxmDNBKZyFVO1krBuzwipy /G1g== X-Gm-Message-State: AOAM531iCzBdPsrobrQVHOoOJtTjEqDvU57KMTXyZLkkZMKlX2Vr4V4P 9IQbz7xXE2hS2KHID8wgK04XL8VFdgJkzA== X-Received: by 2002:a63:4922:: with SMTP id w34mr1540774pga.423.1613605300423; Wed, 17 Feb 2021 15:41:40 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:39 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 32/35] Hexagon (tests/tcg/hexagon) TCG tests - multiarch Date: Wed, 17 Feb 2021 15:40:20 -0800 Message-Id: <20210217234023.1742406-33-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42f; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Enable multiarch tests for Hexagon Modify tests/tcg/configure.sh Add reference files to tests/tcg/hexagon Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1612763186-18161-32-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- tests/tcg/configure.sh | 4 +- tests/tcg/hexagon/Makefile.target | 30 ++ tests/tcg/hexagon/float_convs.ref | 748 +++++++++++++++++++++++++++++ tests/tcg/hexagon/float_madds.ref | 768 ++++++++++++++++++++++++++++++ 4 files changed, 1549 insertions(+), 1 deletion(-) create mode 100644 tests/tcg/hexagon/Makefile.target create mode 100644 tests/tcg/hexagon/float_convs.ref create mode 100644 tests/tcg/hexagon/float_madds.ref -- 2.25.1 diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh index ba8ac9a93e..551c02f469 100755 --- a/tests/tcg/configure.sh +++ b/tests/tcg/configure.sh @@ -49,6 +49,8 @@ fi : $(cross_cc_alpha="alpha-linux-gnu-gcc") : ${cross_cc_arm="arm-linux-gnueabihf-gcc"} : ${cross_cc_cflags_armeb="-mbig-endian"} +: ${cross_cc_hexagon="hexagon-unknown-linux-musl-clang"} +: ${cross_cc_cflags_hexagon="-mv67 -O2 -static"} : ${cross_cc_hppa="hppa-linux-gnu-gcc"} : ${cross_cc_i386="i386-pc-linux-gnu-gcc"} : ${cross_cc_cflags_i386="-m32"} @@ -94,7 +96,7 @@ for target in $target_list; do xtensa|xtensaeb) arches=xtensa ;; - alpha|cris|hppa|i386|lm32|microblaze|microblazeel|m68k|openrisc|riscv64|s390x|sh4|sparc64) + alpha|cris|hexagon|hppa|i386|lm32|microblaze|microblazeel|m68k|openrisc|riscv64|s390x|sh4|sparc64) arches=$target ;; *) diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target new file mode 100644 index 0000000000..10b7c84813 --- /dev/null +++ b/tests/tcg/hexagon/Makefile.target @@ -0,0 +1,30 @@ +## +## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +# Hexagon doesn't support gdb, so skip the EXTRA_RUNS +EXTRA_RUNS = + +# Hexagon has 64K pages, so increase the timeout to keep +# test-mmap from timing out +ifeq ($(CONFIG_DEBUG_TCG),y) +TIMEOUT=800 +else +TIMEOUT=500 +endif + + +CFLAGS += -Wno-incompatible-pointer-types -Wno-undefined-internal diff --git a/tests/tcg/hexagon/float_convs.ref b/tests/tcg/hexagon/float_convs.ref new file mode 100644 index 0000000000..9ec9ffc08d --- /dev/null +++ b/tests/tcg/hexagon/float_convs.ref @@ -0,0 +1,748 @@ +### Rounding to nearest +from single: f32(-nan:0xffa00000) + to double: f64(-nan:0x00ffffffffffffffff) (INVALID) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0xffc00000) + to double: f64(-nan:0x00ffffffffffffffff) (OK) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-inf:0xff800000) + to double: f64(-inf:0x00fff0000000000000) (OK) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + to double: f64(-0x1.fffffe00000000000000p+127:0x00c7efffffe0000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + to double: f64(-0x1.1874b200000000000000p+103:0x00c661874b20000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + to double: f64(-0x1.c0bab600000000000000p+99:0x00c62c0bab60000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.31f75000000000000000p-40:0xab98fba8) + to double: f64(-0x1.31f75000000000000000p-40:0x00bd731f7500000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.50544400000000000000p-66:0x9ea82a22) + to double: f64(-0x1.50544400000000000000p-66:0x00bbd5054440000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.00000000000000000000p-126:0x80800000) + to double: f64(-0x1.00000000000000000000p-126:0x00b810000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(0x0.00000000000000000000p+0:0000000000) + to double: f64(0x0.00000000000000000000p+0:00000000000000000000) (OK) + to int32: 0 (OK) + to int64: 0 (OK) + to uint32: 0 (OK) + to uint64: 0 (OK) +from single: f32(0x1.00000000000000000000p-126:0x00800000) + to double: f64(0x1.00000000000000000000p-126:0x003810000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000000000000000000p-25:0x33000000) + to double: f64(0x1.00000000000000000000p-25:0x003e60000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.ffffe600000000000000p-25:0x337ffff3) + to double: f64(0x1.ffffe600000000000000p-25:0x003e6ffffe60000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.ff801a00000000000000p-15:0x387fc00d) + to double: f64(0x1.ff801a00000000000000p-15:0x003f0ff801a0000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000c00000000000000p-14:0x38800006) + to double: f64(0x1.00000c00000000000000p-14:0x003f100000c0000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000000000000000000p+0:0x3f800000) + to double: f64(0x1.00000000000000000000p+0:0x003ff0000000000000) (OK) + to int32: 1 (OK) + to int64: 1 (OK) + to uint32: 1 (OK) + to uint64: 1 (OK) +from single: f32(0x1.00400000000000000000p+0:0x3f802000) + to double: f64(0x1.00400000000000000000p+0:0x003ff0040000000000) (INEXACT ) + to int32: 1 (INEXACT ) + to int64: 1 (INEXACT ) + to uint32: 1 (INEXACT ) + to uint64: 1 (INEXACT ) +from single: f32(0x1.00000000000000000000p+1:0x40000000) + to double: f64(0x1.00000000000000000000p+1:0x004000000000000000) (OK) + to int32: 2 (OK) + to int64: 2 (OK) + to uint32: 2 (OK) + to uint64: 2 (OK) +from single: f32(0x1.5bf0a800000000000000p+1:0x402df854) + to double: f64(0x1.5bf0a800000000000000p+1:0x004005bf0a80000000) (INEXACT ) + to int32: 2 (INEXACT ) + to int64: 2 (INEXACT ) + to uint32: 2 (INEXACT ) + to uint64: 2 (INEXACT ) +from single: f32(0x1.921fb600000000000000p+1:0x40490fdb) + to double: f64(0x1.921fb600000000000000p+1:0x00400921fb60000000) (INEXACT ) + to int32: 3 (INEXACT ) + to int64: 3 (INEXACT ) + to uint32: 3 (INEXACT ) + to uint64: 3 (INEXACT ) +from single: f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + to double: f64(0x1.ffbe0000000000000000p+15:0x0040effbe000000000) (INEXACT ) + to int32: 65503 (OK) + to int64: 65503 (OK) + to uint32: 65503 (OK) + to uint64: 65503 (OK) +from single: f32(0x1.ffc00000000000000000p+15:0x477fe000) + to double: f64(0x1.ffc00000000000000000p+15:0x0040effc0000000000) (INEXACT ) + to int32: 65504 (OK) + to int64: 65504 (OK) + to uint32: 65504 (OK) + to uint64: 65504 (OK) +from single: f32(0x1.ffc20000000000000000p+15:0x477fe100) + to double: f64(0x1.ffc20000000000000000p+15:0x0040effc2000000000) (INEXACT ) + to int32: 65505 (OK) + to int64: 65505 (OK) + to uint32: 65505 (OK) + to uint64: 65505 (OK) +from single: f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + to double: f64(0x1.ffbf0000000000000000p+16:0x0040fffbf000000000) (INEXACT ) + to int32: 131007 (OK) + to int64: 131007 (OK) + to uint32: 131007 (OK) + to uint64: 131007 (OK) +from single: f32(0x1.ffc00000000000000000p+16:0x47ffe000) + to double: f64(0x1.ffc00000000000000000p+16:0x0040fffc0000000000) (INEXACT ) + to int32: 131008 (OK) + to int64: 131008 (OK) + to uint32: 131008 (OK) + to uint64: 131008 (OK) +from single: f32(0x1.ffc10000000000000000p+16:0x47ffe080) + to double: f64(0x1.ffc10000000000000000p+16:0x0040fffc1000000000) (INEXACT ) + to int32: 131009 (OK) + to int64: 131009 (OK) + to uint32: 131009 (OK) + to uint64: 131009 (OK) +from single: f32(0x1.c0bab600000000000000p+99:0x71605d5b) + to double: f64(0x1.c0bab600000000000000p+99:0x00462c0bab60000000) (INEXACT ) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + to double: f64(0x1.fffffe00000000000000p+127:0x0047efffffe0000000) (INEXACT ) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(inf:0x7f800000) + to double: f64(inf:0x007ff0000000000000) (OK) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0x7fc00000) + to double: f64(-nan:0x00ffffffffffffffff) (OK) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0x7fa00000) + to double: f64(-nan:0x00ffffffffffffffff) (INVALID) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +### Rounding upwards +from single: f32(-nan:0xffa00000) + to double: f64(-nan:0x00ffffffffffffffff) (INVALID) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0xffc00000) + to double: f64(-nan:0x00ffffffffffffffff) (OK) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-inf:0xff800000) + to double: f64(-inf:0x00fff0000000000000) (OK) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + to double: f64(-0x1.fffffe00000000000000p+127:0x00c7efffffe0000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + to double: f64(-0x1.1874b200000000000000p+103:0x00c661874b20000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + to double: f64(-0x1.c0bab600000000000000p+99:0x00c62c0bab60000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.31f75000000000000000p-40:0xab98fba8) + to double: f64(-0x1.31f75000000000000000p-40:0x00bd731f7500000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.50544400000000000000p-66:0x9ea82a22) + to double: f64(-0x1.50544400000000000000p-66:0x00bbd5054440000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.00000000000000000000p-126:0x80800000) + to double: f64(-0x1.00000000000000000000p-126:0x00b810000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(0x0.00000000000000000000p+0:0000000000) + to double: f64(0x0.00000000000000000000p+0:00000000000000000000) (OK) + to int32: 0 (OK) + to int64: 0 (OK) + to uint32: 0 (OK) + to uint64: 0 (OK) +from single: f32(0x1.00000000000000000000p-126:0x00800000) + to double: f64(0x1.00000000000000000000p-126:0x003810000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000000000000000000p-25:0x33000000) + to double: f64(0x1.00000000000000000000p-25:0x003e60000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.ffffe600000000000000p-25:0x337ffff3) + to double: f64(0x1.ffffe600000000000000p-25:0x003e6ffffe60000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.ff801a00000000000000p-15:0x387fc00d) + to double: f64(0x1.ff801a00000000000000p-15:0x003f0ff801a0000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000c00000000000000p-14:0x38800006) + to double: f64(0x1.00000c00000000000000p-14:0x003f100000c0000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000000000000000000p+0:0x3f800000) + to double: f64(0x1.00000000000000000000p+0:0x003ff0000000000000) (OK) + to int32: 1 (OK) + to int64: 1 (OK) + to uint32: 1 (OK) + to uint64: 1 (OK) +from single: f32(0x1.00400000000000000000p+0:0x3f802000) + to double: f64(0x1.00400000000000000000p+0:0x003ff0040000000000) (INEXACT ) + to int32: 1 (INEXACT ) + to int64: 1 (INEXACT ) + to uint32: 1 (INEXACT ) + to uint64: 1 (INEXACT ) +from single: f32(0x1.00000000000000000000p+1:0x40000000) + to double: f64(0x1.00000000000000000000p+1:0x004000000000000000) (OK) + to int32: 2 (OK) + to int64: 2 (OK) + to uint32: 2 (OK) + to uint64: 2 (OK) +from single: f32(0x1.5bf0a800000000000000p+1:0x402df854) + to double: f64(0x1.5bf0a800000000000000p+1:0x004005bf0a80000000) (INEXACT ) + to int32: 2 (INEXACT ) + to int64: 2 (INEXACT ) + to uint32: 2 (INEXACT ) + to uint64: 2 (INEXACT ) +from single: f32(0x1.921fb600000000000000p+1:0x40490fdb) + to double: f64(0x1.921fb600000000000000p+1:0x00400921fb60000000) (INEXACT ) + to int32: 3 (INEXACT ) + to int64: 3 (INEXACT ) + to uint32: 3 (INEXACT ) + to uint64: 3 (INEXACT ) +from single: f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + to double: f64(0x1.ffbe0000000000000000p+15:0x0040effbe000000000) (INEXACT ) + to int32: 65503 (OK) + to int64: 65503 (OK) + to uint32: 65503 (OK) + to uint64: 65503 (OK) +from single: f32(0x1.ffc00000000000000000p+15:0x477fe000) + to double: f64(0x1.ffc00000000000000000p+15:0x0040effc0000000000) (INEXACT ) + to int32: 65504 (OK) + to int64: 65504 (OK) + to uint32: 65504 (OK) + to uint64: 65504 (OK) +from single: f32(0x1.ffc20000000000000000p+15:0x477fe100) + to double: f64(0x1.ffc20000000000000000p+15:0x0040effc2000000000) (INEXACT ) + to int32: 65505 (OK) + to int64: 65505 (OK) + to uint32: 65505 (OK) + to uint64: 65505 (OK) +from single: f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + to double: f64(0x1.ffbf0000000000000000p+16:0x0040fffbf000000000) (INEXACT ) + to int32: 131007 (OK) + to int64: 131007 (OK) + to uint32: 131007 (OK) + to uint64: 131007 (OK) +from single: f32(0x1.ffc00000000000000000p+16:0x47ffe000) + to double: f64(0x1.ffc00000000000000000p+16:0x0040fffc0000000000) (INEXACT ) + to int32: 131008 (OK) + to int64: 131008 (OK) + to uint32: 131008 (OK) + to uint64: 131008 (OK) +from single: f32(0x1.ffc10000000000000000p+16:0x47ffe080) + to double: f64(0x1.ffc10000000000000000p+16:0x0040fffc1000000000) (INEXACT ) + to int32: 131009 (OK) + to int64: 131009 (OK) + to uint32: 131009 (OK) + to uint64: 131009 (OK) +from single: f32(0x1.c0bab600000000000000p+99:0x71605d5b) + to double: f64(0x1.c0bab600000000000000p+99:0x00462c0bab60000000) (INEXACT ) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + to double: f64(0x1.fffffe00000000000000p+127:0x0047efffffe0000000) (INEXACT ) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(inf:0x7f800000) + to double: f64(inf:0x007ff0000000000000) (OK) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0x7fc00000) + to double: f64(-nan:0x00ffffffffffffffff) (OK) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0x7fa00000) + to double: f64(-nan:0x00ffffffffffffffff) (INVALID) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +### Rounding downwards +from single: f32(-nan:0xffa00000) + to double: f64(-nan:0x00ffffffffffffffff) (INVALID) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0xffc00000) + to double: f64(-nan:0x00ffffffffffffffff) (OK) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-inf:0xff800000) + to double: f64(-inf:0x00fff0000000000000) (OK) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + to double: f64(-0x1.fffffe00000000000000p+127:0x00c7efffffe0000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + to double: f64(-0x1.1874b200000000000000p+103:0x00c661874b20000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + to double: f64(-0x1.c0bab600000000000000p+99:0x00c62c0bab60000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.31f75000000000000000p-40:0xab98fba8) + to double: f64(-0x1.31f75000000000000000p-40:0x00bd731f7500000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.50544400000000000000p-66:0x9ea82a22) + to double: f64(-0x1.50544400000000000000p-66:0x00bbd5054440000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.00000000000000000000p-126:0x80800000) + to double: f64(-0x1.00000000000000000000p-126:0x00b810000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(0x0.00000000000000000000p+0:0000000000) + to double: f64(0x0.00000000000000000000p+0:00000000000000000000) (OK) + to int32: 0 (OK) + to int64: 0 (OK) + to uint32: 0 (OK) + to uint64: 0 (OK) +from single: f32(0x1.00000000000000000000p-126:0x00800000) + to double: f64(0x1.00000000000000000000p-126:0x003810000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000000000000000000p-25:0x33000000) + to double: f64(0x1.00000000000000000000p-25:0x003e60000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.ffffe600000000000000p-25:0x337ffff3) + to double: f64(0x1.ffffe600000000000000p-25:0x003e6ffffe60000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.ff801a00000000000000p-15:0x387fc00d) + to double: f64(0x1.ff801a00000000000000p-15:0x003f0ff801a0000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000c00000000000000p-14:0x38800006) + to double: f64(0x1.00000c00000000000000p-14:0x003f100000c0000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000000000000000000p+0:0x3f800000) + to double: f64(0x1.00000000000000000000p+0:0x003ff0000000000000) (OK) + to int32: 1 (OK) + to int64: 1 (OK) + to uint32: 1 (OK) + to uint64: 1 (OK) +from single: f32(0x1.00400000000000000000p+0:0x3f802000) + to double: f64(0x1.00400000000000000000p+0:0x003ff0040000000000) (INEXACT ) + to int32: 1 (INEXACT ) + to int64: 1 (INEXACT ) + to uint32: 1 (INEXACT ) + to uint64: 1 (INEXACT ) +from single: f32(0x1.00000000000000000000p+1:0x40000000) + to double: f64(0x1.00000000000000000000p+1:0x004000000000000000) (OK) + to int32: 2 (OK) + to int64: 2 (OK) + to uint32: 2 (OK) + to uint64: 2 (OK) +from single: f32(0x1.5bf0a800000000000000p+1:0x402df854) + to double: f64(0x1.5bf0a800000000000000p+1:0x004005bf0a80000000) (INEXACT ) + to int32: 2 (INEXACT ) + to int64: 2 (INEXACT ) + to uint32: 2 (INEXACT ) + to uint64: 2 (INEXACT ) +from single: f32(0x1.921fb600000000000000p+1:0x40490fdb) + to double: f64(0x1.921fb600000000000000p+1:0x00400921fb60000000) (INEXACT ) + to int32: 3 (INEXACT ) + to int64: 3 (INEXACT ) + to uint32: 3 (INEXACT ) + to uint64: 3 (INEXACT ) +from single: f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + to double: f64(0x1.ffbe0000000000000000p+15:0x0040effbe000000000) (INEXACT ) + to int32: 65503 (OK) + to int64: 65503 (OK) + to uint32: 65503 (OK) + to uint64: 65503 (OK) +from single: f32(0x1.ffc00000000000000000p+15:0x477fe000) + to double: f64(0x1.ffc00000000000000000p+15:0x0040effc0000000000) (INEXACT ) + to int32: 65504 (OK) + to int64: 65504 (OK) + to uint32: 65504 (OK) + to uint64: 65504 (OK) +from single: f32(0x1.ffc20000000000000000p+15:0x477fe100) + to double: f64(0x1.ffc20000000000000000p+15:0x0040effc2000000000) (INEXACT ) + to int32: 65505 (OK) + to int64: 65505 (OK) + to uint32: 65505 (OK) + to uint64: 65505 (OK) +from single: f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + to double: f64(0x1.ffbf0000000000000000p+16:0x0040fffbf000000000) (INEXACT ) + to int32: 131007 (OK) + to int64: 131007 (OK) + to uint32: 131007 (OK) + to uint64: 131007 (OK) +from single: f32(0x1.ffc00000000000000000p+16:0x47ffe000) + to double: f64(0x1.ffc00000000000000000p+16:0x0040fffc0000000000) (INEXACT ) + to int32: 131008 (OK) + to int64: 131008 (OK) + to uint32: 131008 (OK) + to uint64: 131008 (OK) +from single: f32(0x1.ffc10000000000000000p+16:0x47ffe080) + to double: f64(0x1.ffc10000000000000000p+16:0x0040fffc1000000000) (INEXACT ) + to int32: 131009 (OK) + to int64: 131009 (OK) + to uint32: 131009 (OK) + to uint64: 131009 (OK) +from single: f32(0x1.c0bab600000000000000p+99:0x71605d5b) + to double: f64(0x1.c0bab600000000000000p+99:0x00462c0bab60000000) (INEXACT ) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + to double: f64(0x1.fffffe00000000000000p+127:0x0047efffffe0000000) (INEXACT ) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(inf:0x7f800000) + to double: f64(inf:0x007ff0000000000000) (OK) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0x7fc00000) + to double: f64(-nan:0x00ffffffffffffffff) (OK) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0x7fa00000) + to double: f64(-nan:0x00ffffffffffffffff) (INVALID) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +### Rounding to zero +from single: f32(-nan:0xffa00000) + to double: f64(-nan:0x00ffffffffffffffff) (INVALID) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0xffc00000) + to double: f64(-nan:0x00ffffffffffffffff) (OK) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-inf:0xff800000) + to double: f64(-inf:0x00fff0000000000000) (OK) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + to double: f64(-0x1.fffffe00000000000000p+127:0x00c7efffffe0000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + to double: f64(-0x1.1874b200000000000000p+103:0x00c661874b20000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + to double: f64(-0x1.c0bab600000000000000p+99:0x00c62c0bab60000000) (INEXACT ) + to int32: -2147483648 (INVALID) + to int64: -9223372036854775808 (INVALID) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.31f75000000000000000p-40:0xab98fba8) + to double: f64(-0x1.31f75000000000000000p-40:0x00bd731f7500000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.50544400000000000000p-66:0x9ea82a22) + to double: f64(-0x1.50544400000000000000p-66:0x00bbd5054440000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(-0x1.00000000000000000000p-126:0x80800000) + to double: f64(-0x1.00000000000000000000p-126:0x00b810000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INVALID) + to uint64: 0 (INVALID) +from single: f32(0x0.00000000000000000000p+0:0000000000) + to double: f64(0x0.00000000000000000000p+0:00000000000000000000) (OK) + to int32: 0 (OK) + to int64: 0 (OK) + to uint32: 0 (OK) + to uint64: 0 (OK) +from single: f32(0x1.00000000000000000000p-126:0x00800000) + to double: f64(0x1.00000000000000000000p-126:0x003810000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000000000000000000p-25:0x33000000) + to double: f64(0x1.00000000000000000000p-25:0x003e60000000000000) (OK) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.ffffe600000000000000p-25:0x337ffff3) + to double: f64(0x1.ffffe600000000000000p-25:0x003e6ffffe60000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.ff801a00000000000000p-15:0x387fc00d) + to double: f64(0x1.ff801a00000000000000p-15:0x003f0ff801a0000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000c00000000000000p-14:0x38800006) + to double: f64(0x1.00000c00000000000000p-14:0x003f100000c0000000) (INEXACT ) + to int32: 0 (INEXACT ) + to int64: 0 (INEXACT ) + to uint32: 0 (INEXACT ) + to uint64: 0 (INEXACT ) +from single: f32(0x1.00000000000000000000p+0:0x3f800000) + to double: f64(0x1.00000000000000000000p+0:0x003ff0000000000000) (OK) + to int32: 1 (OK) + to int64: 1 (OK) + to uint32: 1 (OK) + to uint64: 1 (OK) +from single: f32(0x1.00400000000000000000p+0:0x3f802000) + to double: f64(0x1.00400000000000000000p+0:0x003ff0040000000000) (INEXACT ) + to int32: 1 (INEXACT ) + to int64: 1 (INEXACT ) + to uint32: 1 (INEXACT ) + to uint64: 1 (INEXACT ) +from single: f32(0x1.00000000000000000000p+1:0x40000000) + to double: f64(0x1.00000000000000000000p+1:0x004000000000000000) (OK) + to int32: 2 (OK) + to int64: 2 (OK) + to uint32: 2 (OK) + to uint64: 2 (OK) +from single: f32(0x1.5bf0a800000000000000p+1:0x402df854) + to double: f64(0x1.5bf0a800000000000000p+1:0x004005bf0a80000000) (INEXACT ) + to int32: 2 (INEXACT ) + to int64: 2 (INEXACT ) + to uint32: 2 (INEXACT ) + to uint64: 2 (INEXACT ) +from single: f32(0x1.921fb600000000000000p+1:0x40490fdb) + to double: f64(0x1.921fb600000000000000p+1:0x00400921fb60000000) (INEXACT ) + to int32: 3 (INEXACT ) + to int64: 3 (INEXACT ) + to uint32: 3 (INEXACT ) + to uint64: 3 (INEXACT ) +from single: f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + to double: f64(0x1.ffbe0000000000000000p+15:0x0040effbe000000000) (INEXACT ) + to int32: 65503 (OK) + to int64: 65503 (OK) + to uint32: 65503 (OK) + to uint64: 65503 (OK) +from single: f32(0x1.ffc00000000000000000p+15:0x477fe000) + to double: f64(0x1.ffc00000000000000000p+15:0x0040effc0000000000) (INEXACT ) + to int32: 65504 (OK) + to int64: 65504 (OK) + to uint32: 65504 (OK) + to uint64: 65504 (OK) +from single: f32(0x1.ffc20000000000000000p+15:0x477fe100) + to double: f64(0x1.ffc20000000000000000p+15:0x0040effc2000000000) (INEXACT ) + to int32: 65505 (OK) + to int64: 65505 (OK) + to uint32: 65505 (OK) + to uint64: 65505 (OK) +from single: f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + to double: f64(0x1.ffbf0000000000000000p+16:0x0040fffbf000000000) (INEXACT ) + to int32: 131007 (OK) + to int64: 131007 (OK) + to uint32: 131007 (OK) + to uint64: 131007 (OK) +from single: f32(0x1.ffc00000000000000000p+16:0x47ffe000) + to double: f64(0x1.ffc00000000000000000p+16:0x0040fffc0000000000) (INEXACT ) + to int32: 131008 (OK) + to int64: 131008 (OK) + to uint32: 131008 (OK) + to uint64: 131008 (OK) +from single: f32(0x1.ffc10000000000000000p+16:0x47ffe080) + to double: f64(0x1.ffc10000000000000000p+16:0x0040fffc1000000000) (INEXACT ) + to int32: 131009 (OK) + to int64: 131009 (OK) + to uint32: 131009 (OK) + to uint64: 131009 (OK) +from single: f32(0x1.c0bab600000000000000p+99:0x71605d5b) + to double: f64(0x1.c0bab600000000000000p+99:0x00462c0bab60000000) (INEXACT ) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + to double: f64(0x1.fffffe00000000000000p+127:0x0047efffffe0000000) (INEXACT ) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(inf:0x7f800000) + to double: f64(inf:0x007ff0000000000000) (OK) + to int32: 2147483647 (INVALID) + to int64: 9223372036854775807 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0x7fc00000) + to double: f64(-nan:0x00ffffffffffffffff) (OK) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) +from single: f32(-nan:0x7fa00000) + to double: f64(-nan:0x00ffffffffffffffff) (INVALID) + to int32: -1 (INVALID) + to int64: -1 (INVALID) + to uint32: -1 (INVALID) + to uint64: -1 (INVALID) diff --git a/tests/tcg/hexagon/float_madds.ref b/tests/tcg/hexagon/float_madds.ref new file mode 100644 index 0000000000..ceed3bbbfb --- /dev/null +++ b/tests/tcg/hexagon/float_madds.ref @@ -0,0 +1,768 @@ +### Rounding to nearest +op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-inf:0xff800000) +res: f32(-nan:0xffffffff) flags=INVALID (0/0) +op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (0/1) +op : f32(-inf:0xff800000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=INVALID (0/2) +op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(-nan:0xffffffff) flags=OK (1/0) +op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=OK (1/1) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-nan:0xffc00000) + f32(-inf:0xff800000) +res: f32(-nan:0xffffffff) flags=OK (1/2) +op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(inf:0x7f800000) flags=OK (2/0) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-inf:0xff800000) +res: f32(-inf:0xff800000) flags=OK (2/1) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(inf:0x7f800000) flags=OK (2/2) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (3/0) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (3/1) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (3/2) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (4/0) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(-0x1.1874b200000000000000p+103:0xf30c3a59) flags=INEXACT (4/1) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) flags=INEXACT (4/2) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(0x1.0c27fa00000000000000p+60:0x5d8613fd) flags=INEXACT (5/0) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) flags=INEXACT (5/1) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(0x1.26c46200000000000000p+34:0x50936231) flags=INEXACT (5/2) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(0x1.91f94000000000000000p-106:0x0ac8fca0) flags=INEXACT (6/0) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(-0x1.31f75000000000000000p-40:0xab98fba8) flags=INEXACT (6/1) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=INEXACT (6/2) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT (7/0) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=INEXACT (7/1) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (7/2) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (8/0) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (8/1) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(-0x0.00000000000000000000p+0:0x80000000) flags=UNDERFLOW INEXACT (8/2) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.00000000000000000000p-25:0x33000000) flags=OK (9/0) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT (9/1) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (9/2) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.ffffe600000000000000p-25:0x337ffff3) flags=INEXACT (10/0) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.ffffe600000000000000p-50:0x26fffff3) flags=INEXACT (10/1) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.00000000000000000000p-25:0x33000000) flags=INEXACT (10/2) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ff801a00000000000000p-15:0x387fc00d) flags=INEXACT (11/0) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.0007fe00000000000000p-25:0x330003ff) flags=INEXACT (11/1) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.0001f200000000000000p-24:0x338000f9) flags=INEXACT (11/2) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.00000c00000000000000p-14:0x38800006) flags=INEXACT (12/0) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.0ffbf400000000000000p-24:0x3387fdfa) flags=INEXACT (12/1) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ff801c00000000000000p-15:0x387fc00e) flags=INEXACT (12/2) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.00000000000000000000p+0:0x3f800000) flags=INEXACT (13/0) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT (13/1) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT (13/2) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT (14/0) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT (14/1) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.00040200000000000000p+0:0x3f800201) flags=INEXACT (14/2) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.80200000000000000000p+1:0x40401000) flags=INEXACT (15/0) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.80400000000000000000p+1:0x40402000) flags=INEXACT (15/1) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.80200000000000000000p+1:0x40401000) flags=INEXACT (15/2) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.2e185400000000000000p+2:0x40970c2a) flags=INEXACT (16/0) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.9c00a800000000000000p+2:0x40ce0054) flags=INEXACT (16/1) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.2e23d200000000000000p+2:0x409711e9) flags=INEXACT (16/2) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.12804200000000000000p+3:0x41094021) flags=INEXACT (17/0) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.51458000000000000000p+3:0x4128a2c0) flags=INEXACT (17/1) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.200c0400000000000000p+3:0x41100602) flags=INEXACT (17/2) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.ffcf1400000000000000p+15:0x477fe78a) flags=INEXACT (18/0) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.91ed3c00000000000000p+17:0x4848f69e) flags=INEXACT (18/1) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.5bc56000000000000000p+17:0x482de2b0) flags=INEXACT (18/2) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.08edf000000000000000p+18:0x488476f8) flags=INEXACT (19/0) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.ff7e0800000000000000p+31:0x4f7fbf04) flags=INEXACT (19/1) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.08ee7a00000000000000p+18:0x4884773d) flags=INEXACT (19/2) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff800800000000000000p+31:0x4f7fc004) flags=INEXACT (20/0) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.ff840800000000000000p+31:0x4f7fc204) flags=INEXACT (20/1) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.ff820800000000000000p+31:0x4f7fc104) flags=INEXACT (20/2) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff860800000000000000p+31:0x4f7fc304) flags=INEXACT (21/0) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.ff820800000000000000p+32:0x4fffc104) flags=INEXACT (21/1) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff800800000000000000p+32:0x4fffc004) flags=INEXACT (21/2) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.ff830800000000000000p+32:0x4fffc184) flags=INEXACT (22/0) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff7f8800000000000000p+33:0x507fbfc4) flags=INEXACT (22/1) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff840800000000000000p+32:0x4fffc204) flags=INEXACT (22/2) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(0x1.ff800800000000000000p+33:0x507fc004) flags=INEXACT (23/0) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff820800000000000000p+33:0x507fc104) flags=INEXACT (23/1) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.ff810800000000000000p+33:0x507fc084) flags=INEXACT (23/2) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(0x1.c0bab600000000000000p+99:0x71605d5b) flags=INEXACT (24/0) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.c0838000000000000000p+116:0x79e041c0) flags=INEXACT (24/1) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(0x1.c0829e00000000000000p+116:0x79e0414f) flags=INEXACT (24/2) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (25/0) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (25/1) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (25/2) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000) +res: f32(inf:0x7f800000) flags=OK (26/0) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(inf:0x7f800000) flags=OK (26/1) +op : f32(inf:0x7f800000) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(inf:0x7f800000) flags=OK (26/2) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=OK (27/0) +op : f32(inf:0x7f800000) * f32(-nan:0x7fc00000) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(-nan:0xffffffff) flags=OK (27/1) +op : f32(-nan:0x7fc00000) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000) +res: f32(-nan:0xffffffff) flags=OK (27/2) +op : f32(inf:0x7f800000) * f32(-nan:0x7fc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (28/0) +op : f32(-nan:0x7fc00000) * f32(-nan:0x7fa00000) + f32(inf:0x7f800000) +res: f32(-nan:0xffffffff) flags=INVALID (28/1) +op : f32(-nan:0x7fa00000) * f32(inf:0x7f800000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=INVALID (28/2) +op : f32(-nan:0x7fc00000) * f32(-nan:0x7fa00000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/0) +op : f32(-nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/1) +op : f32(-nan:0xffa00000) * f32(-nan:0x7fc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/2) +op : f32(-nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/0) +op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/1) +op : f32(-nan:0xffc00000) * f32(-nan:0x7fa00000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/2) +# LP184149 +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-1:0x3f000000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x0.00000000000000000000p+0:0000000000) flags=OK (31/0) +op : f32(0x1.00000000000000000000p-149:0x00000001) * f32(0x1.00000000000000000000p-149:0x00000001) + f32(0x1.00000000000000000000p-149:0x00000001) +res: f32(0x1.00000000000000000000p-149:0x00000001) flags=UNDERFLOW INEXACT (32/0) +### Rounding upwards +op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-inf:0xff800000) +res: f32(-nan:0xffffffff) flags=INVALID (0/0) +op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (0/1) +op : f32(-inf:0xff800000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=INVALID (0/2) +op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(-nan:0xffffffff) flags=OK (1/0) +op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=OK (1/1) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-nan:0xffc00000) + f32(-inf:0xff800000) +res: f32(-nan:0xffffffff) flags=OK (1/2) +op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(inf:0x7f800000) flags=OK (2/0) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-inf:0xff800000) +res: f32(-inf:0xff800000) flags=OK (2/1) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(inf:0x7f800000) flags=OK (2/2) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (3/0) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (3/1) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (3/2) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (4/0) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(-0x1.1874b000000000000000p+103:0xf30c3a58) flags=INEXACT (4/1) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(-0x1.c0bab400000000000000p+99:0xf1605d5a) flags=INEXACT (4/2) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(0x1.0c27fa00000000000000p+60:0x5d8613fd) flags=INEXACT (5/0) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(-0x1.c0bab400000000000000p+99:0xf1605d5a) flags=INEXACT (5/1) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(0x1.26c46200000000000000p+34:0x50936231) flags=INEXACT (5/2) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(0x1.91f94000000000000000p-106:0x0ac8fca0) flags=INEXACT (6/0) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(-0x1.31f74e00000000000000p-40:0xab98fba7) flags=INEXACT (6/1) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(-0x1.50544200000000000000p-66:0x9ea82a21) flags=INEXACT (6/2) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x1.00000000000000000000p-149:0x00000001) flags=UNDERFLOW INEXACT (7/0) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=INEXACT (7/1) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (7/2) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (8/0) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (8/1) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(-0x0.00000000000000000000p+0:0x80000000) flags=UNDERFLOW INEXACT (8/2) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.00000000000000000000p-25:0x33000000) flags=OK (9/0) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x1.00000000000000000000p-149:0x00000001) flags=UNDERFLOW INEXACT (9/1) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (9/2) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.ffffe800000000000000p-25:0x337ffff4) flags=INEXACT (10/0) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.ffffe800000000000000p-50:0x26fffff4) flags=INEXACT (10/1) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.00000200000000000000p-25:0x33000001) flags=INEXACT (10/2) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ff801c00000000000000p-15:0x387fc00e) flags=INEXACT (11/0) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.00080000000000000000p-25:0x33000400) flags=INEXACT (11/1) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.0001f400000000000000p-24:0x338000fa) flags=INEXACT (11/2) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.00000e00000000000000p-14:0x38800007) flags=INEXACT (12/0) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.0ffbf600000000000000p-24:0x3387fdfb) flags=INEXACT (12/1) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ff801c00000000000000p-15:0x387fc00e) flags=INEXACT (12/2) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.00000200000000000000p+0:0x3f800001) flags=INEXACT (13/0) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ffc01a00000000000000p-14:0x38ffe00d) flags=INEXACT (13/1) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.ffc01a00000000000000p-14:0x38ffe00d) flags=INEXACT (13/2) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.00440200000000000000p+0:0x3f802201) flags=INEXACT (14/0) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.00440200000000000000p+0:0x3f802201) flags=INEXACT (14/1) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.00040200000000000000p+0:0x3f800201) flags=INEXACT (14/2) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.80200000000000000000p+1:0x40401000) flags=INEXACT (15/0) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.80400000000000000000p+1:0x40402000) flags=INEXACT (15/1) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.80200000000000000000p+1:0x40401000) flags=INEXACT (15/2) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.2e185400000000000000p+2:0x40970c2a) flags=INEXACT (16/0) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.9c00a800000000000000p+2:0x40ce0054) flags=INEXACT (16/1) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.2e23d400000000000000p+2:0x409711ea) flags=INEXACT (16/2) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.12804200000000000000p+3:0x41094021) flags=INEXACT (17/0) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.51458200000000000000p+3:0x4128a2c1) flags=INEXACT (17/1) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.200c0600000000000000p+3:0x41100603) flags=INEXACT (17/2) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.ffcf1600000000000000p+15:0x477fe78b) flags=INEXACT (18/0) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.91ed3c00000000000000p+17:0x4848f69e) flags=INEXACT (18/1) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.5bc56200000000000000p+17:0x482de2b1) flags=INEXACT (18/2) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.08edf000000000000000p+18:0x488476f8) flags=INEXACT (19/0) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.ff7e0a00000000000000p+31:0x4f7fbf05) flags=INEXACT (19/1) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.08ee7a00000000000000p+18:0x4884773d) flags=INEXACT (19/2) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff800a00000000000000p+31:0x4f7fc005) flags=INEXACT (20/0) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.ff840800000000000000p+31:0x4f7fc204) flags=INEXACT (20/1) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.ff820800000000000000p+31:0x4f7fc104) flags=INEXACT (20/2) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff860800000000000000p+31:0x4f7fc304) flags=INEXACT (21/0) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.ff820800000000000000p+32:0x4fffc104) flags=INEXACT (21/1) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff800a00000000000000p+32:0x4fffc005) flags=INEXACT (21/2) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.ff830800000000000000p+32:0x4fffc184) flags=INEXACT (22/0) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff7f8a00000000000000p+33:0x507fbfc5) flags=INEXACT (22/1) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff840800000000000000p+32:0x4fffc204) flags=INEXACT (22/2) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(0x1.ff800a00000000000000p+33:0x507fc005) flags=INEXACT (23/0) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff820800000000000000p+33:0x507fc104) flags=INEXACT (23/1) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.ff810800000000000000p+33:0x507fc084) flags=INEXACT (23/2) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(0x1.c0bab800000000000000p+99:0x71605d5c) flags=INEXACT (24/0) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.c0838000000000000000p+116:0x79e041c0) flags=INEXACT (24/1) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(0x1.c082a000000000000000p+116:0x79e04150) flags=INEXACT (24/2) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (25/0) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (25/1) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT (25/2) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000) +res: f32(inf:0x7f800000) flags=OK (26/0) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(inf:0x7f800000) flags=OK (26/1) +op : f32(inf:0x7f800000) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(inf:0x7f800000) flags=OK (26/2) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=OK (27/0) +op : f32(inf:0x7f800000) * f32(-nan:0x7fc00000) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(-nan:0xffffffff) flags=OK (27/1) +op : f32(-nan:0x7fc00000) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000) +res: f32(-nan:0xffffffff) flags=OK (27/2) +op : f32(inf:0x7f800000) * f32(-nan:0x7fc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (28/0) +op : f32(-nan:0x7fc00000) * f32(-nan:0x7fa00000) + f32(inf:0x7f800000) +res: f32(-nan:0xffffffff) flags=INVALID (28/1) +op : f32(-nan:0x7fa00000) * f32(inf:0x7f800000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=INVALID (28/2) +op : f32(-nan:0x7fc00000) * f32(-nan:0x7fa00000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/0) +op : f32(-nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/1) +op : f32(-nan:0xffa00000) * f32(-nan:0x7fc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/2) +op : f32(-nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/0) +op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/1) +op : f32(-nan:0xffc00000) * f32(-nan:0x7fa00000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/2) +# LP184149 +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-1:0x3f000000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x0.00000000000000000000p+0:0000000000) flags=OK (31/0) +op : f32(0x1.00000000000000000000p-149:0x00000001) * f32(0x1.00000000000000000000p-149:0x00000001) + f32(0x1.00000000000000000000p-149:0x00000001) +res: f32(0x1.00000000000000000000p-148:0x00000002) flags=UNDERFLOW INEXACT (32/0) +### Rounding downwards +op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-inf:0xff800000) +res: f32(-nan:0xffffffff) flags=INVALID (0/0) +op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (0/1) +op : f32(-inf:0xff800000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=INVALID (0/2) +op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(-nan:0xffffffff) flags=OK (1/0) +op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=OK (1/1) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-nan:0xffc00000) + f32(-inf:0xff800000) +res: f32(-nan:0xffffffff) flags=OK (1/2) +op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(inf:0x7f800000) flags=OK (2/0) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-inf:0xff800000) +res: f32(-inf:0xff800000) flags=OK (2/1) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(inf:0x7f800000) flags=OK (2/2) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (3/0) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (3/1) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (3/2) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (4/0) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(-0x1.1874b200000000000000p+103:0xf30c3a59) flags=INEXACT (4/1) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) flags=INEXACT (4/2) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(0x1.0c27f800000000000000p+60:0x5d8613fc) flags=INEXACT (5/0) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) flags=INEXACT (5/1) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(0x1.26c46000000000000000p+34:0x50936230) flags=INEXACT (5/2) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(0x1.91f93e00000000000000p-106:0x0ac8fc9f) flags=INEXACT (6/0) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(-0x1.31f75000000000000000p-40:0xab98fba8) flags=INEXACT (6/1) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=INEXACT (6/2) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT (7/0) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=INEXACT (7/1) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (7/2) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (8/0) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (8/1) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(-0x1.00000000000000000000p-149:0x80000001) flags=UNDERFLOW INEXACT (8/2) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.00000000000000000000p-25:0x33000000) flags=OK (9/0) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT (9/1) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (9/2) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.ffffe600000000000000p-25:0x337ffff3) flags=INEXACT (10/0) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.ffffe600000000000000p-50:0x26fffff3) flags=INEXACT (10/1) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.00000000000000000000p-25:0x33000000) flags=INEXACT (10/2) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ff801a00000000000000p-15:0x387fc00d) flags=INEXACT (11/0) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.0007fe00000000000000p-25:0x330003ff) flags=INEXACT (11/1) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.0001f200000000000000p-24:0x338000f9) flags=INEXACT (11/2) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.00000c00000000000000p-14:0x38800006) flags=INEXACT (12/0) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.0ffbf400000000000000p-24:0x3387fdfa) flags=INEXACT (12/1) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ff801a00000000000000p-15:0x387fc00d) flags=INEXACT (12/2) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.00000000000000000000p+0:0x3f800000) flags=INEXACT (13/0) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT (13/1) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT (13/2) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT (14/0) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT (14/1) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.00040000000000000000p+0:0x3f800200) flags=INEXACT (14/2) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.80200000000000000000p+1:0x40401000) flags=INEXACT (15/0) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.80400000000000000000p+1:0x40402000) flags=INEXACT (15/1) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.80200000000000000000p+1:0x40401000) flags=INEXACT (15/2) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.2e185400000000000000p+2:0x40970c2a) flags=INEXACT (16/0) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.9c00a800000000000000p+2:0x40ce0054) flags=INEXACT (16/1) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.2e23d200000000000000p+2:0x409711e9) flags=INEXACT (16/2) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.12804000000000000000p+3:0x41094020) flags=INEXACT (17/0) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.51458000000000000000p+3:0x4128a2c0) flags=INEXACT (17/1) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.200c0400000000000000p+3:0x41100602) flags=INEXACT (17/2) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.ffcf1400000000000000p+15:0x477fe78a) flags=INEXACT (18/0) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.91ed3a00000000000000p+17:0x4848f69d) flags=INEXACT (18/1) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.5bc56000000000000000p+17:0x482de2b0) flags=INEXACT (18/2) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.08edee00000000000000p+18:0x488476f7) flags=INEXACT (19/0) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.ff7e0800000000000000p+31:0x4f7fbf04) flags=INEXACT (19/1) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.08ee7800000000000000p+18:0x4884773c) flags=INEXACT (19/2) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff800800000000000000p+31:0x4f7fc004) flags=INEXACT (20/0) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.ff840600000000000000p+31:0x4f7fc203) flags=INEXACT (20/1) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.ff820600000000000000p+31:0x4f7fc103) flags=INEXACT (20/2) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff860600000000000000p+31:0x4f7fc303) flags=INEXACT (21/0) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.ff820600000000000000p+32:0x4fffc103) flags=INEXACT (21/1) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff800800000000000000p+32:0x4fffc004) flags=INEXACT (21/2) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.ff830600000000000000p+32:0x4fffc183) flags=INEXACT (22/0) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff7f8800000000000000p+33:0x507fbfc4) flags=INEXACT (22/1) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff840600000000000000p+32:0x4fffc203) flags=INEXACT (22/2) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(0x1.ff800800000000000000p+33:0x507fc004) flags=INEXACT (23/0) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff820600000000000000p+33:0x507fc103) flags=INEXACT (23/1) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.ff810600000000000000p+33:0x507fc083) flags=INEXACT (23/2) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(0x1.c0bab600000000000000p+99:0x71605d5b) flags=INEXACT (24/0) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.c0837e00000000000000p+116:0x79e041bf) flags=INEXACT (24/1) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(0x1.c0829e00000000000000p+116:0x79e0414f) flags=INEXACT (24/2) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (25/0) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (25/1) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (25/2) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000) +res: f32(inf:0x7f800000) flags=OK (26/0) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(inf:0x7f800000) flags=OK (26/1) +op : f32(inf:0x7f800000) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(inf:0x7f800000) flags=OK (26/2) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=OK (27/0) +op : f32(inf:0x7f800000) * f32(-nan:0x7fc00000) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(-nan:0xffffffff) flags=OK (27/1) +op : f32(-nan:0x7fc00000) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000) +res: f32(-nan:0xffffffff) flags=OK (27/2) +op : f32(inf:0x7f800000) * f32(-nan:0x7fc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (28/0) +op : f32(-nan:0x7fc00000) * f32(-nan:0x7fa00000) + f32(inf:0x7f800000) +res: f32(-nan:0xffffffff) flags=INVALID (28/1) +op : f32(-nan:0x7fa00000) * f32(inf:0x7f800000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=INVALID (28/2) +op : f32(-nan:0x7fc00000) * f32(-nan:0x7fa00000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/0) +op : f32(-nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/1) +op : f32(-nan:0xffa00000) * f32(-nan:0x7fc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/2) +op : f32(-nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/0) +op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/1) +op : f32(-nan:0xffc00000) * f32(-nan:0x7fa00000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/2) +# LP184149 +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-1:0x3f000000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x0.00000000000000000000p+0:0000000000) flags=OK (31/0) +op : f32(0x1.00000000000000000000p-149:0x00000001) * f32(0x1.00000000000000000000p-149:0x00000001) + f32(0x1.00000000000000000000p-149:0x00000001) +res: f32(0x1.00000000000000000000p-149:0x00000001) flags=UNDERFLOW INEXACT (32/0) +### Rounding to zero +op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-inf:0xff800000) +res: f32(-nan:0xffffffff) flags=INVALID (0/0) +op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (0/1) +op : f32(-inf:0xff800000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=INVALID (0/2) +op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(-nan:0xffffffff) flags=OK (1/0) +op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=OK (1/1) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-nan:0xffc00000) + f32(-inf:0xff800000) +res: f32(-nan:0xffffffff) flags=OK (1/2) +op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(inf:0x7f800000) flags=OK (2/0) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-inf:0xff800000) +res: f32(-inf:0xff800000) flags=OK (2/1) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(inf:0x7f800000) flags=OK (2/2) +op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (3/0) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (3/1) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (3/2) +op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (4/0) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59) +res: f32(-0x1.1874b000000000000000p+103:0xf30c3a58) flags=INEXACT (4/1) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(-0x1.c0bab400000000000000p+99:0xf1605d5a) flags=INEXACT (4/2) +op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(0x1.0c27f800000000000000p+60:0x5d8613fc) flags=INEXACT (5/0) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) +res: f32(-0x1.c0bab400000000000000p+99:0xf1605d5a) flags=INEXACT (5/1) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(0x1.26c46000000000000000p+34:0x50936230) flags=INEXACT (5/2) +op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(0x1.91f93e00000000000000p-106:0x0ac8fc9f) flags=INEXACT (6/0) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(-0x1.31f75000000000000000p-40:0xab98fba8) +res: f32(-0x1.31f74e00000000000000p-40:0xab98fba7) flags=INEXACT (6/1) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(-0x1.50544200000000000000p-66:0x9ea82a21) flags=INEXACT (6/2) +op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT (7/0) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(-0x1.50544400000000000000p-66:0x9ea82a22) +res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=INEXACT (7/1) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (7/2) +op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (8/0) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(-0x1.00000000000000000000p-126:0x80800000) +res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (8/1) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(-0x0.00000000000000000000p+0:0x80000000) flags=UNDERFLOW INEXACT (8/2) +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.00000000000000000000p-25:0x33000000) flags=OK (9/0) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT (9/1) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (9/2) +op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.ffffe600000000000000p-25:0x337ffff3) flags=INEXACT (10/0) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.00000000000000000000p-126:0x00800000) +res: f32(0x1.ffffe600000000000000p-50:0x26fffff3) flags=INEXACT (10/1) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.00000000000000000000p-25:0x33000000) flags=INEXACT (10/2) +op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ff801a00000000000000p-15:0x387fc00d) flags=INEXACT (11/0) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000000000000000000p-25:0x33000000) +res: f32(0x1.0007fe00000000000000p-25:0x330003ff) flags=INEXACT (11/1) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.0001f200000000000000p-24:0x338000f9) flags=INEXACT (11/2) +op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.00000c00000000000000p-14:0x38800006) flags=INEXACT (12/0) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.ffffe600000000000000p-25:0x337ffff3) +res: f32(0x1.0ffbf400000000000000p-24:0x3387fdfa) flags=INEXACT (12/1) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ff801a00000000000000p-15:0x387fc00d) flags=INEXACT (12/2) +op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.00000000000000000000p+0:0x3f800000) flags=INEXACT (13/0) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.ff801a00000000000000p-15:0x387fc00d) +res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT (13/1) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT (13/2) +op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT (14/0) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000c00000000000000p-14:0x38800006) +res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT (14/1) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.00040000000000000000p+0:0x3f800200) flags=INEXACT (14/2) +op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.80200000000000000000p+1:0x40401000) flags=INEXACT (15/0) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.00000000000000000000p+0:0x3f800000) +res: f32(0x1.80400000000000000000p+1:0x40402000) flags=INEXACT (15/1) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.80200000000000000000p+1:0x40401000) flags=INEXACT (15/2) +op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.2e185400000000000000p+2:0x40970c2a) flags=INEXACT (16/0) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.00400000000000000000p+0:0x3f802000) +res: f32(0x1.9c00a800000000000000p+2:0x40ce0054) flags=INEXACT (16/1) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.2e23d200000000000000p+2:0x409711e9) flags=INEXACT (16/2) +op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.12804000000000000000p+3:0x41094020) flags=INEXACT (17/0) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.00000000000000000000p+1:0x40000000) +res: f32(0x1.51458000000000000000p+3:0x4128a2c0) flags=INEXACT (17/1) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.200c0400000000000000p+3:0x41100602) flags=INEXACT (17/2) +op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.ffcf1400000000000000p+15:0x477fe78a) flags=INEXACT (18/0) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.5bf0a800000000000000p+1:0x402df854) +res: f32(0x1.91ed3a00000000000000p+17:0x4848f69d) flags=INEXACT (18/1) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.5bc56000000000000000p+17:0x482de2b0) flags=INEXACT (18/2) +op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.08edee00000000000000p+18:0x488476f7) flags=INEXACT (19/0) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.921fb600000000000000p+1:0x40490fdb) +res: f32(0x1.ff7e0800000000000000p+31:0x4f7fbf04) flags=INEXACT (19/1) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.08ee7800000000000000p+18:0x4884773c) flags=INEXACT (19/2) +op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff800800000000000000p+31:0x4f7fc004) flags=INEXACT (20/0) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00) +res: f32(0x1.ff840600000000000000p+31:0x4f7fc203) flags=INEXACT (20/1) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.ff820600000000000000p+31:0x4f7fc103) flags=INEXACT (20/2) +op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff860600000000000000p+31:0x4f7fc303) flags=INEXACT (21/0) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+15:0x477fe000) +res: f32(0x1.ff820600000000000000p+32:0x4fffc103) flags=INEXACT (21/1) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff800800000000000000p+32:0x4fffc004) flags=INEXACT (21/2) +op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.ff830600000000000000p+32:0x4fffc183) flags=INEXACT (22/0) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100) +res: f32(0x1.ff7f8800000000000000p+33:0x507fbfc4) flags=INEXACT (22/1) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff840600000000000000p+32:0x4fffc203) flags=INEXACT (22/2) +op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(0x1.ff800800000000000000p+33:0x507fc004) flags=INEXACT (23/0) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) +res: f32(0x1.ff820600000000000000p+33:0x507fc103) flags=INEXACT (23/1) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.ff810600000000000000p+33:0x507fc083) flags=INEXACT (23/2) +op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(0x1.c0bab600000000000000p+99:0x71605d5b) flags=INEXACT (24/0) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.ffc00000000000000000p+16:0x47ffe000) +res: f32(0x1.c0837e00000000000000p+116:0x79e041bf) flags=INEXACT (24/1) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(0x1.c0829e00000000000000p+116:0x79e0414f) flags=INEXACT (24/2) +op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (25/0) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(0x1.ffc10000000000000000p+16:0x47ffe080) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (25/1) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT (25/2) +op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000) +res: f32(inf:0x7f800000) flags=OK (26/0) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(0x1.c0bab600000000000000p+99:0x71605d5b) +res: f32(inf:0x7f800000) flags=OK (26/1) +op : f32(inf:0x7f800000) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(inf:0x7f800000) flags=OK (26/2) +op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=OK (27/0) +op : f32(inf:0x7f800000) * f32(-nan:0x7fc00000) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff) +res: f32(-nan:0xffffffff) flags=OK (27/1) +op : f32(-nan:0x7fc00000) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000) +res: f32(-nan:0xffffffff) flags=OK (27/2) +op : f32(inf:0x7f800000) * f32(-nan:0x7fc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (28/0) +op : f32(-nan:0x7fc00000) * f32(-nan:0x7fa00000) + f32(inf:0x7f800000) +res: f32(-nan:0xffffffff) flags=INVALID (28/1) +op : f32(-nan:0x7fa00000) * f32(inf:0x7f800000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=INVALID (28/2) +op : f32(-nan:0x7fc00000) * f32(-nan:0x7fa00000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/0) +op : f32(-nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0x7fc00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/1) +op : f32(-nan:0xffa00000) * f32(-nan:0x7fc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (29/2) +op : f32(-nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/0) +op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-nan:0x7fa00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/1) +op : f32(-nan:0xffc00000) * f32(-nan:0x7fa00000) + f32(-nan:0xffa00000) +res: f32(-nan:0xffffffff) flags=INVALID (30/2) +# LP184149 +op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-1:0x3f000000) + f32(0x0.00000000000000000000p+0:0000000000) +res: f32(0x0.00000000000000000000p+0:0000000000) flags=OK (31/0) +op : f32(0x1.00000000000000000000p-149:0x00000001) * f32(0x1.00000000000000000000p-149:0x00000001) + f32(0x1.00000000000000000000p-149:0x00000001) +res: f32(0x1.00000000000000000000p-149:0x00000001) flags=UNDERFLOW INEXACT (32/0) From patchwork Wed Feb 17 23:40:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384201 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3234023jao; Wed, 17 Feb 2021 16:11:32 -0800 (PST) X-Google-Smtp-Source: ABdhPJx66sz0ozUmJ5ahkv/vaLocCtDQLPA1+XmL1ZgVrTtvEF9NrPxzluKBqZ1v4vXUOTh+frJM X-Received: by 2002:a25:8687:: with SMTP id z7mr2650265ybk.209.1613607092713; Wed, 17 Feb 2021 16:11:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613607092; cv=none; d=google.com; s=arc-20160816; b=a89gDhIoiyiRYeaVMi5tkw6zjrxcHSbcdjhi4zH4KwnhaER5bVukwuydIdjYerQZMU snGWOrayBVOsohO/S14i0jZSU0S+gARyL+mmsBeJqbxzraDPCnQLVmx2GzLrx2wSO5jf GDhMgWNjFO7v8496LZpNPtLtBRWuR78aUPU1z07zu0rTjBl+9YjypIk2YqB+7Uw6zWx1 Ea8BXg14yUkzTBnuvy1UCGIww9PSEsO49Myq20thJ13A0gQmq95qOH8MUCMebJM/fEO6 nyXzF69A18Xkh2zstTka6W1tkKmnL3/7vetJnLgoh968SHVksSjasOjB4GU6/ZK1oZML m81Q== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=NrnvBEX9wxABZhH4uNqG+pDYIgCmpZeFvdyMJTnD9lE=; b=BwF8oWShdGQletxnnoFimAPGI4KWw8aZzF/AZyFF7n29/GTEbbbC7aTPR1Q62s9n6f pSv+VmTGm3X7r8P0FnDZzwVYULOU2jTF7v1t1NRRVdvaoMVbwb7pscLUCzvU8oHhPp/w H2AN9ERmRIMbpaj4dH3KPvmn8vWSE9AVCMEZc3zRBXIVGz9t+d7W/YKU6FZdV97Cx1w4 ByZBZxjMqSAyyI9GEgN86PL6kcb5eWsgohI/m6Kwv5Nm8GUO/noeNoreYUQlxfGDjKDR e5Vp5PZAATcdoVCCdrxHVd+xauwqWWf1+E0jN3OAIRKHsNQl8jjj9K3IBrE3iRoN/YFU /Sug== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=tD5CPryv; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 4si3307492ybo.222.2021.02.17.16.11.32 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 16:11:32 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=tD5CPryv; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:34098 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWuq-0002BS-6u for patch@linaro.org; Wed, 17 Feb 2021 19:11:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51204) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWSF-0001Fi-JQ for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:59 -0500 Received: from mail-pg1-x52c.google.com ([2607:f8b0:4864:20::52c]:41707) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWS2-0004uy-BC for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:59 -0500 Received: by mail-pg1-x52c.google.com with SMTP id t11so9515859pgu.8 for ; Wed, 17 Feb 2021 15:41:44 -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 :mime-version:content-transfer-encoding; bh=NrnvBEX9wxABZhH4uNqG+pDYIgCmpZeFvdyMJTnD9lE=; b=tD5CPryvqELvdKeQJpYUqTvpW7+8XAQohNOVXSVPTNa2etQltOfURNxfZGuOL6A1k4 DVLHuls7BYc9xqMlvc4eodeP2Ys4nLhzm6fSGprOmK28gELLneDUQ6MOvsXoOtwfNRiz RTtjNOmM6+vXVwpvgSZC9QMkeaIPZhBwASjvE7bLpudbHrEJ7qCNpVmj1Izbb4psHBXW Z0wb+jt/dbBkU9pSi+kZ7jFG/h/TFOle5e3CaF2lOJPcRXEU99EydpVnDMbKbb7YnQuE Qfo5o/WBd/ohSM6cyZ58dEzLITzMmGFkFhftv2qds4XWdzwYcmTr+wLc7B2DCh49chT3 8A8A== 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:mime-version:content-transfer-encoding; bh=NrnvBEX9wxABZhH4uNqG+pDYIgCmpZeFvdyMJTnD9lE=; b=AHEzk4v3Ehgy4FehWd+ay/lZ1eXbJ6EWGDyy+56ohm2xNhruCyhQ+sgwm5Fx0wG3dr DQNTQo8zzZ0DTKNVxoSItkggzo8UNyTbPhOdYRgK7pSCseAMT6NuU6zy6zTQ9Hkslsnp LfcJjTIU16bI0Xv+GF57D5WHzsTpeoQFA6IR/AK+N7+Ja4znDPySDoUNmmK55NejrF8M +uZAkD2/Q+wOrgVXow1fXAkn5IngVcf2WvS11u8xP+V9JkgaCwwHXi29rZEe97/ZNjhm X5AXmGttDNxe8yl7ujjvIooGZNyBhmqRt6cnE92VpztUXOY+J6GttVyozOMpvK92sUli h+iw== X-Gm-Message-State: AOAM530GGXcekIAIP65IT0rBh0DBaush1sI0Goy5QapHLvKDhAYCnykJ uljJGODKnxOeY59POcq0XX1Op1KQ3RYonA== X-Received: by 2002:a63:f709:: with SMTP id x9mr1531548pgh.287.1613605302698; Wed, 17 Feb 2021 15:41:42 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:42 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 33/35] Hexagon (tests/tcg/hexagon) TCG tests - atomics/load/store/misc Date: Wed, 17 Feb 2021 15:40:21 -0800 Message-Id: <20210217234023.1742406-34-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52c; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Signed-off-by: Taylor Simpson Message-Id: <1612763186-18161-33-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- tests/tcg/hexagon/atomics.c | 139 +++++++++++ tests/tcg/hexagon/dual_stores.c | 60 +++++ tests/tcg/hexagon/mem_noshuf.c | 328 ++++++++++++++++++++++++++ tests/tcg/hexagon/misc.c | 380 ++++++++++++++++++++++++++++++ tests/tcg/hexagon/preg_alias.c | 169 +++++++++++++ tests/tcg/hexagon/Makefile.target | 15 ++ tests/tcg/hexagon/first.S | 56 +++++ 7 files changed, 1147 insertions(+) create mode 100644 tests/tcg/hexagon/atomics.c create mode 100644 tests/tcg/hexagon/dual_stores.c create mode 100644 tests/tcg/hexagon/mem_noshuf.c create mode 100644 tests/tcg/hexagon/misc.c create mode 100644 tests/tcg/hexagon/preg_alias.c create mode 100644 tests/tcg/hexagon/first.S -- 2.25.1 diff --git a/tests/tcg/hexagon/atomics.c b/tests/tcg/hexagon/atomics.c new file mode 100644 index 0000000000..ff1ceee241 --- /dev/null +++ b/tests/tcg/hexagon/atomics.c @@ -0,0 +1,139 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +/* Using volatile because we are testing atomics */ +static inline int atomic_inc32(volatile int *x) +{ + int old, dummy; + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n\t" + " %1 = add(%0, #1)\n\t" + " memw_locked(%2, p0) = %1\n\t" + " if (!p0) jump 1b\n\t" + : "=&r"(old), "=&r"(dummy) + : "r"(x) + : "p0", "memory"); + return old; +} + +/* Using volatile because we are testing atomics */ +static inline long long atomic_inc64(volatile long long *x) +{ + long long old, dummy; + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n\t" + " %1 = #1\n\t" + " %1 = add(%0, %1)\n\t" + " memd_locked(%2, p0) = %1\n\t" + " if (!p0) jump 1b\n\t" + : "=&r"(old), "=&r"(dummy) + : "r"(x) + : "p0", "memory"); + return old; +} + +/* Using volatile because we are testing atomics */ +static inline int atomic_dec32(volatile int *x) +{ + int old, dummy; + __asm__ __volatile__( + "1: %0 = memw_locked(%2)\n\t" + " %1 = add(%0, #-1)\n\t" + " memw_locked(%2, p0) = %1\n\t" + " if (!p0) jump 1b\n\t" + : "=&r"(old), "=&r"(dummy) + : "r"(x) + : "p0", "memory"); + return old; +} + +/* Using volatile because we are testing atomics */ +static inline long long atomic_dec64(volatile long long *x) +{ + long long old, dummy; + __asm__ __volatile__( + "1: %0 = memd_locked(%2)\n\t" + " %1 = #-1\n\t" + " %1 = add(%0, %1)\n\t" + " memd_locked(%2, p0) = %1\n\t" + " if (!p0) jump 1b\n\t" + : "=&r"(old), "=&r"(dummy) + : "r"(x) + : "p0", "memory"); + return old; +} + +#define LOOP_CNT 1000 +/* Using volatile because we are testing atomics */ +volatile int tick32 = 1; +/* Using volatile because we are testing atomics */ +volatile long long tick64 = 1; +int err; + +void *thread1_func(void *arg) +{ + int i; + + for (i = 0; i < LOOP_CNT; i++) { + atomic_inc32(&tick32); + atomic_dec64(&tick64); + } + return NULL; +} + +void *thread2_func(void *arg) +{ + int i; + for (i = 0; i < LOOP_CNT; i++) { + atomic_dec32(&tick32); + atomic_inc64(&tick64); + } + return NULL; +} + +void test_pthread(void) +{ + pthread_t tid1, tid2; + + pthread_create(&tid1, NULL, thread1_func, "hello1"); + pthread_create(&tid2, NULL, thread2_func, "hello2"); + pthread_join(tid1, NULL); + pthread_join(tid2, NULL); + + if (tick32 != 1) { + printf("ERROR: tick32 %d != 1\n", tick32); + err++; + } + if (tick64 != 1) { + printf("ERROR: tick64 %lld != 1\n", tick64); + err++; + } +} + +int main(int argc, char **argv) +{ + test_pthread(); + puts(err ? "FAIL" : "PASS"); + return err; +} diff --git a/tests/tcg/hexagon/dual_stores.c b/tests/tcg/hexagon/dual_stores.c new file mode 100644 index 0000000000..a86a381ab9 --- /dev/null +++ b/tests/tcg/hexagon/dual_stores.c @@ -0,0 +1,60 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include + +/* + * Make sure that two stores in the same packet honor proper + * semantics: slot 1 executes first, then slot 0. + * This is important when the addresses overlap. + */ +static inline void dual_stores(int *p, char *q, int x, char y) +{ + asm volatile("{\n\t" + " memw(%0) = %2\n\t" + " memb(%1) = %3\n\t" + "}\n" + :: "r"(p), "r"(q), "r"(x), "r"(y) + : "memory"); +} + +typedef union { + int word; + char byte; +} Dual; + +int err; + +static void check(Dual d, int expect) +{ + if (d.word != expect) { + printf("ERROR: 0x%08x != 0x%08x\n", d.word, expect); + err++; + } +} + +int main() +{ + Dual d; + + d.word = ~0; + dual_stores(&d.word, &d.byte, 0x12345678, 0xff); + check(d, 0x123456ff); + + puts(err ? "FAIL" : "PASS"); + return err; +} diff --git a/tests/tcg/hexagon/mem_noshuf.c b/tests/tcg/hexagon/mem_noshuf.c new file mode 100644 index 0000000000..dd714d5e98 --- /dev/null +++ b/tests/tcg/hexagon/mem_noshuf.c @@ -0,0 +1,328 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include + +/* + * Make sure that the :mem_noshuf packet attribute is honored. + * This is important when the addresses overlap. + * The store instruction in slot 1 effectively executes first, + * followed by the load instruction in slot 0. + */ + +#define MEM_NOSHUF32(NAME, ST_TYPE, LD_TYPE, ST_OP, LD_OP) \ +static inline unsigned int NAME(ST_TYPE * p, LD_TYPE * q, ST_TYPE x) \ +{ \ + unsigned int ret; \ + asm volatile("{\n\t" \ + " " #ST_OP "(%1) = %3\n\t" \ + " %0 = " #LD_OP "(%2)\n\t" \ + "}:mem_noshuf\n" \ + : "=r"(ret) \ + : "r"(p), "r"(q), "r"(x) \ + : "memory"); \ + return ret; \ +} + +#define MEM_NOSHUF64(NAME, ST_TYPE, LD_TYPE, ST_OP, LD_OP) \ +static inline unsigned long long NAME(ST_TYPE * p, LD_TYPE * q, ST_TYPE x) \ +{ \ + unsigned long long ret; \ + asm volatile("{\n\t" \ + " " #ST_OP "(%1) = %3\n\t" \ + " %0 = " #LD_OP "(%2)\n\t" \ + "}:mem_noshuf\n" \ + : "=r"(ret) \ + : "r"(p), "r"(q), "r"(x) \ + : "memory"); \ + return ret; \ +} + +/* Store byte combinations */ +MEM_NOSHUF32(mem_noshuf_sb_lb, signed char, signed char, memb, memb) +MEM_NOSHUF32(mem_noshuf_sb_lub, signed char, unsigned char, memb, memub) +MEM_NOSHUF32(mem_noshuf_sb_lh, signed char, signed short, memb, memh) +MEM_NOSHUF32(mem_noshuf_sb_luh, signed char, unsigned short, memb, memuh) +MEM_NOSHUF32(mem_noshuf_sb_lw, signed char, signed int, memb, memw) +MEM_NOSHUF64(mem_noshuf_sb_ld, signed char, signed long long, memb, memd) + +/* Store half combinations */ +MEM_NOSHUF32(mem_noshuf_sh_lb, signed short, signed char, memh, memb) +MEM_NOSHUF32(mem_noshuf_sh_lub, signed short, unsigned char, memh, memub) +MEM_NOSHUF32(mem_noshuf_sh_lh, signed short, signed short, memh, memh) +MEM_NOSHUF32(mem_noshuf_sh_luh, signed short, unsigned short, memh, memuh) +MEM_NOSHUF32(mem_noshuf_sh_lw, signed short, signed int, memh, memw) +MEM_NOSHUF64(mem_noshuf_sh_ld, signed short, signed long long, memh, memd) + +/* Store word combinations */ +MEM_NOSHUF32(mem_noshuf_sw_lb, signed int, signed char, memw, memb) +MEM_NOSHUF32(mem_noshuf_sw_lub, signed int, unsigned char, memw, memub) +MEM_NOSHUF32(mem_noshuf_sw_lh, signed int, signed short, memw, memh) +MEM_NOSHUF32(mem_noshuf_sw_luh, signed int, unsigned short, memw, memuh) +MEM_NOSHUF32(mem_noshuf_sw_lw, signed int, signed int, memw, memw) +MEM_NOSHUF64(mem_noshuf_sw_ld, signed int, signed long long, memw, memd) + +/* Store double combinations */ +MEM_NOSHUF32(mem_noshuf_sd_lb, long long, signed char, memd, memb) +MEM_NOSHUF32(mem_noshuf_sd_lub, long long, unsigned char, memd, memub) +MEM_NOSHUF32(mem_noshuf_sd_lh, long long, signed short, memd, memh) +MEM_NOSHUF32(mem_noshuf_sd_luh, long long, unsigned short, memd, memuh) +MEM_NOSHUF32(mem_noshuf_sd_lw, long long, signed int, memd, memw) +MEM_NOSHUF64(mem_noshuf_sd_ld, long long, signed long long, memd, memd) + +static inline unsigned int cancel_sw_lb(int pred, int *p, signed char *q, int x) +{ + unsigned int ret; + asm volatile("p0 = cmp.eq(%4, #0)\n\t" + "{\n\t" + " if (!p0) memw(%1) = %3\n\t" + " %0 = memb(%2)\n\t" + "}:mem_noshuf\n" + : "=r"(ret) + : "r"(p), "r"(q), "r"(x), "r"(pred) + : "p0", "memory"); + return ret; +} + +static inline +unsigned long long cancel_sw_ld(int pred, int *p, long long *q, int x) +{ + long long ret; + asm volatile("p0 = cmp.eq(%4, #0)\n\t" + "{\n\t" + " if (!p0) memw(%1) = %3\n\t" + " %0 = memd(%2)\n\t" + "}:mem_noshuf\n" + : "=r"(ret) + : "r"(p), "r"(q), "r"(x), "r"(pred) + : "p0", "memory"); + return ret; +} + +typedef union { + signed long long d[2]; + unsigned long long ud[2]; + signed int w[4]; + unsigned int uw[4]; + signed short h[8]; + unsigned short uh[8]; + signed char b[16]; + unsigned char ub[16]; +} Memory; + +int err; + +static void check32(int n, int expect) +{ + if (n != expect) { + printf("ERROR: 0x%08x != 0x%08x\n", n, expect); + err++; + } +} + +static void check64(long long n, long long expect) +{ + if (n != expect) { + printf("ERROR: 0x%08llx != 0x%08llx\n", n, expect); + err++; + } +} + +int main() +{ + Memory n; + unsigned int res32; + unsigned long long res64; + + /* + * Store byte combinations + */ + n.w[0] = ~0; + res32 = mem_noshuf_sb_lb(&n.b[0], &n.b[0], 0x87); + check32(res32, 0xffffff87); + + n.w[0] = ~0; + res32 = mem_noshuf_sb_lub(&n.b[0], &n.ub[0], 0x87); + check32(res32, 0x00000087); + + n.w[0] = ~0; + res32 = mem_noshuf_sb_lh(&n.b[0], &n.h[0], 0x87); + check32(res32, 0xffffff87); + + n.w[0] = ~0; + res32 = mem_noshuf_sb_luh(&n.b[0], &n.uh[0], 0x87); + check32(res32, 0x0000ff87); + + n.w[0] = ~0; + res32 = mem_noshuf_sb_lw(&n.b[0], &n.w[0], 0x87); + check32(res32, 0xffffff87); + + n.d[0] = ~0LL; + res64 = mem_noshuf_sb_ld(&n.b[0], &n.d[0], 0x87); + check64(res64, 0xffffffffffffff87LL); + + /* + * Store half combinations + */ + n.w[0] = ~0; + res32 = mem_noshuf_sh_lb(&n.h[0], &n.b[0], 0x8787); + check32(res32, 0xffffff87); + + n.w[0] = ~0; + res32 = mem_noshuf_sh_lub(&n.h[0], &n.ub[1], 0x8f87); + check32(res32, 0x0000008f); + + n.w[0] = ~0; + res32 = mem_noshuf_sh_lh(&n.h[0], &n.h[0], 0x8a87); + check32(res32, 0xffff8a87); + + n.w[0] = ~0; + res32 = mem_noshuf_sh_luh(&n.h[0], &n.uh[0], 0x8a87); + check32(res32, 0x8a87); + + n.w[0] = ~0; + res32 = mem_noshuf_sh_lw(&n.h[1], &n.w[0], 0x8a87); + check32(res32, 0x8a87ffff); + + n.w[0] = ~0; + res64 = mem_noshuf_sh_ld(&n.h[1], &n.d[0], 0x8a87); + check64(res64, 0xffffffff8a87ffffLL); + + /* + * Store word combinations + */ + n.w[0] = ~0; + res32 = mem_noshuf_sw_lb(&n.w[0], &n.b[0], 0x12345687); + check32(res32, 0xffffff87); + + n.w[0] = ~0; + res32 = mem_noshuf_sw_lub(&n.w[0], &n.ub[0], 0x12345687); + check32(res32, 0x00000087); + + n.w[0] = ~0; + res32 = mem_noshuf_sw_lh(&n.w[0], &n.h[0], 0x1234f678); + check32(res32, 0xfffff678); + + n.w[0] = ~0; + res32 = mem_noshuf_sw_luh(&n.w[0], &n.uh[0], 0x12345678); + check32(res32, 0x00005678); + + n.w[0] = ~0; + res32 = mem_noshuf_sw_lw(&n.w[0], &n.w[0], 0x12345678); + check32(res32, 0x12345678); + + n.d[0] = ~0LL; + res64 = mem_noshuf_sw_ld(&n.w[0], &n.d[0], 0x12345678); + check64(res64, 0xffffffff12345678LL); + + /* + * Store double combinations + */ + n.d[0] = ~0LL; + res32 = mem_noshuf_sd_lb(&n.d[0], &n.b[1], 0x123456789abcdef0); + check32(res32, 0xffffffde); + + n.d[0] = ~0LL; + res32 = mem_noshuf_sd_lub(&n.d[0], &n.ub[1], 0x123456789abcdef0); + check32(res32, 0x000000de); + + n.d[0] = ~0LL; + res32 = mem_noshuf_sd_lh(&n.d[0], &n.h[1], 0x123456789abcdef0); + check32(res32, 0xffff9abc); + + n.d[0] = ~0LL; + res32 = mem_noshuf_sd_luh(&n.d[0], &n.uh[1], 0x123456789abcdef0); + check32(res32, 0x00009abc); + + n.d[0] = ~0LL; + res32 = mem_noshuf_sd_lw(&n.d[0], &n.w[1], 0x123456789abcdef0); + check32(res32, 0x12345678); + + n.d[0] = ~0LL; + res64 = mem_noshuf_sd_ld(&n.d[0], &n.d[0], 0x123456789abcdef0); + check64(res64, 0x123456789abcdef0LL); + + /* + * Predicated word stores + */ + n.w[0] = ~0; + res32 = cancel_sw_lb(0, &n.w[0], &n.b[0], 0x12345678); + check32(res32, 0xffffffff); + + n.w[0] = ~0; + res32 = cancel_sw_lb(1, &n.w[0], &n.b[0], 0x12345687); + check32(res32, 0xffffff87); + + /* + * Predicated double stores + */ + n.d[0] = ~0LL; + res64 = cancel_sw_ld(0, &n.w[0], &n.d[0], 0x12345678); + check64(res64, 0xffffffffffffffffLL); + + n.d[0] = ~0LL; + res64 = cancel_sw_ld(1, &n.w[0], &n.d[0], 0x12345678); + check64(res64, 0xffffffff12345678LL); + + n.d[0] = ~0LL; + res64 = cancel_sw_ld(0, &n.w[1], &n.d[0], 0x12345678); + check64(res64, 0xffffffffffffffffLL); + + n.d[0] = ~0LL; + res64 = cancel_sw_ld(1, &n.w[1], &n.d[0], 0x12345678); + check64(res64, 0x12345678ffffffffLL); + + /* + * No overlap tests + */ + n.w[0] = ~0; + res32 = mem_noshuf_sb_lb(&n.b[1], &n.b[0], 0x87); + check32(res32, 0xffffffff); + + n.w[0] = ~0; + res32 = mem_noshuf_sb_lb(&n.b[0], &n.b[1], 0x87); + check32(res32, 0xffffffff); + + n.w[0] = ~0; + res32 = mem_noshuf_sh_lh(&n.h[1], &n.h[0], 0x8787); + check32(res32, 0xffffffff); + + n.w[0] = ~0; + res32 = mem_noshuf_sh_lh(&n.h[0], &n.h[1], 0x8787); + check32(res32, 0xffffffff); + + n.d[0] = ~0LL; + res32 = mem_noshuf_sw_lw(&n.w[0], &n.w[1], 0x12345678); + check32(res32, 0xffffffff); + + n.d[0] = ~0LL; + res32 = mem_noshuf_sw_lw(&n.w[1], &n.w[0], 0x12345678); + check32(res32, 0xffffffff); + + n.d[0] = ~0LL; + n.d[1] = ~0LL; + res64 = mem_noshuf_sd_ld(&n.d[1], &n.d[0], 0x123456789abcdef0LL); + check64(res64, 0xffffffffffffffffLL); + + n.d[0] = ~0LL; + n.d[1] = ~0LL; + res64 = mem_noshuf_sd_ld(&n.d[0], &n.d[1], 0x123456789abcdef0LL); + check64(res64, 0xffffffffffffffffLL); + + puts(err ? "FAIL" : "PASS"); + return err; +} diff --git a/tests/tcg/hexagon/misc.c b/tests/tcg/hexagon/misc.c new file mode 100644 index 0000000000..458759f7b1 --- /dev/null +++ b/tests/tcg/hexagon/misc.c @@ -0,0 +1,380 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + + +static inline void S4_storerhnew_rr(void *p, int index, uint16_t v) +{ + asm volatile("{\n\t" + " r0 = %0\n\n" + " memh(%1+%2<<#2) = r0.new\n\t" + "}\n" + :: "r"(v), "r"(p), "r"(index) + : "r0", "memory"); +} + +static uint32_t data; +static inline void *S4_storerbnew_ap(uint8_t v) +{ + void *ret; + asm volatile("{\n\t" + " r0 = %1\n\n" + " memb(%0 = ##data) = r0.new\n\t" + "}\n" + : "=r"(ret) + : "r"(v) + : "r0", "memory"); + return ret; +} + +static inline void *S4_storerhnew_ap(uint16_t v) +{ + void *ret; + asm volatile("{\n\t" + " r0 = %1\n\n" + " memh(%0 = ##data) = r0.new\n\t" + "}\n" + : "=r"(ret) + : "r"(v) + : "r0", "memory"); + return ret; +} + +static inline void *S4_storerinew_ap(uint32_t v) +{ + void *ret; + asm volatile("{\n\t" + " r0 = %1\n\n" + " memw(%0 = ##data) = r0.new\n\t" + "}\n" + : "=r"(ret) + : "r"(v) + : "r0", "memory"); + return ret; +} + +static inline void S4_storeirbt_io(void *p, int pred) +{ + asm volatile("p0 = cmp.eq(%0, #1)\n\t" + "if (p0) memb(%1+#4)=#27\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeirbf_io(void *p, int pred) +{ + asm volatile("p0 = cmp.eq(%0, #1)\n\t" + "if (!p0) memb(%1+#4)=#27\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeirbtnew_io(void *p, int pred) +{ + asm volatile("{\n\t" + " p0 = cmp.eq(%0, #1)\n\t" + " if (p0.new) memb(%1+#4)=#27\n\t" + "}\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeirbfnew_io(void *p, int pred) +{ + asm volatile("{\n\t" + " p0 = cmp.eq(%0, #1)\n\t" + " if (!p0.new) memb(%1+#4)=#27\n\t" + "}\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeirht_io(void *p, int pred) +{ + asm volatile("p0 = cmp.eq(%0, #1)\n\t" + "if (p0) memh(%1+#4)=#27\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeirhf_io(void *p, int pred) +{ + asm volatile("p0 = cmp.eq(%0, #1)\n\t" + "if (!p0) memh(%1+#4)=#27\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeirhtnew_io(void *p, int pred) +{ + asm volatile("{\n\t" + " p0 = cmp.eq(%0, #1)\n\t" + " if (p0.new) memh(%1+#4)=#27\n\t" + "}\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeirhfnew_io(void *p, int pred) +{ + asm volatile("{\n\t" + " p0 = cmp.eq(%0, #1)\n\t" + " if (!p0.new) memh(%1+#4)=#27\n\t" + "}\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeirit_io(void *p, int pred) +{ + asm volatile("p0 = cmp.eq(%0, #1)\n\t" + "if (p0) memw(%1+#4)=#27\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeirif_io(void *p, int pred) +{ + asm volatile("p0 = cmp.eq(%0, #1)\n\t" + "if (!p0) memw(%1+#4)=#27\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeiritnew_io(void *p, int pred) +{ + asm volatile("{\n\t" + " p0 = cmp.eq(%0, #1)\n\t" + " if (p0.new) memw(%1+#4)=#27\n\t" + "}\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +static inline void S4_storeirifnew_io(void *p, int pred) +{ + asm volatile("{\n\t" + " p0 = cmp.eq(%0, #1)\n\t" + " if (!p0.new) memw(%1+#4)=#27\n\t" + "}\n\t" + :: "r"(pred), "r"(p) + : "p0", "memory"); +} + +/* + * Test that compound-compare-jump is executed in 2 parts + * First we have to do all the compares in the packet and + * account for auto-anding. Then, we can do the predicated + * jump. + */ +static inline int cmpnd_cmp_jump(void) +{ + int retval; + asm ("r5 = #7\n\t" + "r6 = #9\n\t" + "{\n\t" + " p0 = cmp.eq(r5, #7)\n\t" + " if (p0.new) jump:nt 1f\n\t" + " p0 = cmp.eq(r6, #7)\n\t" + "}\n\t" + "%0 = #12\n\t" + "jump 2f\n\t" + "1:\n\t" + "%0 = #13\n\t" + "2:\n\t" + : "=r"(retval) :: "r5", "r6", "p0"); + return retval; +} + +static inline int test_clrtnew(int arg1, int old_val) +{ + int ret; + asm volatile("r5 = %2\n\t" + "{\n\t" + "p0 = cmp.eq(%1, #1)\n\t" + "if (p0.new) r5=#0\n\t" + "}\n\t" + "%0 = r5\n\t" + : "=r"(ret) + : "r"(arg1), "r"(old_val) + : "p0", "r5"); + return ret; +} + +int err; + +static void check(int val, int expect) +{ + if (val != expect) { + printf("ERROR: 0x%04x != 0x%04x\n", val, expect); + err++; + } +} + +uint32_t init[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; +uint32_t array[10]; + +uint32_t early_exit; + +/* + * Write this as a function because we can't guarantee the compiler will + * allocate a frame with just the SL2_return_tnew packet. + */ +static void SL2_return_tnew(int x); +asm ("SL2_return_tnew:\n\t" + " allocframe(#0)\n\t" + " r1 = #1\n\t" + " memw(##early_exit) = r1\n\t" + " {\n\t" + " p0 = cmp.eq(r0, #1)\n\t" + " if (p0.new) dealloc_return:nt\n\t" /* SL2_return_tnew */ + " }\n\t" + " r1 = #0\n\t" + " memw(##early_exit) = r1\n\t" + " dealloc_return\n\t" + ); + +static long long creg_pair(int x, int y) +{ + long long retval; + asm ("m0 = %1\n\t" + "m1 = %2\n\t" + "%0 = c7:6\n\t" + : "=r"(retval) : "r"(x), "r"(y) : "m0", "m1"); + return retval; +} + +int main() +{ + + memcpy(array, init, sizeof(array)); + S4_storerhnew_rr(array, 4, 0xffff); + check(array[4], 0xffff); + + data = ~0; + check((uint32_t)S4_storerbnew_ap(0x12), (uint32_t)&data); + check(data, 0xffffff12); + + data = ~0; + check((uint32_t)S4_storerhnew_ap(0x1234), (uint32_t)&data); + check(data, 0xffff1234); + + data = ~0; + check((uint32_t)S4_storerinew_ap(0x12345678), (uint32_t)&data); + check(data, 0x12345678); + + /* Byte */ + memcpy(array, init, sizeof(array)); + S4_storeirbt_io(&array[1], 1); + check(array[2], 27); + S4_storeirbt_io(&array[2], 0); + check(array[3], 3); + + memcpy(array, init, sizeof(array)); + S4_storeirbf_io(&array[3], 0); + check(array[4], 27); + S4_storeirbf_io(&array[4], 1); + check(array[5], 5); + + memcpy(array, init, sizeof(array)); + S4_storeirbtnew_io(&array[5], 1); + check(array[6], 27); + S4_storeirbtnew_io(&array[6], 0); + check(array[7], 7); + + memcpy(array, init, sizeof(array)); + S4_storeirbfnew_io(&array[7], 0); + check(array[8], 27); + S4_storeirbfnew_io(&array[8], 1); + check(array[9], 9); + + /* Half word */ + memcpy(array, init, sizeof(array)); + S4_storeirht_io(&array[1], 1); + check(array[2], 27); + S4_storeirht_io(&array[2], 0); + check(array[3], 3); + + memcpy(array, init, sizeof(array)); + S4_storeirhf_io(&array[3], 0); + check(array[4], 27); + S4_storeirhf_io(&array[4], 1); + check(array[5], 5); + + memcpy(array, init, sizeof(array)); + S4_storeirhtnew_io(&array[5], 1); + check(array[6], 27); + S4_storeirhtnew_io(&array[6], 0); + check(array[7], 7); + + memcpy(array, init, sizeof(array)); + S4_storeirhfnew_io(&array[7], 0); + check(array[8], 27); + S4_storeirhfnew_io(&array[8], 1); + check(array[9], 9); + + /* Word */ + memcpy(array, init, sizeof(array)); + S4_storeirit_io(&array[1], 1); + check(array[2], 27); + S4_storeirit_io(&array[2], 0); + check(array[3], 3); + + memcpy(array, init, sizeof(array)); + S4_storeirif_io(&array[3], 0); + check(array[4], 27); + S4_storeirif_io(&array[4], 1); + check(array[5], 5); + + memcpy(array, init, sizeof(array)); + S4_storeiritnew_io(&array[5], 1); + check(array[6], 27); + S4_storeiritnew_io(&array[6], 0); + check(array[7], 7); + + memcpy(array, init, sizeof(array)); + S4_storeirifnew_io(&array[7], 0); + check(array[8], 27); + S4_storeirifnew_io(&array[8], 1); + check(array[9], 9); + + int x = cmpnd_cmp_jump(); + check(x, 12); + + SL2_return_tnew(0); + check(early_exit, 0); + SL2_return_tnew(1); + check(early_exit, 1); + + long long pair = creg_pair(5, 7); + check((int)pair, 5); + check((int)(pair >> 32), 7); + + int res = test_clrtnew(1, 7); + check(res, 0); + res = test_clrtnew(2, 7); + check(res, 7); + + puts(err ? "FAIL" : "PASS"); + return err; +} diff --git a/tests/tcg/hexagon/preg_alias.c b/tests/tcg/hexagon/preg_alias.c new file mode 100644 index 0000000000..0cac469b78 --- /dev/null +++ b/tests/tcg/hexagon/preg_alias.c @@ -0,0 +1,169 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include + +static inline int preg_alias(int v0, int v1, int v2, int v3) +{ + int ret; + asm volatile("p0 = %1\n\t" + "p1 = %2\n\t" + "p2 = %3\n\t" + "p3 = %4\n\t" + "%0 = C4\n" + : "=r"(ret) + : "r"(v0), "r"(v1), "r"(v2), "r"(v3) + : "p0", "p1", "p2", "p3"); + return ret; +} + +static inline int preg_alias_pair(int v0, int v1, int v2, int v3) +{ + long long c54; + asm volatile("p0 = %1\n\t" + "p1 = %2\n\t" + "p2 = %3\n\t" + "p3 = %4\n\t" + "%0 = C5:4\n" + : "=r"(c54) + : "r"(v0), "r"(v1), "r"(v2), "r"(v3) + : "p0", "p1", "p2", "p3"); + return (int)c54; +} + +typedef union { + int creg; + struct { + unsigned char p0; + unsigned char p1; + unsigned char p2; + unsigned char p3; + } pregs; +} PRegs; + +static inline void creg_alias(int cval, PRegs *pregs) +{ + unsigned char val; + asm volatile("c4 = %0" : : "r"(cval)); + + asm volatile("%0 = p0" : "=r"(val)); + pregs->pregs.p0 = val; + asm volatile("%0 = p1" : "=r"(val)); + pregs->pregs.p1 = val; + asm volatile("%0 = p2" : "=r"(val)); + pregs->pregs.p2 = val; + asm volatile("%0 = p3" : "=r"(val)); + pregs->pregs.p3 = val; +} + +int err; + +static void check(int val, int expect) +{ + if (val != expect) { + printf("ERROR: 0x%08x != 0x%08x\n", val, expect); + err++; + } +} + +static inline void creg_alias_pair(unsigned int cval, PRegs *pregs) +{ + unsigned long long cval_pair = (0xdeadbeefULL << 32) | cval; + unsigned char val; + int c5; + asm volatile("c5:4 = %0" : : "r"(cval_pair)); + + asm volatile("%0 = p0" : "=r"(val)); + pregs->pregs.p0 = val; + asm volatile("%0 = p1" : "=r"(val)); + pregs->pregs.p1 = val; + asm volatile("%0 = p2" : "=r"(val)); + pregs->pregs.p2 = val; + asm volatile("%0 = p3" : "=r"(val)); + pregs->pregs.p3 = val; + asm volatile("%0 = c5" : "=r"(c5)); + check(c5, 0xdeadbeef); +} + +int main() +{ + int c4; + PRegs pregs; + + c4 = preg_alias(0xff, 0x00, 0xff, 0x00); + check(c4, 0x00ff00ff); + c4 = preg_alias(0xff, 0x00, 0x00, 0x00); + check(c4, 0x000000ff); + c4 = preg_alias(0x00, 0xff, 0x00, 0x00); + check(c4, 0x0000ff00); + c4 = preg_alias(0x00, 0x00, 0xff, 0x00); + check(c4, 0x00ff0000); + c4 = preg_alias(0x00, 0x00, 0x00, 0xff); + check(c4, 0xff000000); + c4 = preg_alias(0xff, 0xff, 0xff, 0xff); + check(c4, 0xffffffff); + + c4 = preg_alias_pair(0xff, 0x00, 0xff, 0x00); + check(c4, 0x00ff00ff); + c4 = preg_alias_pair(0xff, 0x00, 0x00, 0x00); + check(c4, 0x000000ff); + c4 = preg_alias_pair(0x00, 0xff, 0x00, 0x00); + check(c4, 0x0000ff00); + c4 = preg_alias_pair(0x00, 0x00, 0xff, 0x00); + check(c4, 0x00ff0000); + c4 = preg_alias_pair(0x00, 0x00, 0x00, 0xff); + check(c4, 0xff000000); + c4 = preg_alias_pair(0xff, 0xff, 0xff, 0xff); + check(c4, 0xffffffff); + + creg_alias(0x00ff00ff, &pregs); + check(pregs.creg, 0x00ff00ff); + creg_alias(0x00ffff00, &pregs); + check(pregs.creg, 0x00ffff00); + creg_alias(0x00000000, &pregs); + check(pregs.creg, 0x00000000); + creg_alias(0xff000000, &pregs); + check(pregs.creg, 0xff000000); + creg_alias(0x00ff0000, &pregs); + check(pregs.creg, 0x00ff0000); + creg_alias(0x0000ff00, &pregs); + check(pregs.creg, 0x0000ff00); + creg_alias(0x000000ff, &pregs); + check(pregs.creg, 0x000000ff); + creg_alias(0xffffffff, &pregs); + check(pregs.creg, 0xffffffff); + + creg_alias_pair(0x00ff00ff, &pregs); + check(pregs.creg, 0x00ff00ff); + creg_alias_pair(0x00ffff00, &pregs); + check(pregs.creg, 0x00ffff00); + creg_alias_pair(0x00000000, &pregs); + check(pregs.creg, 0x00000000); + creg_alias_pair(0xff000000, &pregs); + check(pregs.creg, 0xff000000); + creg_alias_pair(0x00ff0000, &pregs); + check(pregs.creg, 0x00ff0000); + creg_alias_pair(0x0000ff00, &pregs); + check(pregs.creg, 0x0000ff00); + creg_alias_pair(0x000000ff, &pregs); + check(pregs.creg, 0x000000ff); + creg_alias_pair(0xffffffff, &pregs); + check(pregs.creg, 0xffffffff); + + puts(err ? "FAIL" : "PASS"); + return err; +} diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target index 10b7c84813..a54e3c7503 100644 --- a/tests/tcg/hexagon/Makefile.target +++ b/tests/tcg/hexagon/Makefile.target @@ -28,3 +28,18 @@ endif CFLAGS += -Wno-incompatible-pointer-types -Wno-undefined-internal + +HEX_SRC=$(SRC_PATH)/tests/tcg/hexagon +VPATH += $(HEX_SRC) + +first: $(HEX_SRC)/first.S + $(CC) -static -mv67 -nostdlib $^ -o $@ + +HEX_TESTS = first +HEX_TESTS += misc +HEX_TESTS += preg_alias +HEX_TESTS += dual_stores +HEX_TESTS += mem_noshuf +HEX_TESTS += atomics + +TESTS += $(HEX_TESTS) diff --git a/tests/tcg/hexagon/first.S b/tests/tcg/hexagon/first.S new file mode 100644 index 0000000000..e9f2d963ec --- /dev/null +++ b/tests/tcg/hexagon/first.S @@ -0,0 +1,56 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#define SYS_write 64 +#define SYS_exit_group 94 +#define SYS_exit 93 + +#define FD_STDOUT 1 + + .type str,@object + .section .rodata +str: + .string "Hello!\n" + .size str, 8 + +.text +.global _start +_start: + r6 = #SYS_write + r0 = #FD_STDOUT + r1 = ##str + r2 = #7 + trap0(#1) + + r0 = #0 + r6 = #SYS_exit_group + trap0(#1) + +.section ".note.ABI-tag", "a" +.align 4 +.long 1f - 0f /* name length */ +.long 3f - 2f /* data length */ +.long 1 /* note type */ + +/* + * vendor name seems like this should be MUSL but lldb doesn't agree. + */ +0: .asciz "GNU" +1: .align 4 +2: .long 0 /* linux */ + .long 3,0,0 +3: .align 4 From patchwork Wed Feb 17 23:40:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384200 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3232863jao; Wed, 17 Feb 2021 16:09:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJwQ0y96dkEgVGv6DNZRi8VdCYfSGPK7KUxfjWPOUdZ+djEALlOFcoZ5bGQJgYflGq66Ds9X X-Received: by 2002:a25:b745:: with SMTP id e5mr3031814ybm.518.1613606980845; Wed, 17 Feb 2021 16:09:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606980; cv=none; d=google.com; s=arc-20160816; b=RL/szGBuFYKpHl4bEwSzznLa+ok326RwCakIlX1QGT711UzBUYTWDgxVMdecf3NzTu I82GEPK/bO96l5RKiJuvqJAyjcOwzLKW92w1zgDwaZ/HKDMHX2+heuMrEFOT/K0AMGHj jYHFhMQNgH5J99y+M0ofx9Dvb96hAZrHP1ocVsOHvfPo7l8L78QTUq7FveEx4hx7nG4L o5ZoajNF3Pr9iiGMQ/07pJ8N9QIuoLwdu7r1GmF5fs42YP3Ym24vOxQAm7uGIi0677VA rXjLUZlaO3z0kapF77PU/eF8bBqYXF1DDpeUJJGh8GzWoFepID9XagX7s+guTTI8nVhV 5ndw== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=SLHfS+Gcj+KKjKVIhmB4FpKge7O6y5amgsSfjoU+Ky4=; b=Fdy6CfvDWepdq7fbRI4bBb6CHF0joi9lQ2jbug4o+dJLaJsf5ljXDMcD0qJFaML+lf VUv1phvf1N29C/ao083CLrvGnmz1jbt3Vn51sTckdZNHLHngROedEN6BZ7CDv3llUnLI Rp3BJ02n345nNQRGnATqoKUqa4iroDCahaIqZNRh5Kd1kAPtYjqkp9jM3UN6eNE65Kwf Kny12+Wc9tPeKV8G65LHLb1e0LIiV6Nvpt+2zg7eN5/3o5hqiqT3Mj3SzQAYlMWqO2e4 acOp3Lkw0/Jtu5sPn0R0XeXL3MVOYIg58QHiL0OFBUW0EUgYfxGbncnlZscty5Na2mYt BcUQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iisYvsSC; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 70si3896309ybf.432.2021.02.17.16.09.40 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 16:09:40 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iisYvsSC; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:59900 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWt2-00014G-C0 for patch@linaro.org; Wed, 17 Feb 2021 19:09:40 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51192) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWSD-0001Ce-6H for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:57 -0500 Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]:42336) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWS5-0004vU-AW for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:56 -0500 Received: by mail-pl1-x634.google.com with SMTP id s16so197357plr.9 for ; Wed, 17 Feb 2021 15:41:48 -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 :mime-version:content-transfer-encoding; bh=SLHfS+Gcj+KKjKVIhmB4FpKge7O6y5amgsSfjoU+Ky4=; b=iisYvsSCbxIHnI8GgCtddcc0tna0xnSI+1XXW/fCbovln2PVvYQ3t7jnwuVPIJT0Ly QZWEcW8E3x1n07OfTq3VAQyGPdfnOyJtMdP7gbudeOZGLNf1EPoe4U8vxbqF18Vi9O2D aUYtrtVsqSfiErN7RsUgSuVYGE67E+2F8HRuCKH+RP1g5yW9aT4o/3iohzQqq2+dQs0R OiR+47eSpqpZZaXsNoH/FCJRDy6S049Ti12WskuVXnHzVpu3fBOTkQvi/va3Lv2Rxymx ClPsHlvJKBPtEfCSbYtGqR2m7IjEjGhWrkicane4FMijJ1L24wE15sMGmKhgGFMZA5wC o0AA== 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:mime-version:content-transfer-encoding; bh=SLHfS+Gcj+KKjKVIhmB4FpKge7O6y5amgsSfjoU+Ky4=; b=Y2L6v+3n7Xey2mWuGMtwa8b4rB4pImWIakcsmcs3VVvudH66h8W8hl6T9yDk+T5MKt nyxE5SVTRz1o2r18UUzdQpnq4Nw+dEnS14yGzkrgU4p7GGMLAXQuK+syX4RQcTaRz8KY anwFZBtqheOLjVUdxt+gRgFwJYX1d6RoCTOl+OFMmrigJCiRYmxvmVyNZkM7q8W4S+Hk NkyIb3hASCnM45chASan85XqNb1Nxi2MIDD7yqYBo+0jAMNHQZEhTiEVcQO1naCTMSHT IlMNTFDxV0pbi77soWQlTRtFl5Dtg23nA9ZKUO3x94nkQy6YRgHfQioexvXVTWbD3jq0 gjqw== X-Gm-Message-State: AOAM533w03oj1K80G8XuSIxT8I559uBTKUtFWCDPfOc/bJrYgjsdsOCQ JNmMGV9KHNrfl55bFOIJX6DuZFaUMtLxlA== X-Received: by 2002:a17:90b:1495:: with SMTP id js21mr1195582pjb.127.1613605304373; Wed, 17 Feb 2021 15:41:44 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:43 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 34/35] Hexagon (tests/tcg/hexagon) TCG tests - floating point Date: Wed, 17 Feb 2021 15:40:22 -0800 Message-Id: <20210217234023.1742406-35-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::634; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x634.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-34-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- tests/tcg/hexagon/fpstuff.c | 370 ++++++++++++++++++++++++++++++ tests/tcg/hexagon/Makefile.target | 1 + 2 files changed, 371 insertions(+) create mode 100644 tests/tcg/hexagon/fpstuff.c -- 2.25.1 diff --git a/tests/tcg/hexagon/fpstuff.c b/tests/tcg/hexagon/fpstuff.c new file mode 100644 index 0000000000..e4f1a0eeb4 --- /dev/null +++ b/tests/tcg/hexagon/fpstuff.c @@ -0,0 +1,370 @@ +/* + * Copyright(c) 2020-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * This test checks various FP operations performed on Hexagon + */ + +#include + +const int FPINVF_BIT = 1; /* Invalid */ +const int FPINVF = 1 << FPINVF_BIT; +const int FPDBZF_BIT = 2; /* Divide by zero */ +const int FPDBZF = 1 << FPDBZF_BIT; +const int FPOVFF_BIT = 3; /* Overflow */ +const int FPOVFF = 1 << FPOVFF_BIT; +const int FPUNFF_BIT = 4; /* Underflow */ +const int FPUNFF = 1 << FPUNFF_BIT; +const int FPINPF_BIT = 5; /* Inexact */ +const int FPINPF = 1 << FPINPF_BIT; + +const int SF_ZERO = 0x00000000; +const int SF_NaN = 0x7fc00000; +const int SF_NaN_special = 0x7f800001; +const int SF_ANY = 0x3f800000; +const int SF_HEX_NAN = 0xffffffff; + +const long long DF_NaN = 0x7ff8000000000000ULL; +const long long DF_ANY = 0x3f80000000000000ULL; +const long long DF_HEX_NAN = 0xffffffffffffffffULL; + +int err; + +#define CLEAR_FPSTATUS \ + "r2 = usr\n\t" \ + "r2 = clrbit(r2, #1)\n\t" \ + "r2 = clrbit(r2, #2)\n\t" \ + "r2 = clrbit(r2, #3)\n\t" \ + "r2 = clrbit(r2, #4)\n\t" \ + "r2 = clrbit(r2, #5)\n\t" \ + "usr = r2\n\t" + +static void check_fpstatus_bit(int usr, int expect, int flag, const char *n) +{ + int bit = 1 << flag; + if ((usr & bit) != (expect & bit)) { + printf("ERROR %s: usr = %d, expect = %d\n", n, + (usr >> flag) & 1, (expect >> flag) & 1); + err++; + } +} + +static void check_fpstatus(int usr, int expect) +{ + check_fpstatus_bit(usr, expect, FPINVF_BIT, "Invalid"); + check_fpstatus_bit(usr, expect, FPDBZF_BIT, "Div by zero"); + check_fpstatus_bit(usr, expect, FPOVFF_BIT, "Overflow"); + check_fpstatus_bit(usr, expect, FPUNFF_BIT, "Underflow"); + check_fpstatus_bit(usr, expect, FPINPF_BIT, "Inexact"); +} + +static void check32(int val, int expect) +{ + if (val != expect) { + printf("ERROR: 0x%x != 0x%x\n", val, expect); + err++; + } +} +static void check64(unsigned long long val, unsigned long long expect) +{ + if (val != expect) { + printf("ERROR: 0x%llx != 0x%llx\n", val, expect); + err++; + } +} + +static void check_compare_exception(void) +{ + int cmp; + int usr; + + /* Check that FP compares are quiet (don't raise any execptions) */ + asm (CLEAR_FPSTATUS + "p0 = sfcmp.eq(%2, %3)\n\t" + "%0 = p0\n\t" + "%1 = usr\n\t" + : "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "p0", "usr"); + check32(cmp, 0); + check_fpstatus(usr, 0); + + asm (CLEAR_FPSTATUS + "p0 = sfcmp.gt(%2, %3)\n\t" + "%0 = p0\n\t" + "%1 = usr\n\t" + : "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "p0", "usr"); + check32(cmp, 0); + check_fpstatus(usr, 0); + + asm (CLEAR_FPSTATUS + "p0 = sfcmp.ge(%2, %3)\n\t" + "%0 = p0\n\t" + "%1 = usr\n\t" + : "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "p0", "usr"); + check32(cmp, 0); + check_fpstatus(usr, 0); + + asm (CLEAR_FPSTATUS + "p0 = dfcmp.eq(%2, %3)\n\t" + "%0 = p0\n\t" + "%1 = usr\n\t" + : "=r"(cmp), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) + : "r2", "p0", "usr"); + check32(cmp, 0); + check_fpstatus(usr, 0); + + asm (CLEAR_FPSTATUS + "p0 = dfcmp.gt(%2, %3)\n\t" + "%0 = p0\n\t" + "%1 = usr\n\t" + : "=r"(cmp), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) + : "r2", "p0", "usr"); + check32(cmp, 0); + check_fpstatus(usr, 0); + + asm (CLEAR_FPSTATUS + "p0 = dfcmp.ge(%2, %3)\n\t" + "%0 = p0\n\t" + "%1 = usr\n\t" + : "=r"(cmp), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) + : "r2", "p0", "usr"); + check32(cmp, 0); + check_fpstatus(usr, 0); +} + +static void check_sfminmax(void) +{ + int minmax; + int usr; + + /* + * Execute sfmin/sfmax instructions with one operand as NaN + * Check that + * Result is the other operand + * Invalid bit in USR is not set + */ + asm (CLEAR_FPSTATUS + "%0 = sfmin(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "usr"); + check64(minmax, SF_ANY); + check_fpstatus(usr, 0); + + asm (CLEAR_FPSTATUS + "%0 = sfmax(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "usr"); + check64(minmax, SF_ANY); + check_fpstatus(usr, 0); + + /* + * Execute sfmin/sfmax instructions with both operands NaN + * Check that + * Result is SF_HEX_NAN + * Invalid bit in USR is set + */ + asm (CLEAR_FPSTATUS + "%0 = sfmin(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_NaN) + : "r2", "usr"); + check64(minmax, SF_HEX_NAN); + check_fpstatus(usr, 0); + + asm (CLEAR_FPSTATUS + "%0 = sfmax(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_NaN) + : "r2", "usr"); + check64(minmax, SF_HEX_NAN); + check_fpstatus(usr, 0); +} + +static void check_dfminmax(void) +{ + unsigned long long minmax; + int usr; + + /* + * Execute dfmin/dfmax instructions with one operand as NaN + * Check that + * Result is the other operand + * Invalid bit in USR is set + */ + asm (CLEAR_FPSTATUS + "%0 = dfmin(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(minmax), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) + : "r2", "usr"); + check64(minmax, DF_ANY); + check_fpstatus(usr, FPINVF); + + asm (CLEAR_FPSTATUS + "%0 = dfmax(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(minmax), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) + : "r2", "usr"); + check64(minmax, DF_ANY); + check_fpstatus(usr, FPINVF); + + /* + * Execute dfmin/dfmax instructions with both operands NaN + * Check that + * Result is DF_HEX_NAN + * Invalid bit in USR is set + */ + asm (CLEAR_FPSTATUS + "%0 = dfmin(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(minmax), "=r"(usr) : "r"(DF_NaN), "r"(DF_NaN) + : "r2", "usr"); + check64(minmax, DF_HEX_NAN); + check_fpstatus(usr, FPINVF); + + asm (CLEAR_FPSTATUS + "%0 = dfmax(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(minmax), "=r"(usr) : "r"(DF_NaN), "r"(DF_NaN) + : "r2", "usr"); + check64(minmax, DF_HEX_NAN); + check_fpstatus(usr, FPINVF); +} + +static void check_canonical_NaN(void) +{ + int sf_result; + unsigned long long df_result; + int usr; + + /* Check that each FP instruction properly returns SF_HEX_NAN/DF_HEX_NAN */ + asm(CLEAR_FPSTATUS + "%0 = sfadd(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "usr"); + check32(sf_result, SF_HEX_NAN); + check_fpstatus(usr, 0); + + asm(CLEAR_FPSTATUS + "%0 = sfsub(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "usr"); + check32(sf_result, SF_HEX_NAN); + check_fpstatus(usr, 0); + + asm(CLEAR_FPSTATUS + "%0 = sfmpy(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "usr"); + check32(sf_result, SF_HEX_NAN); + check_fpstatus(usr, 0); + + sf_result = SF_ZERO; + asm(CLEAR_FPSTATUS + "%0 += sfmpy(%2, %3)\n\t" + "%1 = usr\n\t" + : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "usr"); + check32(sf_result, SF_HEX_NAN); + check_fpstatus(usr, 0); + + sf_result = SF_ZERO; + asm(CLEAR_FPSTATUS + "p0 = !cmp.eq(r0, r0)\n\t" + "%0 += sfmpy(%2, %3, p0):scale\n\t" + "%1 = usr\n\t" + : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "usr", "p0"); + check32(sf_result, SF_HEX_NAN); + check_fpstatus(usr, 0); + + sf_result = SF_ZERO; + asm(CLEAR_FPSTATUS + "%0 -= sfmpy(%2, %3)\n\t" + "%1 = usr\n\t" + : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "usr"); + check32(sf_result, SF_HEX_NAN); + check_fpstatus(usr, 0); + + sf_result = SF_ZERO; + asm(CLEAR_FPSTATUS + "%0 += sfmpy(%2, %3):lib\n\t" + "%1 = usr\n\t" + : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "usr"); + check32(sf_result, SF_HEX_NAN); + check_fpstatus(usr, 0); + + sf_result = SF_ZERO; + asm(CLEAR_FPSTATUS + "%0 -= sfmpy(%2, %3):lib\n\t" + "%1 = usr\n\t" + : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) + : "r2", "usr"); + check32(sf_result, SF_HEX_NAN); + check_fpstatus(usr, 0); + + asm(CLEAR_FPSTATUS + "%0 = convert_df2sf(%2)\n\t" + "%1 = usr\n\t" + : "=r"(sf_result), "=r"(usr) : "r"(DF_NaN) + : "r2", "usr"); + check32(sf_result, SF_HEX_NAN); + check_fpstatus(usr, 0); + + asm(CLEAR_FPSTATUS + "%0 = dfadd(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(df_result), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) + : "r2", "usr"); + check64(df_result, DF_HEX_NAN); + check_fpstatus(usr, 0); + + asm(CLEAR_FPSTATUS + "%0 = dfsub(%2, %3)\n\t" + "%1 = usr\n\t" + : "=r"(df_result), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) + : "r2", "usr"); + check64(df_result, DF_HEX_NAN); + check_fpstatus(usr, 0); + + asm(CLEAR_FPSTATUS + "%0 = convert_sf2df(%2)\n\t" + "%1 = usr\n\t" + : "=r"(df_result), "=r"(usr) : "r"(SF_NaN) + : "r2", "usr"); + check64(df_result, DF_HEX_NAN); + check_fpstatus(usr, 0); +} + +int main() +{ + check_compare_exception(); + check_sfminmax(); + check_dfminmax(); + check_canonical_NaN(); + + puts(err ? "FAIL" : "PASS"); + return err ? 1 : 0; +} diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target index a54e3c7503..616af697fe 100644 --- a/tests/tcg/hexagon/Makefile.target +++ b/tests/tcg/hexagon/Makefile.target @@ -41,5 +41,6 @@ HEX_TESTS += preg_alias HEX_TESTS += dual_stores HEX_TESTS += mem_noshuf HEX_TESTS += atomics +HEX_TESTS += fpstuff TESTS += $(HEX_TESTS) From patchwork Wed Feb 17 23:40:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 384189 Delivered-To: patch@linaro.org Received: by 2002:a02:c80e:0:0:0:0:0 with SMTP id p14csp3230125jao; Wed, 17 Feb 2021 16:04:49 -0800 (PST) X-Google-Smtp-Source: ABdhPJwnaFAMlra7U/LHkha5Gcm5Runo6T2DqIkESkHWm55NrOAI6muksT9yeH9nQUNErKMLC2Ml X-Received: by 2002:a25:105:: with SMTP id 5mr2787741ybb.133.1613606689149; Wed, 17 Feb 2021 16:04:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613606689; cv=none; d=google.com; s=arc-20160816; b=bkLw4X0P6SswXxilSva1L+eM6cT+PAb1AtK7vH2Ue/UFiP0ULjAROevzT/qukCHFYA CE4US8kceuhU0lHbKWoXuh5UNjlvEIr/xKrTJW4KJeOGSYPw66RjRpsVsabOqmHPvldP 7KJ1b07AC52zRqY11PLjrZ9D/p1Xsylypp3V9bwTEIz3tMHxJGckVzQiMefyQWbRSLkZ Nc4KsPZlcz8jF9Mnc2NzUwIpr09BxLBcioLAFXGM1f5G6NPsE1AiqbRCw8T7zJP/37G7 +vNAMnq3t9kS6TQ/T3ODpCilU4vZwS5QMb5G81jh+/OV7CEzMv1ZQTIMEBU2UN1ci0/g mD+Q== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=wadihy0ZN45qBHR18cRkPDzIIFYhZQPkhTGr+p9Ixkg=; b=Yu3+T+wq+w108TpYUWAmHdk788z6/dXlWzQOjwdvI835ysAXtK0Y93VV5FUh2rSrRR 41sYQ4iUkjyvurKv7V/WAP2kVI4SwI47etO/MdBQpVVXWiau8h8g7xW+QsWJhYXk/211 7pLvLki/9YpoCYZ8FBugAe3sythAk97XoKxDkbccPh3qt2SPgD40xFnHkKItEngpEdSf jjZxxtX3sFYxT/ePgUmDpM1L9MjKa4+m7B35KpKK1cWzimNV8sIRwNmZUCUu1O/VJ3iH KJIcWvV3HigQT0d4sN0qmlmni5i5N7dFvYKwqL3ntPxr4g0clQIMNK2H2azPPgEdvu4N /pZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="ram42as/"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 8si3569616ybo.110.2021.02.17.16.04.49 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Feb 2021 16:04:49 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="ram42as/"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49022 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lCWoJ-0004d0-Eh for patch@linaro.org; Wed, 17 Feb 2021 19:04:47 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51172) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lCWS8-0001C2-Un for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:53 -0500 Received: from mail-pf1-x431.google.com ([2607:f8b0:4864:20::431]:42147) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lCWS3-0004vH-FQ for qemu-devel@nongnu.org; Wed, 17 Feb 2021 18:41:52 -0500 Received: by mail-pf1-x431.google.com with SMTP id w18so24825pfu.9 for ; Wed, 17 Feb 2021 15:41:47 -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 :mime-version:content-transfer-encoding; bh=wadihy0ZN45qBHR18cRkPDzIIFYhZQPkhTGr+p9Ixkg=; b=ram42as/Vb6drqiL1C5MOaTk1MwfLXGA86mzg8W5PrXNIVoJjzIYrKuq6hu79aQvQ6 slm8h7CFKtSXsGgiU9P3FqqYOoVpSTAh48dEDvtiUAjoQxB4WIcvEsk2sD8M5b5BI1LV 9NSyT9V8V8hOWSpPwGZNEwc+XgdiASrFERAvQSS5jfPBQ7582AEkLKqNNN3ubaqmDxJx nIJ5DbbxqlhzeAWKedXNWoPvRkoKd0mSOMtmKqMcULonj2jllbPoZLjl2t0iupB/wr8U j5xQI0t5fv+Q50ZbLyX7hVWmBO3BPC7IzdHXR+URcUOu820snof6yw0XpKefY04+Rb7Z 4THg== 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:mime-version:content-transfer-encoding; bh=wadihy0ZN45qBHR18cRkPDzIIFYhZQPkhTGr+p9Ixkg=; b=D9Usic6O4xdrYF6wIF/7h+vDmoAerYhYHuWXvZLfsVO25g/IuwCu17m5jjr9QAzkHT 9Ax5zSgvRmxRxqU3caEXpqOynKlgPinyoxrRS70QE30Gu28ccuvwrMaH8fe8nPPSqz7K BjIOjSkJyHVY1bo4kEGNb5Uw+G/JqmuR2hwf5x2f5U3nStiCER6JyIZYOmgP7plvd7Xm ko6b/yuRscDu6kPaubYldTluvs8+eAZcKH8j1w9vurpWf6ewHVymS2d2w4Y8YJyJbUYf IXnDRDL15U8XURXU9QyiMG00+KPwHpzg09EbOqczJkXjH6WTTukV+dt8axWVpU6taPgM SlVg== X-Gm-Message-State: AOAM531QjUHhWeIhjejU6lKRj6+3NbRYByx0alIJUoTh2ENpLQPa3kz8 weJu1pU1v2HxUXZ6uUt+jXNpkd0pFN40ZA== X-Received: by 2002:a63:7d13:: with SMTP id y19mr1507895pgc.369.1613605306107; Wed, 17 Feb 2021 15:41:46 -0800 (PST) Received: from localhost.localdomain (047-051-160-125.biz.spectrum.com. [47.51.160.125]) by smtp.gmail.com with ESMTPSA id c21sm3950355pgh.0.2021.02.17.15.41.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 15:41:45 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 35/35] Hexagon build infrastructure Date: Wed, 17 Feb 2021 15:40:23 -0800 Message-Id: <20210217234023.1742406-36-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210217234023.1742406-1-richard.henderson@linaro.org> References: <20210217234023.1742406-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::431; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Taylor Simpson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Taylor Simpson Add file to default-configs Add hexagon to meson.build Add hexagon to target/meson.build Add target/hexagon/meson.build Change scripts/qemu-binfmt-conf.sh We can build a hexagon-linux-user target and run programs on the Hexagon scalar core. With hexagon-linux-clang installed, "make check-tcg" will pass. Tested-by: Philippe Mathieu-Daudé Signed-off-by: Taylor Simpson Reviewed-by: Richard Henderson Message-Id: <1612763186-18161-35-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson --- .../targets/hexagon-linux-user.mak | 1 + meson.build | 1 + scripts/qemu-binfmt-conf.sh | 6 +- target/hexagon/meson.build | 193 ++++++++++++++++++ target/meson.build | 1 + 5 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 default-configs/targets/hexagon-linux-user.mak create mode 100644 target/hexagon/meson.build -- 2.25.1 diff --git a/default-configs/targets/hexagon-linux-user.mak b/default-configs/targets/hexagon-linux-user.mak new file mode 100644 index 0000000000..003ed0a408 --- /dev/null +++ b/default-configs/targets/hexagon-linux-user.mak @@ -0,0 +1 @@ +TARGET_ARCH=hexagon diff --git a/meson.build b/meson.build index a923f249d8..05a67c20d9 100644 --- a/meson.build +++ b/meson.build @@ -1188,6 +1188,7 @@ disassemblers = { 'arm' : ['CONFIG_ARM_DIS'], 'avr' : ['CONFIG_AVR_DIS'], 'cris' : ['CONFIG_CRIS_DIS'], + 'hexagon' : ['CONFIG_HEXAGON_DIS'], 'hppa' : ['CONFIG_HPPA_DIS'], 'i386' : ['CONFIG_I386_DIS'], 'x86_64' : ['CONFIG_I386_DIS'], diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh index 9f1580a91c..7b5d54b887 100755 --- a/scripts/qemu-binfmt-conf.sh +++ b/scripts/qemu-binfmt-conf.sh @@ -4,7 +4,7 @@ qemu_target_list="i386 i486 alpha arm armeb sparc sparc32plus sparc64 \ ppc ppc64 ppc64le m68k mips mipsel mipsn32 mipsn32el mips64 mips64el \ sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \ -microblaze microblazeel or1k x86_64" +microblaze microblazeel or1k x86_64 hexagon" i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00' i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff' @@ -136,6 +136,10 @@ or1k_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\ or1k_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff' or1k_family=or1k +hexagon_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xa4\x00' +hexagon_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff' +hexagon_family=hexagon + qemu_get_family() { cpu=${HOST_ARCH:-$(uname -m)} case "$cpu" in diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build new file mode 100644 index 0000000000..06f449da66 --- /dev/null +++ b/target/hexagon/meson.build @@ -0,0 +1,193 @@ +## +## Copyright(c) 2020-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see . +## + +hexagon_ss = ss.source_set() + +prog_python = import('python').find_installation('python3') + +hex_common_py = 'hex_common.py' +attribs_def = meson.current_source_dir() / 'attribs_def.h.inc' +gen_tcg_h = meson.current_source_dir() / 'gen_tcg.h' + +# +# Step 1 +# We use a C program to create semantics_generated.pyinc +# +gen_semantics = executable( + 'gen_semantics', + 'gen_semantics.c', + native: true, build_by_default: false) + +semantics_generated = custom_target( + 'semantics_generated.pyinc', + output: 'semantics_generated.pyinc', + input: gen_semantics, + command: ['@INPUT@', '@OUTPUT@'], +) +hexagon_ss.add(semantics_generated) + +# +# Step 2 +# We use Python scripts to generate the following files +# shortcode_generated.h.inc +# helper_protos_generated.h.inc +# tcg_funcs_generated.c.inc +# tcg_func_table_generated.c.inc +# helper_funcs_generated.c.inc +# printinsn_generated.h.inc +# op_regs_generated.h.inc +# op_attribs_generated.h.inc +# opcodes_def_generated.h.inc +# +shortcode_generated = custom_target( + 'shortcode_generated.h.inc', + output: 'shortcode_generated.h.inc', + input: 'gen_shortcode.py', + depends: [semantics_generated], + depend_files: [hex_common_py, attribs_def], + command: [prog_python, '@INPUT@', semantics_generated, attribs_def, '@OUTPUT@'], +) +hexagon_ss.add(shortcode_generated) + +helper_protos_generated = custom_target( + 'helper_protos_generated.h.inc', + output: 'helper_protos_generated.h.inc', + input: 'gen_helper_protos.py', + depends: [semantics_generated], + depend_files: [hex_common_py, attribs_def, gen_tcg_h], + command: [prog_python, '@INPUT@', semantics_generated, attribs_def, gen_tcg_h, '@OUTPUT@'], +) +hexagon_ss.add(helper_protos_generated) + +tcg_funcs_generated = custom_target( + 'tcg_funcs_generated.c.inc', + output: 'tcg_funcs_generated.c.inc', + input: 'gen_tcg_funcs.py', + depends: [semantics_generated], + depend_files: [hex_common_py, attribs_def, gen_tcg_h], + command: [prog_python, '@INPUT@', semantics_generated, attribs_def, gen_tcg_h, '@OUTPUT@'], +) +hexagon_ss.add(tcg_funcs_generated) + +tcg_func_table_generated = custom_target( + 'tcg_func_table_generated.c.inc', + output: 'tcg_func_table_generated.c.inc', + input: 'gen_tcg_func_table.py', + depends: [semantics_generated], + depend_files: [hex_common_py, attribs_def], + command: [prog_python, '@INPUT@', semantics_generated, attribs_def, '@OUTPUT@'], +) +hexagon_ss.add(tcg_func_table_generated) + +helper_funcs_generated = custom_target( + 'helper_funcs_generated.c.inc', + output: 'helper_funcs_generated.c.inc', + input: 'gen_helper_funcs.py', + depends: [semantics_generated], + depend_files: [hex_common_py, attribs_def, gen_tcg_h], + command: [prog_python, '@INPUT@', semantics_generated, attribs_def, gen_tcg_h, '@OUTPUT@'], +) +hexagon_ss.add(helper_funcs_generated) + +printinsn_generated = custom_target( + 'printinsn_generated.h.inc', + output: 'printinsn_generated.h.inc', + input: 'gen_printinsn.py', + depends: [semantics_generated], + depend_files: [hex_common_py, attribs_def], + command: [prog_python, '@INPUT@', semantics_generated, attribs_def, '@OUTPUT@'], +) +hexagon_ss.add(printinsn_generated) + +op_regs_generated = custom_target( + 'op_regs_generated.h.inc', + output: 'op_regs_generated.h.inc', + input: 'gen_op_regs.py', + depends: [semantics_generated], + depend_files: [hex_common_py, attribs_def], + command: [prog_python, '@INPUT@', semantics_generated, attribs_def, '@OUTPUT@'], +) +hexagon_ss.add(op_regs_generated) + +op_attribs_generated = custom_target( + 'op_attribs_generated.h.inc', + output: 'op_attribs_generated.h.inc', + input: 'gen_op_attribs.py', + depends: [semantics_generated], + depend_files: [hex_common_py, attribs_def], + command: [prog_python, '@INPUT@', semantics_generated, attribs_def, '@OUTPUT@'], +) +hexagon_ss.add(op_attribs_generated) + +opcodes_def_generated = custom_target( + 'opcodes_def_generated.h.inc', + output: 'opcodes_def_generated.h.inc', + input: 'gen_opcodes_def.py', + depends: [semantics_generated], + depend_files: [hex_common_py, attribs_def], + command: [prog_python, '@INPUT@', semantics_generated, attribs_def, '@OUTPUT@'], +) +hexagon_ss.add(opcodes_def_generated) + +# +# Step 3 +# We use a C program to create iset.py which is imported into dectree.py +# to create the decode tree +# +gen_dectree_import = executable( + 'gen_dectree_import', + 'gen_dectree_import.c', opcodes_def_generated, op_regs_generated, + native: true, build_by_default: false) + +iset_py = custom_target( + 'iset.py', + output: 'iset.py', + input: gen_dectree_import, + command: ['@INPUT@', '@OUTPUT@'], +) +hexagon_ss.add(iset_py) + +# +# Step 4 +# We use the dectree.py script to generate the decode tree header file +# +dectree_generated = custom_target( + 'dectree_generated.h.inc', + output: 'dectree_generated.h.inc', + input: 'dectree.py', + depends: [iset_py], + command: ['PYTHONPATH=' + meson.current_build_dir(), '@INPUT@', '@OUTPUT@'], +) +hexagon_ss.add(dectree_generated) + +hexagon_ss.add(files( + 'cpu.c', + 'translate.c', + 'op_helper.c', + 'gdbstub.c', + 'genptr.c', + 'reg_fields.c', + 'decode.c', + 'iclass.c', + 'opcodes.c', + 'printinsn.c', + 'arch.c', + 'fma_emu.c', + 'conv_emu.c', +)) + +target_arch += {'hexagon': hexagon_ss} diff --git a/target/meson.build b/target/meson.build index 9f0ae93b75..c35c1e9d34 100644 --- a/target/meson.build +++ b/target/meson.build @@ -2,6 +2,7 @@ subdir('alpha') subdir('arm') subdir('avr') subdir('cris') +subdir('hexagon') subdir('hppa') subdir('i386') subdir('lm32')