{"id":2235096,"url":"http://patchwork.ozlabs.org/api/1.2/patches/2235096/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260508-mips-octeon-missing-insns-v2-v3-28-bcbec96357d9@gmail.com/","project":{"id":14,"url":"http://patchwork.ozlabs.org/api/1.2/projects/14/?format=json","name":"QEMU Development","link_name":"qemu-devel","list_id":"qemu-devel.nongnu.org","list_email":"qemu-devel@nongnu.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260508-mips-octeon-missing-insns-v2-v3-28-bcbec96357d9@gmail.com>","list_archive_url":null,"date":"2026-05-08T15:12:28","name":"[v3,28/32] target/mips: add Octeon SHA3 crypto support","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"776b6b342bd2309b81b97ffda71028147822a0f7","submitter":{"id":66301,"url":"http://patchwork.ozlabs.org/api/1.2/people/66301/?format=json","name":"James Hilliard","email":"james.hilliard1@gmail.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260508-mips-octeon-missing-insns-v2-v3-28-bcbec96357d9@gmail.com/mbox/","series":[{"id":503407,"url":"http://patchwork.ozlabs.org/api/1.2/series/503407/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/list/?series=503407","date":"2026-05-08T15:12:00","name":"target/mips: add missing Octeon user-mode support","version":3,"mbox":"http://patchwork.ozlabs.org/series/503407/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2235096/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2235096/checks/","tags":{},"related":[],"headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=QZDsMO3X;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4gBt2m6wBkz1yKd\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 09 May 2026 01:14:56 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wLMuB-000423-LA; Fri, 08 May 2026 11:14:19 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <james.hilliard1@gmail.com>)\n id 1wLMtO-0002ja-Ck\n for qemu-devel@nongnu.org; Fri, 08 May 2026 11:13:30 -0400","from mail-oi1-x22a.google.com ([2607:f8b0:4864:20::22a])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <james.hilliard1@gmail.com>)\n id 1wLMtL-0001mo-2Q\n for qemu-devel@nongnu.org; Fri, 08 May 2026 11:13:29 -0400","by mail-oi1-x22a.google.com with SMTP id\n 5614622812f47-479eb8bcacbso1319727b6e.1\n for <qemu-devel@nongnu.org>; Fri, 08 May 2026 08:13:26 -0700 (PDT)","from\n 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa\n (71-218-113-237.hlrn.qwest.net. [71.218.113.237])\n by smtp.gmail.com with ESMTPSA id\n 586e51a60fabf-43557109b7dsm1897904fac.5.2026.05.08.08.13.24\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 08 May 2026 08:13:24 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1778253206; x=1778858006; darn=nongnu.org;\n h=cc:to:in-reply-to:references:message-id:content-transfer-encoding\n :mime-version:subject:date:from:from:to:cc:subject:date:message-id\n :reply-to; bh=6OIjhNAc1qSWjldhaWCDmAlnLGPwF92RMvqkn/pHPU8=;\n b=QZDsMO3XyVyHhPQC+bMyJ9BvLv0vBl5AVos80qkqsymnjux1PXP4EOYSXXCujZFIua\n 4xIMBJldSeew8ZX8w0wKqVgfkVyrhgYZJYSRZ+1QnLKTZr2GoF2fj21RSWqlZGba4J2w\n ktKpG9kG4gC4zYGtFnXm/VuyexPmiNJzFWR5kardygVXVLDG2fkSdmxLyewA3ByxLPsH\n MsmstYqDQ38FhgRQc7TUNDyviVSC7pLIvOTgxeSMOja5YDUJt75pRa0VQB9sCjPwlYN4\n 9uencSW53tsVzVIDgnw4bt5QtBubINvrcwNS1Wk8pw31o+vnNqYRcW5/dn2BFAfGbeAS\n dlqg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1778253206; x=1778858006;\n h=cc:to:in-reply-to:references:message-id:content-transfer-encoding\n :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to\n :cc:subject:date:message-id:reply-to;\n bh=6OIjhNAc1qSWjldhaWCDmAlnLGPwF92RMvqkn/pHPU8=;\n b=YiR/rardBxagVHGa4+kBCO9qSW3MQf+G7uBn2PB+p8AKnnhOuONer3ZImT0Z9ANYS0\n l7zyPbQnVcrZmYRvmDj9G5xNsB+IVPehqqLdQkVlVMXnEXNP3Mrf4r6SryUpsziCz54X\n 4dPXSkmHsYGLOXMGKgW8B59FMqRvKMZW4Zm6wAx0mLSNA/FAkaFaL8VyTaYI+ivyuata\n QOAUp1Y/IJ39sEsJT0Q9LwqhtDzhKnVS8tfz3WZDArYzvycLezp7msPyhjfgGrWndG6g\n dMZ4AoIYTDjmbTCnilhJ1HOzZGOGbfQ7vdLCgWXlM6T8v/EGrSKlrHH6Mvvan/+38XQp\n 9awQ==","X-Gm-Message-State":"AOJu0Yy5RNItxM+xJdFxzWA1QudQeqqMvQ7T8MZqQaIhqM0WghZVxkTY\n jtITpmHsEFCQEzNnIsWZ2WV3E9lhjRnB1kIjbXaqgJWL90aukspx8QIJPLG0xw==","X-Gm-Gg":"AeBDietIQfK5KW2vhV5XHhrAjlimIq+GOUp0qiz3zPoOh183ficsHaFMYINIPSW6S07\n nNMv+137YS4VZ3/tzmgwVJuyYytkiHdZQ01dwgTpoNMgY06xRr2igvSWMtVTXXGZd40CnnKkv3l\n wWFSlaih0ybx3swVOZmnEHDzvLklVKhCxYKepp3bN+5GLIrHpwNWM73i5QQMUAp4dUXknYCjBcz\n 3tMScNomrN1OjyK8LnP2H4BpVV8ueN11+7M1tTnprtgERLegHGTKKgoJrfE31jpvN6e0XKeQ0Ii\n Jzotvpm0hYFxG6ubm/P2BeGEAS5m1As4duCoNaY6CkSTmu7Z28RYCNVxf6fpugcSIwd/dSv8J03\n T6u9JWX+R+bMhFoRth2ljCpz2rYlhStKBAHJuCUpoUkQUNQThNp0y0N4qr8O+jGbcnBclXKFuIo\n YzgW4aUd9ZtDjPHeMljFEWghZtJQxKQdjCZTft7U+FQkxrwW5QeDQKXk0TpCqyCfI8GKyaHvNL3\n 8L9CJU63fuLLJnh2aFqnJwM1k/z33GfErfFMKyuf8WYCz6V7y4sMhQl0XQ0WtRWvRuyboajb6am\n Uv1H+J9WXY7LeRv1riK3Iu0uBo/1gVoXOvKc26C/fZ0yF6m4Liyd6b705RXDdRWsUTcHQD5oK6X\n j6RQwfA==","X-Received":"by 2002:a05:6808:e64a:b0:475:be6f:aa with SMTP id\n 5614622812f47-480420c5dffmr5889149b6e.19.1778253205571;\n Fri, 08 May 2026 08:13:25 -0700 (PDT)","From":"James Hilliard <james.hilliard1@gmail.com>","Date":"Fri, 08 May 2026 09:12:28 -0600","Subject":"[PATCH v3 28/32] target/mips: add Octeon SHA3 crypto support","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"8bit","Message-Id":"\n <20260508-mips-octeon-missing-insns-v2-v3-28-bcbec96357d9@gmail.com>","References":"\n <20260508-mips-octeon-missing-insns-v2-v3-0-bcbec96357d9@gmail.com>","In-Reply-To":"\n <20260508-mips-octeon-missing-insns-v2-v3-0-bcbec96357d9@gmail.com>","To":"qemu-devel@nongnu.org","Cc":"Laurent Vivier <laurent@vivier.eu>, =?utf-8?q?Philippe_Mathieu-Daud?=\n\t=?utf-8?q?=C3=A9?= <philmd@linaro.org>,\n  Aurelien Jarno <aurelien@aurel32.net>,\n  Jiaxun Yang <jiaxun.yang@flygoat.com>,\n  Aleksandar Rikalo <arikalo@gmail.com>, Huacai Chen <chenhuacai@kernel.org>,\n  James Hilliard <james.hilliard1@gmail.com>, Helge Deller <deller@gmx.de>,\n  Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>,\n  Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>","X-Mailer":"b4 0.15.2","Received-SPF":"pass client-ip=2607:f8b0:4864:20::22a;\n envelope-from=james.hilliard1@gmail.com; helo=mail-oi1-x22a.google.com","X-Spam_score_int":"-17","X-Spam_score":"-1.8","X-Spam_bar":"-","X-Spam_report":"(-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n 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.29","Precedence":"list","List-Id":"qemu development <qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"},"content":"Add the Octeon SHA3 register window and STARTOP selector.\n\nKeep the shared HSH/SHA3/SHA512 write path coherent, then model the\ndedicated 25-lane Keccak state and the Keccak-f[1600] permutation so the\nCOP2 SHA3 interface follows the hardware behaviour.\n\nSigned-off-by: James Hilliard <james.hilliard1@gmail.com>\n---\nChanges v1 -> v2:\n  - Use switch ranges and g_assert_not_reached() for SHA3 selector\n    position decoding.  (suggested by Philippe Mathieu-Daudé)\n  - Add selector dispatch updates in octeon_translate.c after moving\n    COP2 decode out of translate.c.  (suggested by Philippe\n    Mathieu-Daudé)\n---\n target/mips/cpu.h                  |  22 +++++\n target/mips/system/machine.c       |   1 +\n target/mips/tcg/octeon_crypto.c    | 171 +++++++++++++++++++++++++++++++++++++\n target/mips/tcg/octeon_translate.c |  22 +++++\n 4 files changed, 216 insertions(+)","diff":"diff --git a/target/mips/cpu.h b/target/mips/cpu.h\nindex 2457b253ae..4f136e87f4 100644\n--- a/target/mips/cpu.h\n+++ b/target/mips/cpu.h\n@@ -533,6 +533,7 @@ typedef enum MIPSOcteonSharedMode {\n     OCTEON_SHARED_MODE_NONE = 0,\n     OCTEON_SHARED_MODE_SHA512,\n     OCTEON_SHARED_MODE_SNOW3G,\n+    OCTEON_SHARED_MODE_SHA3,\n } MIPSOcteonSharedMode;\n \n typedef enum MIPSOcteonCop2Sel {\n@@ -637,6 +638,7 @@ typedef enum MIPSOcteonCop2Sel {\n     OCTEON_COP2_SEL_HSH_DATW13,\n     OCTEON_COP2_SEL_HSH_DATW14,\n     OCTEON_COP2_SEL_HSH_DATW15,\n+    OCTEON_COP2_SEL_SHA3_DAT15_READ = 0x024f,\n     OCTEON_COP2_SEL_HSH_IVW0 = 0x0250,\n     OCTEON_COP2_SEL_HSH_IVW1,\n     OCTEON_COP2_SEL_HSH_IVW2,\n@@ -663,6 +665,24 @@ typedef enum MIPSOcteonCop2Sel {\n     OCTEON_COP2_SEL_GFM_RESINP1,\n     OCTEON_COP2_SEL_GFM_XOR0,\n     OCTEON_COP2_SEL_GFM_POLY = 0x025e,\n+    OCTEON_COP2_SEL_SHA3_XORDAT0 = 0x02c0,\n+    OCTEON_COP2_SEL_SHA3_XORDAT1,\n+    OCTEON_COP2_SEL_SHA3_XORDAT2,\n+    OCTEON_COP2_SEL_SHA3_XORDAT3,\n+    OCTEON_COP2_SEL_SHA3_XORDAT4,\n+    OCTEON_COP2_SEL_SHA3_XORDAT5,\n+    OCTEON_COP2_SEL_SHA3_XORDAT6,\n+    OCTEON_COP2_SEL_SHA3_XORDAT7,\n+    OCTEON_COP2_SEL_SHA3_XORDAT8,\n+    OCTEON_COP2_SEL_SHA3_XORDAT9,\n+    OCTEON_COP2_SEL_SHA3_XORDAT10,\n+    OCTEON_COP2_SEL_SHA3_XORDAT11,\n+    OCTEON_COP2_SEL_SHA3_XORDAT12,\n+    OCTEON_COP2_SEL_SHA3_XORDAT13,\n+    OCTEON_COP2_SEL_SHA3_XORDAT14,\n+    OCTEON_COP2_SEL_SHA3_XORDAT15,\n+    OCTEON_COP2_SEL_SHA3_XORDAT16,\n+    OCTEON_COP2_SEL_SHA3_XORDAT17,\n     OCTEON_COP2_SEL_AES_ENC_CBC1 = 0x3109,\n     OCTEON_COP2_SEL_AES_ENC1 = 0x310b,\n     OCTEON_COP2_SEL_AES_DEC_CBC1 = 0x310d,\n@@ -675,6 +695,7 @@ typedef enum MIPSOcteonCop2Sel {\n     OCTEON_COP2_SEL_SNOW3G_START = 0x404d,\n     OCTEON_COP2_SEL_SNOW3G_MORE = 0x404e,\n     OCTEON_COP2_SEL_HSH_STARTSHA256 = 0x404f,\n+    OCTEON_COP2_SEL_SHA3_STARTOP = 0x4052,\n     OCTEON_COP2_SEL_GFM_XORMUL1_REFLECT = 0x405d,\n     OCTEON_COP2_SEL_HSH_STARTSHA1 = 0x4057,\n     OCTEON_COP2_SEL_HSH_STARTSHA512 = 0x424f,\n@@ -689,6 +710,7 @@ typedef struct MIPSOcteonCryptoState {\n     uint64_t hash_block[8];\n     uint64_t sha512_state[8];\n     uint64_t sha512_block[16];\n+    uint64_t sha3_state[25];\n     uint64_t aes_iv[2];\n     uint64_t aes_key[4];\n     uint64_t aes_result[2];\ndiff --git a/target/mips/system/machine.c b/target/mips/system/machine.c\nindex 8595b1bdfa..bf48544a08 100644\n--- a/target/mips/system/machine.c\n+++ b/target/mips/system/machine.c\n@@ -292,6 +292,7 @@ static const VMStateDescription mips_vmstate_octeon_crypto = {\n         VMSTATE_UINT64_ARRAY(env.octeon_crypto.hash_block, MIPSCPU, 8),\n         VMSTATE_UINT64_ARRAY(env.octeon_crypto.sha512_state, MIPSCPU, 8),\n         VMSTATE_UINT64_ARRAY(env.octeon_crypto.sha512_block, MIPSCPU, 16),\n+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.sha3_state, MIPSCPU, 25),\n         VMSTATE_UINT64_ARRAY(env.octeon_crypto.aes_iv, MIPSCPU, 2),\n         VMSTATE_UINT64_ARRAY(env.octeon_crypto.aes_key, MIPSCPU, 4),\n         VMSTATE_UINT64_ARRAY(env.octeon_crypto.aes_result, MIPSCPU, 2),\ndiff --git a/target/mips/tcg/octeon_crypto.c b/target/mips/tcg/octeon_crypto.c\nindex 177d112483..d9e66f3dc8 100644\n--- a/target/mips/tcg/octeon_crypto.c\n+++ b/target/mips/tcg/octeon_crypto.c\n@@ -487,21 +487,150 @@ static void octeon_sha512_transform(MIPSOcteonCryptoState *crypto)\n     crypto->sha512_state[7] += h;\n }\n \n+static const uint64_t octeon_sha3_round_constants[24] = {\n+    0x0000000000000001ULL, 0x0000000000008082ULL,\n+    0x800000000000808aULL, 0x8000000080008000ULL,\n+    0x000000000000808bULL, 0x0000000080000001ULL,\n+    0x8000000080008081ULL, 0x8000000000008009ULL,\n+    0x000000000000008aULL, 0x0000000000000088ULL,\n+    0x0000000080008009ULL, 0x000000008000000aULL,\n+    0x000000008000808bULL, 0x800000000000008bULL,\n+    0x8000000000008089ULL, 0x8000000000008003ULL,\n+    0x8000000000008002ULL, 0x8000000000000080ULL,\n+    0x000000000000800aULL, 0x800000008000000aULL,\n+    0x8000000080008081ULL, 0x8000000000008080ULL,\n+    0x0000000080000001ULL, 0x8000000080008008ULL,\n+};\n+\n+static const uint8_t octeon_sha3_rotation_constants[24] = {\n+     1,  3,  6, 10, 15, 21, 28, 36, 45, 55,  2, 14,\n+    27, 41, 56,  8, 25, 43, 62, 18, 39, 61, 20, 44,\n+};\n+\n+static const uint8_t octeon_sha3_pi_lanes[24] = {\n+    10,  7, 11, 17, 18,  3,  5, 16,  8, 21, 24,  4,\n+    15, 23, 19, 13, 12,  2, 20, 14, 22,  9,  6,  1,\n+};\n+\n+static void octeon_sha3_permute(MIPSOcteonCryptoState *crypto)\n+{\n+    uint64_t *state = crypto->sha3_state;\n+\n+    for (int round = 0; round < 24; round++) {\n+        uint64_t bc[5];\n+        uint64_t temp;\n+\n+        for (int x = 0; x < 5; x++) {\n+            bc[x] = state[x] ^ state[5 + x] ^ state[10 + x] ^\n+                    state[15 + x] ^ state[20 + x];\n+        }\n+        for (int x = 0; x < 5; x++) {\n+            temp = bc[(x + 4) % 5] ^ rol64(bc[(x + 1) % 5], 1);\n+            for (int y = 0; y < 25; y += 5) {\n+                state[y + x] ^= temp;\n+            }\n+        }\n+\n+        temp = state[1];\n+        for (int i = 0; i < 24; i++) {\n+            uint64_t next = state[octeon_sha3_pi_lanes[i]];\n+\n+            state[octeon_sha3_pi_lanes[i]] =\n+                rol64(temp, octeon_sha3_rotation_constants[i]);\n+            temp = next;\n+        }\n+\n+        for (int y = 0; y < 25; y += 5) {\n+            for (int x = 0; x < 5; x++) {\n+                bc[x] = state[y + x];\n+            }\n+            for (int x = 0; x < 5; x++) {\n+                state[y + x] = bc[x] ^ ((~bc[(x + 1) % 5]) & bc[(x + 2) % 5]);\n+            }\n+        }\n+\n+        state[0] ^= octeon_sha3_round_constants[round];\n+    }\n+}\n+\n+static bool octeon_sha3_is_dat_sel(uint32_t sel)\n+{\n+    switch (sel) {\n+    case OCTEON_COP2_SEL_HSH_DATW0 ... OCTEON_COP2_SEL_HSH_DATW15:\n+    case OCTEON_COP2_SEL_HSH_IVW0 ... OCTEON_COP2_SEL_HSH_IVW7:\n+    case OCTEON_COP2_SEL_SHA3_DAT15_WRITE:\n+    case OCTEON_COP2_SEL_SHA3_DAT24:\n+        return true;\n+    default:\n+        return false;\n+    }\n+}\n+\n+static int octeon_sha3_dat_pos_from_sel(uint32_t sel)\n+{\n+    switch (sel) {\n+    case OCTEON_COP2_SEL_HSH_DATW0 ... OCTEON_COP2_SEL_HSH_DATW14:\n+        return sel - OCTEON_COP2_SEL_HSH_DATW0;\n+    case OCTEON_COP2_SEL_HSH_IVW0 ... OCTEON_COP2_SEL_HSH_IVW7:\n+        return 16 + (sel - OCTEON_COP2_SEL_HSH_IVW0);\n+    case OCTEON_COP2_SEL_HSH_DATW15:\n+    case OCTEON_COP2_SEL_SHA3_DAT15_WRITE:\n+        return 15;\n+    case OCTEON_COP2_SEL_SHA3_DAT24:\n+        return 24;\n+    default:\n+        g_assert_not_reached();\n+    }\n+}\n+\n+static uint64_t octeon_sha3_reg_to_lane(uint64_t value)\n+{\n+    /*\n+     * The COP2 register interface is consumed by big-endian MIPS code as\n+     * 64-bit register values, while Keccak lanes are byte-little-endian.\n+     */\n+    return bswap64(value);\n+}\n+\n+static uint64_t octeon_sha3_lane_to_reg(uint64_t value)\n+{\n+    return bswap64(value);\n+}\n+\n static void octeon_store_shared_hash_dat(MIPSOcteonCryptoState *crypto,\n                                          uint32_t sel, uint64_t value)\n {\n     switch (sel) {\n     case OCTEON_COP2_SEL_HSH_DATW0 ... OCTEON_COP2_SEL_HSH_DATW14:\n         crypto->sha512_block[sel - OCTEON_COP2_SEL_HSH_DATW0] = value;\n+        crypto->sha3_state[sel - OCTEON_COP2_SEL_HSH_DATW0] =\n+            octeon_sha3_reg_to_lane(value);\n         break;\n     case OCTEON_COP2_SEL_HSH_IVW0 ... OCTEON_COP2_SEL_HSH_IVW7:\n         crypto->sha512_state[sel - OCTEON_COP2_SEL_HSH_IVW0] = value;\n+        crypto->sha3_state[16 + (sel - OCTEON_COP2_SEL_HSH_IVW0)] =\n+            octeon_sha3_reg_to_lane(value);\n+        break;\n+    case OCTEON_COP2_SEL_SHA3_DAT15_WRITE:\n+        crypto->sha3_state[15] = octeon_sha3_reg_to_lane(value);\n+        break;\n+    case OCTEON_COP2_SEL_SHA3_DAT24:\n+        crypto->sha3_state[24] = octeon_sha3_reg_to_lane(value);\n         break;\n     default:\n         g_assert_not_reached();\n     }\n }\n \n+static int octeon_sha3_xordat_pos_from_sel(uint32_t sel)\n+{\n+    if (sel >= OCTEON_COP2_SEL_SHA3_XORDAT0 &&\n+        sel <= OCTEON_COP2_SEL_SHA3_XORDAT17) {\n+        return sel - OCTEON_COP2_SEL_SHA3_XORDAT0;\n+    }\n+    return -1;\n+}\n+\n static const uint8_t octeon_snow3g_sr[256] = {\n     0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,\n     0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,\n@@ -1396,6 +1525,7 @@ static void octeon_gfm_mul(const uint64_t x[2], const uint64_t y[2],\n uint64_t helper_octeon_cop2_dmfc2(CPUMIPSState *env, uint32_t sel)\n {\n     MIPSOcteonCryptoState *crypto = &env->octeon_crypto;\n+    int sha3_pos;\n \n     if (crypto->shared_mode == OCTEON_SHARED_MODE_SNOW3G) {\n         if (sel >= OCTEON_COP2_SEL_SNOW3G_LFSR0 &&\n@@ -1417,6 +1547,12 @@ uint64_t helper_octeon_cop2_dmfc2(CPUMIPSState *env, uint32_t sel)\n         }\n     }\n \n+    if (crypto->shared_mode == OCTEON_SHARED_MODE_SHA3 &&\n+        octeon_sha3_is_dat_sel(sel)) {\n+        sha3_pos = octeon_sha3_dat_pos_from_sel(sel);\n+        return octeon_sha3_lane_to_reg(crypto->sha3_state[sha3_pos]);\n+    }\n+\n     switch (sel) {\n     case OCTEON_COP2_SEL_3DES_KEY0:\n     case OCTEON_COP2_SEL_3DES_KEY1:\n@@ -1507,6 +1643,7 @@ void helper_octeon_cop2_dmtc2(CPUMIPSState *env, uint64_t value,\n {\n     MIPSOcteonCryptoState *crypto = &env->octeon_crypto;\n     uint64_t q = (uint64_t)value;\n+    int sha3_pos;\n \n     switch (sel) {\n     case OCTEON_COP2_SEL_3DES_KEY0:\n@@ -1628,6 +1765,14 @@ void helper_octeon_cop2_dmtc2(CPUMIPSState *env, uint64_t value,\n         octeon_set_shared_mode(crypto, OCTEON_SHARED_MODE_SHA512);\n         octeon_sha512_transform(crypto);\n         break;\n+    case OCTEON_COP2_SEL_SHA3_DAT15_WRITE:\n+        octeon_set_shared_mode(crypto, OCTEON_SHARED_MODE_SHA3);\n+        octeon_store_shared_hash_dat(crypto, sel, q);\n+        break;\n+    case OCTEON_COP2_SEL_SHA3_DAT24:\n+        octeon_set_shared_mode(crypto, OCTEON_SHARED_MODE_SHA3);\n+        octeon_store_shared_hash_dat(crypto, sel, q);\n+        break;\n     case OCTEON_COP2_SEL_HSH_IVW0:\n     case OCTEON_COP2_SEL_HSH_IVW1:\n     case OCTEON_COP2_SEL_HSH_IVW2:\n@@ -1688,6 +1833,32 @@ void helper_octeon_cop2_dmtc2(CPUMIPSState *env, uint64_t value,\n         crypto->hash_block[7] = q;\n         octeon_sha1_transform(crypto);\n         break;\n+    case OCTEON_COP2_SEL_SHA3_XORDAT0:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT1:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT2:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT3:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT4:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT5:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT6:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT7:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT8:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT9:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT10:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT11:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT12:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT13:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT14:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT15:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT16:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT17:\n+        octeon_set_shared_mode(crypto, OCTEON_SHARED_MODE_SHA3);\n+        sha3_pos = octeon_sha3_xordat_pos_from_sel(sel);\n+        crypto->sha3_state[sha3_pos] ^= octeon_sha3_reg_to_lane(q);\n+        break;\n+    case OCTEON_COP2_SEL_SHA3_STARTOP:\n+        octeon_set_shared_mode(crypto, OCTEON_SHARED_MODE_SHA3);\n+        octeon_sha3_permute(crypto);\n+        break;\n     case OCTEON_COP2_SEL_GFM_XORMUL1_REFLECT:\n         octeon_gfm_mul_reflect(crypto, q);\n         break;\ndiff --git a/target/mips/tcg/octeon_translate.c b/target/mips/tcg/octeon_translate.c\nindex 6d123a4623..278b2ed991 100644\n--- a/target/mips/tcg/octeon_translate.c\n+++ b/target/mips/tcg/octeon_translate.c\n@@ -66,6 +66,7 @@ static bool octeon_cop2_is_supported_dmfc2(uint16_t sel)\n     case OCTEON_COP2_SEL_HSH_IVW6:\n     case OCTEON_COP2_SEL_HSH_IVW7:\n     case OCTEON_COP2_SEL_AES_DAT0:\n+    case OCTEON_COP2_SEL_SHA3_DAT24:\n     case OCTEON_COP2_SEL_GFM_MUL_REFLECT0:\n     case OCTEON_COP2_SEL_GFM_MUL_REFLECT1:\n     case OCTEON_COP2_SEL_GFM_RESINP_REFLECT0:\n@@ -150,6 +151,8 @@ static bool octeon_cop2_is_supported_dmtc2(uint16_t sel)\n     case OCTEON_COP2_SEL_HSH_DATW13:\n     case OCTEON_COP2_SEL_HSH_DATW14:\n     case OCTEON_COP2_SEL_HSH_DATW15:\n+    case OCTEON_COP2_SEL_SHA3_DAT24:\n+    case OCTEON_COP2_SEL_SHA3_DAT15_WRITE:\n     case OCTEON_COP2_SEL_HSH_IVW0:\n     case OCTEON_COP2_SEL_HSH_IVW1:\n     case OCTEON_COP2_SEL_HSH_IVW2:\n@@ -167,11 +170,30 @@ static bool octeon_cop2_is_supported_dmtc2(uint16_t sel)\n     case OCTEON_COP2_SEL_GFM_RESINP1:\n     case OCTEON_COP2_SEL_GFM_XOR0:\n     case OCTEON_COP2_SEL_GFM_POLY:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT0:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT1:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT2:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT3:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT4:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT5:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT6:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT7:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT8:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT9:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT10:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT11:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT12:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT13:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT14:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT15:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT16:\n+    case OCTEON_COP2_SEL_SHA3_XORDAT17:\n     case OCTEON_COP2_SEL_HSH_STARTSHA1_COMPAT:\n     case OCTEON_COP2_SEL_HSH_STARTMD5:\n     case OCTEON_COP2_SEL_SNOW3G_START:\n     case OCTEON_COP2_SEL_SNOW3G_MORE:\n     case OCTEON_COP2_SEL_HSH_STARTSHA256:\n+    case OCTEON_COP2_SEL_SHA3_STARTOP:\n     case OCTEON_COP2_SEL_HSH_STARTSHA1:\n     case OCTEON_COP2_SEL_GFM_XORMUL1_REFLECT:\n     case OCTEON_COP2_SEL_HSH_STARTSHA512:\n","prefixes":["v3","28/32"]}