From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.48 as permitted sender) client-ip=209.85.128.48; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f48.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.48 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906533; cv=none; d=zohomail.com; s=zohoarc; b=hu7zN3x/KupxS9/KvmWfFpUoOnYoBUxEmYolJUK61m7gdn62ZHpTxSPw9GWkJtXnthptchVoyMEpjiA5JqQcTpJBR2v73sQTdodocp+bmLs2qPahGWO/UFLRIJnBMg0hmeRHogKfeFqkVD87cj3YBeGwc4sbfFQn2mEkSd4P+Qk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906533; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=+fc+YUz62tq02umlqIV5H66jZhdZhb5rDT17gD+B0T0=; b=GWJ2uu+EyIjChn09QlAWH1HVR3+tXFwMG/ehK/h4bTVT9xnXvITTlP50z8mqS6hb8LT+ss0j9hGFVOBUxDmsU1IHAv6QEw6Z0wOOi9PgOyW1Z8ySe5gVD23cMIelQvTNA/8qITVuP97qEHDEgWU7x+H0e6OnLanqc+I/urw3Dss= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.48 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) by mx.zohomail.com with SMTPS id 1605906533612279.13351605284925; Fri, 20 Nov 2020 13:08:53 -0800 (PST) Received: by mail-wm1-f48.google.com with SMTP id a65so11254970wme.1 for ; Fri, 20 Nov 2020 13:08:53 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id m3sm6678867wrv.6.2020.11.20.13.08.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:08:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+fc+YUz62tq02umlqIV5H66jZhdZhb5rDT17gD+B0T0=; b=T+c5m+fCdxu+clJ1SWsLGwARmZ6iZF1HIvE2x+jTGE6/Esg1fExuuA2PbAj+5PWHaB rBKxCgy0X4pt7vX6qeshU74KJ/X8xthS+6RYm+Fq05xmkJnPi6hHeud+N5jerDYRPGza u790RBarOzbfE/WAw2uv9CRv9gdu1LXTU251cMLCSxOIfOKyzQd2rlgUXVZ6oReMVsa9 iEYw9UzCwCG0nQx7zLomtaQDSayBvd57iFxf0ZLVgPXNeaO+lqI1fYU23PX3hXIBB4l3 0pKmfiRbluff8D760fEMqzPJzPcDfVFuOEpeZdyBSvc34STqtrDXQGK6JHMmAGJKFrNX aLzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=+fc+YUz62tq02umlqIV5H66jZhdZhb5rDT17gD+B0T0=; b=klaIKo2sO+TqPcpsdzWq/07GZ2Iyjrg0zIJf26ILcMmeUOcdXWnmO6BU1Rf6mLGyg7 Y7zTDLAdEB5JRU9kiOLPkqZ2U909TEooCWkPeQuVGIZzqLE5HAeYRG8s72ZFtHgSfrxa QkuRowpMKP+PVc2utfXEa/SomXNj+MT3BnvZ2qLx6/0y52pWtkFoIqkyfFsgGGAzyHgI DPd4fhR4FhmqXfPkHhwwAI+H2DtuVKORvAx3y8rryEwGY8HtwoayuvTkHhqsnx2ZQOGl BP8+IqGAm+WSjKSE6Z1pXdNWoBk2E01C+e3J9PoG2e5d9yVCrQ4TrRHw5PKcMq9ET8eB b5Xg== X-Gm-Message-State: AOAM5326nlw4Nmcn2gZA3aG/8TqfIziKn1e3aohZtCWkr6ozQkaDWKcr ETh0RVgP1mn8Ui1EfTgjIPc= X-Google-Smtp-Source: ABdhPJyMWl1CLz2CtmfNK1IxSBRRhLqCKClWf6WaMhSaron8adZwuSUc3h3uZbNWWPUz7jV1Yb7ZUQ== X-Received: by 2002:a7b:c8d3:: with SMTP id f19mr11601864wml.17.1605906531772; Fri, 20 Nov 2020 13:08:51 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 01/26] target/mips: Extract FPU helpers to 'fpu_helper.h' Date: Fri, 20 Nov 2020 22:08:19 +0100 Message-Id: <20201120210844.2625602-2-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract FPU specific helpers from "internal.h" to "fpu_helper.h". Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/fpu_helper.h | 50 ++++++++++++++++++++++++++++++++++++++ target/mips/internal.h | 42 -------------------------------- linux-user/mips/cpu_loop.c | 1 + target/mips/fpu_helper.c | 1 + target/mips/gdbstub.c | 1 + target/mips/kvm.c | 1 + target/mips/machine.c | 1 + target/mips/msa_helper.c | 1 + target/mips/translate.c | 1 + 9 files changed, 57 insertions(+), 42 deletions(-) create mode 100644 target/mips/fpu_helper.h diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h new file mode 100644 index 00000000000..83c698d583f --- /dev/null +++ b/target/mips/fpu_helper.h @@ -0,0 +1,50 @@ +/* + * Helpers for emulation of FPU-related MIPS instructions. + * + * Copyright (C) 2004-2005 Jocelyn Mayer + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ +#include "fpu/softfloat-helpers.h" +#include "cpu.h" + +extern unsigned int ieee_rm[]; + +uint32_t float_class_s(uint32_t arg, float_status *fst); +uint64_t float_class_d(uint64_t arg, float_status *fst); + +static inline void restore_rounding_mode(CPUMIPSState *env) +{ + set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], + &env->active_fpu.fp_status); +} + +static inline void restore_flush_mode(CPUMIPSState *env) +{ + set_flush_to_zero((env->active_fpu.fcr31 & (1 << FCR31_FS)) !=3D 0, + &env->active_fpu.fp_status); +} + +static inline void restore_snan_bit_mode(CPUMIPSState *env) +{ + set_snan_bit_is_one((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) =3D= =3D 0, + &env->active_fpu.fp_status); +} + +static inline void restore_fp_status(CPUMIPSState *env) +{ + restore_rounding_mode(env); + restore_flush_mode(env); + restore_snan_bit_mode(env); +} + +static inline void restore_msa_fp_status(CPUMIPSState *env) +{ + float_status *status =3D &env->active_tc.msa_fp_status; + int rounding_mode =3D (env->active_tc.msacsr & MSACSR_RM_MASK) >> MSAC= SR_RM; + bool flush_to_zero =3D (env->active_tc.msacsr & MSACSR_FS_MASK) !=3D 0; + + set_float_rounding_mode(ieee_rm[rounding_mode], status); + set_flush_to_zero(flush_to_zero, status); + set_flush_inputs_to_zero(flush_to_zero, status); +} diff --git a/target/mips/internal.h b/target/mips/internal.h index dd8a7809b64..7bea3af0b29 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -8,8 +8,6 @@ #ifndef MIPS_INTERNAL_H #define MIPS_INTERNAL_H =20 -#include "fpu/softfloat-helpers.h" - /* * MMU types, the first four entries have the same layout as the * CP0C0_MT field. @@ -222,48 +220,8 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, in= t size, bool probe, uintptr_t retaddr); =20 /* op_helper.c */ -uint32_t float_class_s(uint32_t arg, float_status *fst); -uint64_t float_class_d(uint64_t arg, float_status *fst); - -extern unsigned int ieee_rm[]; void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagema= sk); =20 -static inline void restore_rounding_mode(CPUMIPSState *env) -{ - set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], - &env->active_fpu.fp_status); -} - -static inline void restore_flush_mode(CPUMIPSState *env) -{ - set_flush_to_zero((env->active_fpu.fcr31 & (1 << FCR31_FS)) !=3D 0, - &env->active_fpu.fp_status); -} - -static inline void restore_snan_bit_mode(CPUMIPSState *env) -{ - set_snan_bit_is_one((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) =3D= =3D 0, - &env->active_fpu.fp_status); -} - -static inline void restore_fp_status(CPUMIPSState *env) -{ - restore_rounding_mode(env); - restore_flush_mode(env); - restore_snan_bit_mode(env); -} - -static inline void restore_msa_fp_status(CPUMIPSState *env) -{ - float_status *status =3D &env->active_tc.msa_fp_status; - int rounding_mode =3D (env->active_tc.msacsr & MSACSR_RM_MASK) >> MSAC= SR_RM; - bool flush_to_zero =3D (env->active_tc.msacsr & MSACSR_FS_MASK) !=3D 0; - - set_float_rounding_mode(ieee_rm[rounding_mode], status); - set_flush_to_zero(flush_to_zero, status); - set_flush_inputs_to_zero(flush_to_zero, status); -} - static inline void restore_pamask(CPUMIPSState *env) { if (env->hflags & MIPS_HFLAG_ELPA) { diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index cfe7ba5c47d..b58dbeb83d1 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -23,6 +23,7 @@ #include "cpu_loop-common.h" #include "elf.h" #include "internal.h" +#include "fpu_helper.h" =20 # ifdef TARGET_ABI_MIPSO32 # define MIPS_SYSCALL_NUMBER_UNUSED -1 diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c index 020b768e87b..a74dc18d746 100644 --- a/target/mips/fpu_helper.c +++ b/target/mips/fpu_helper.c @@ -31,6 +31,7 @@ #include "exec/memop.h" #include "sysemu/kvm.h" #include "fpu/softfloat.h" +#include "fpu_helper.h" =20 =20 /* Complex FPU operations which may need stack space. */ diff --git a/target/mips/gdbstub.c b/target/mips/gdbstub.c index e39f8d75cf0..f1c2a2cf6d6 100644 --- a/target/mips/gdbstub.c +++ b/target/mips/gdbstub.c @@ -21,6 +21,7 @@ #include "cpu.h" #include "internal.h" #include "exec/gdbstub.h" +#include "fpu_helper.h" =20 int mips_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { diff --git a/target/mips/kvm.c b/target/mips/kvm.c index 72637a1e021..df47eded328 100644 --- a/target/mips/kvm.c +++ b/target/mips/kvm.c @@ -27,6 +27,7 @@ #include "kvm_mips.h" #include "exec/memattrs.h" #include "hw/boards.h" +#include "fpu_helper.h" =20 #define DEBUG_KVM 0 =20 diff --git a/target/mips/machine.c b/target/mips/machine.c index 5b23e3e912a..a4ea67c2980 100644 --- a/target/mips/machine.c +++ b/target/mips/machine.c @@ -2,6 +2,7 @@ #include "cpu.h" #include "internal.h" #include "migration/cpu.h" +#include "fpu_helper.h" =20 static int cpu_post_load(void *opaque, int version_id) { diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 249f0fdad80..b89b4c44902 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -23,6 +23,7 @@ #include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" +#include "fpu_helper.h" =20 /* Data format min and max values */ #define DF_BITS(df) (1 << ((df) + 3)) diff --git a/target/mips/translate.c b/target/mips/translate.c index c64a1bc42e1..5ec9fd7e92a 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -39,6 +39,7 @@ #include "exec/translator.h" #include "exec/log.h" #include "qemu/qemu-print.h" +#include "fpu_helper.h" =20 #define MIPS_DEBUG_DISAS 0 =20 --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.67 as permitted sender) client-ip=209.85.128.67; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f67.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.67 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906539; cv=none; d=zohomail.com; s=zohoarc; b=ZSKPdeB8hLIfINSVYEOAfHAsomKV3nNXzq8a7dh5JhGxwAAangPfxD4S+NtbAhVryqEDKdSVDfMmpQ993rjk0POAO2hypKGohEyghoBNDvZq1ia9W5y+38GlTK4kKWXieW01GKlQen+iYZ4KZGrt8bZ3A09wKoqREGbu+eoxRUI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906539; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=6uggFZJsohD3+Nk7D77B+wpajPgPcxGdSwUAoeazy6s=; b=fuICTnsYKM8gri9S52f3MtSn9wBeYy9zwfcAmYW/7Q5trL3BMqtFBjz1gdJXA915kvS/aR/JrFdR0Qr2CR58ZCFBYzVFtK3D2Pyxdx+ZXsI6lmhQQFFXlkd7HQaXSixrqHX4tJOEA16NtebXzGOXAE8JxAa0UoUqFlPOvS8tyQ0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.67 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by mx.zohomail.com with SMTPS id 1605906539265421.9883164504281; Fri, 20 Nov 2020 13:08:59 -0800 (PST) Received: by mail-wm1-f67.google.com with SMTP id c9so11849685wml.5 for ; Fri, 20 Nov 2020 13:08:58 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id o2sm6332551wrv.4.2020.11.20.13.08.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:08:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6uggFZJsohD3+Nk7D77B+wpajPgPcxGdSwUAoeazy6s=; b=JL8OSaFkk8Y3199CW0KYDcqYH7mxPvxe5QIoZShvFoQ3wbbaVTl/Xpvw0wZY5ys4Jc oA9+bYlId7yvrWmQBkiWMcRAWFg3lrMBW17k+3M+BJqoPH+1J2WAryG+QY7l7yl8iikK WqOeeIr45/DyDNHj53Mzd/CiCgVsmYLhJXqezGFcSUW1eqBXpEVrCJ+pTVGiWmGuTzmy Gdil3evTEGPpfGnONWV6pAIww4flxUzyE0mZ0zWt9eqVTV5SuHX7jywwef9udmAWNFeE oEhK/Zzf847kykXikg8MrgJEamVclPCQObw7281LM4Hs4WBbcEQsJ1J4zjiznAWMSjQV elpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=6uggFZJsohD3+Nk7D77B+wpajPgPcxGdSwUAoeazy6s=; b=O5knJtQ9Y53hqFauJI5dOpVSq+wk2zmPUAsvETJmv6a4wWD8Couj37hc6yWWu90MqG vNBnJLpvAnDq4BP0NvdMADUBbPXcI/QJhTOooko/JveApN75m/bcpkOgVjrZ6c7c7F0U RzOT5of5c8pUWiGUllo1UPs0nU7dL5ek5bDH6weNb+nFSzq6Fuz0Z5bX/kmc6yPyIe6m 2H1okrg95EduL6VCNtulnyexjCkXosh12i1AFe7gt5UO4srXlfNK1VuHARZ4ZcgXjnC/ e89sVRRN+S2fEf2icxcXsDaliGBgjvGnE0n/dJAkJXPaLHlB06Cqd4XeJrriC5eH7AHS VPMg== X-Gm-Message-State: AOAM531+DyAVDozVpREs12URZQNP+tQhp6ojAYWYWwncc2d+ObibVB59 4OG6bJfZu+0wLz2VVqQb5BY= X-Google-Smtp-Source: ABdhPJxrOTauRwNmFJCEOjbdJRyUQ6YxAoQ/nPRu0mXRgNdSm3oTPCRyjfIJ+5i5wKp1I96nV/A4vg== X-Received: by 2002:a1c:a555:: with SMTP id o82mr11910027wme.188.1605906536924; Fri, 20 Nov 2020 13:08:56 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 02/26] target/mips: Extract MSA helpers to mod-mips-msa_helper.c Date: Fri, 20 Nov 2020 22:08:20 +0100 Message-Id: <20201120210844.2625602-3-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) MSA means 'MIPS SIMD Architecture' and is defined as a Module by MIPS. Rename msa_helper.c as mod-mips-msa_helper.c, merge other MSA helpers from op_helper.c. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- .../{msa_helper.c =3D> mod-mips-msa_helper.c} | 392 +++++++++++++++++ target/mips/op_helper.c | 393 ------------------ target/mips/meson.build | 3 +- 3 files changed, 394 insertions(+), 394 deletions(-) rename target/mips/{msa_helper.c =3D> mod-mips-msa_helper.c} (94%) diff --git a/target/mips/msa_helper.c b/target/mips/mod-mips-msa_helper.c similarity index 94% rename from target/mips/msa_helper.c rename to target/mips/mod-mips-msa_helper.c index b89b4c44902..56fca86a242 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/mod-mips-msa_helper.c @@ -8201,3 +8201,395 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint3= 2_t df, uint32_t wd, =20 msa_move_v(pwd, pwx); } + +/* Data format min and max values */ +#define DF_BITS(df) (1 << ((df) + 3)) + +/* Element-by-element access macros */ +#define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df)) + +#if !defined(CONFIG_USER_ONLY) +#define MEMOP_IDX(DF) \ + TCGMemOpIdx oi =3D make_memop_idx(MO_TE | DF | MO_UNALN, \ + cpu_mmu_index(env, false)); +#else +#define MEMOP_IDX(DF) +#endif + +void helper_msa_ld_b(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); + MEMOP_IDX(DF_BYTE) +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->b[0] =3D helper_ret_ldub_mmu(env, addr + (0 << DF_BYTE), oi, GE= TPC()); + pwd->b[1] =3D helper_ret_ldub_mmu(env, addr + (1 << DF_BYTE), oi, GE= TPC()); + pwd->b[2] =3D helper_ret_ldub_mmu(env, addr + (2 << DF_BYTE), oi, GE= TPC()); + pwd->b[3] =3D helper_ret_ldub_mmu(env, addr + (3 << DF_BYTE), oi, GE= TPC()); + pwd->b[4] =3D helper_ret_ldub_mmu(env, addr + (4 << DF_BYTE), oi, GE= TPC()); + pwd->b[5] =3D helper_ret_ldub_mmu(env, addr + (5 << DF_BYTE), oi, GE= TPC()); + pwd->b[6] =3D helper_ret_ldub_mmu(env, addr + (6 << DF_BYTE), oi, GE= TPC()); + pwd->b[7] =3D helper_ret_ldub_mmu(env, addr + (7 << DF_BYTE), oi, GE= TPC()); + pwd->b[8] =3D helper_ret_ldub_mmu(env, addr + (8 << DF_BYTE), oi, GE= TPC()); + pwd->b[9] =3D helper_ret_ldub_mmu(env, addr + (9 << DF_BYTE), oi, GE= TPC()); + pwd->b[10] =3D helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GE= TPC()); + pwd->b[11] =3D helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GE= TPC()); + pwd->b[12] =3D helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GE= TPC()); + pwd->b[13] =3D helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GE= TPC()); + pwd->b[14] =3D helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GE= TPC()); + pwd->b[15] =3D helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GE= TPC()); +#else + pwd->b[0] =3D helper_ret_ldub_mmu(env, addr + (7 << DF_BYTE), oi, GE= TPC()); + pwd->b[1] =3D helper_ret_ldub_mmu(env, addr + (6 << DF_BYTE), oi, GE= TPC()); + pwd->b[2] =3D helper_ret_ldub_mmu(env, addr + (5 << DF_BYTE), oi, GE= TPC()); + pwd->b[3] =3D helper_ret_ldub_mmu(env, addr + (4 << DF_BYTE), oi, GE= TPC()); + pwd->b[4] =3D helper_ret_ldub_mmu(env, addr + (3 << DF_BYTE), oi, GE= TPC()); + pwd->b[5] =3D helper_ret_ldub_mmu(env, addr + (2 << DF_BYTE), oi, GE= TPC()); + pwd->b[6] =3D helper_ret_ldub_mmu(env, addr + (1 << DF_BYTE), oi, GE= TPC()); + pwd->b[7] =3D helper_ret_ldub_mmu(env, addr + (0 << DF_BYTE), oi, GE= TPC()); + pwd->b[8] =3D helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GE= TPC()); + pwd->b[9] =3D helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GE= TPC()); + pwd->b[10] =3D helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GE= TPC()); + pwd->b[11] =3D helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GE= TPC()); + pwd->b[12] =3D helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GE= TPC()); + pwd->b[13] =3D helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GE= TPC()); + pwd->b[14] =3D helper_ret_ldub_mmu(env, addr + (9 << DF_BYTE), oi, GE= TPC()); + pwd->b[15] =3D helper_ret_ldub_mmu(env, addr + (8 << DF_BYTE), oi, GE= TPC()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->b[0] =3D cpu_ldub_data(env, addr + (0 << DF_BYTE)); + pwd->b[1] =3D cpu_ldub_data(env, addr + (1 << DF_BYTE)); + pwd->b[2] =3D cpu_ldub_data(env, addr + (2 << DF_BYTE)); + pwd->b[3] =3D cpu_ldub_data(env, addr + (3 << DF_BYTE)); + pwd->b[4] =3D cpu_ldub_data(env, addr + (4 << DF_BYTE)); + pwd->b[5] =3D cpu_ldub_data(env, addr + (5 << DF_BYTE)); + pwd->b[6] =3D cpu_ldub_data(env, addr + (6 << DF_BYTE)); + pwd->b[7] =3D cpu_ldub_data(env, addr + (7 << DF_BYTE)); + pwd->b[8] =3D cpu_ldub_data(env, addr + (8 << DF_BYTE)); + pwd->b[9] =3D cpu_ldub_data(env, addr + (9 << DF_BYTE)); + pwd->b[10] =3D cpu_ldub_data(env, addr + (10 << DF_BYTE)); + pwd->b[11] =3D cpu_ldub_data(env, addr + (11 << DF_BYTE)); + pwd->b[12] =3D cpu_ldub_data(env, addr + (12 << DF_BYTE)); + pwd->b[13] =3D cpu_ldub_data(env, addr + (13 << DF_BYTE)); + pwd->b[14] =3D cpu_ldub_data(env, addr + (14 << DF_BYTE)); + pwd->b[15] =3D cpu_ldub_data(env, addr + (15 << DF_BYTE)); +#else + pwd->b[0] =3D cpu_ldub_data(env, addr + (7 << DF_BYTE)); + pwd->b[1] =3D cpu_ldub_data(env, addr + (6 << DF_BYTE)); + pwd->b[2] =3D cpu_ldub_data(env, addr + (5 << DF_BYTE)); + pwd->b[3] =3D cpu_ldub_data(env, addr + (4 << DF_BYTE)); + pwd->b[4] =3D cpu_ldub_data(env, addr + (3 << DF_BYTE)); + pwd->b[5] =3D cpu_ldub_data(env, addr + (2 << DF_BYTE)); + pwd->b[6] =3D cpu_ldub_data(env, addr + (1 << DF_BYTE)); + pwd->b[7] =3D cpu_ldub_data(env, addr + (0 << DF_BYTE)); + pwd->b[8] =3D cpu_ldub_data(env, addr + (15 << DF_BYTE)); + pwd->b[9] =3D cpu_ldub_data(env, addr + (14 << DF_BYTE)); + pwd->b[10] =3D cpu_ldub_data(env, addr + (13 << DF_BYTE)); + pwd->b[11] =3D cpu_ldub_data(env, addr + (12 << DF_BYTE)); + pwd->b[12] =3D cpu_ldub_data(env, addr + (11 << DF_BYTE)); + pwd->b[13] =3D cpu_ldub_data(env, addr + (10 << DF_BYTE)); + pwd->b[14] =3D cpu_ldub_data(env, addr + (9 << DF_BYTE)); + pwd->b[15] =3D cpu_ldub_data(env, addr + (8 << DF_BYTE)); +#endif +#endif +} + +void helper_msa_ld_h(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); + MEMOP_IDX(DF_HALF) +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->h[0] =3D helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETP= C()); + pwd->h[1] =3D helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETP= C()); + pwd->h[2] =3D helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETP= C()); + pwd->h[3] =3D helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETP= C()); + pwd->h[4] =3D helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETP= C()); + pwd->h[5] =3D helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETP= C()); + pwd->h[6] =3D helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETP= C()); + pwd->h[7] =3D helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETP= C()); +#else + pwd->h[0] =3D helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETP= C()); + pwd->h[1] =3D helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETP= C()); + pwd->h[2] =3D helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETP= C()); + pwd->h[3] =3D helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETP= C()); + pwd->h[4] =3D helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETP= C()); + pwd->h[5] =3D helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETP= C()); + pwd->h[6] =3D helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETP= C()); + pwd->h[7] =3D helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETP= C()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->h[0] =3D cpu_lduw_data(env, addr + (0 << DF_HALF)); + pwd->h[1] =3D cpu_lduw_data(env, addr + (1 << DF_HALF)); + pwd->h[2] =3D cpu_lduw_data(env, addr + (2 << DF_HALF)); + pwd->h[3] =3D cpu_lduw_data(env, addr + (3 << DF_HALF)); + pwd->h[4] =3D cpu_lduw_data(env, addr + (4 << DF_HALF)); + pwd->h[5] =3D cpu_lduw_data(env, addr + (5 << DF_HALF)); + pwd->h[6] =3D cpu_lduw_data(env, addr + (6 << DF_HALF)); + pwd->h[7] =3D cpu_lduw_data(env, addr + (7 << DF_HALF)); +#else + pwd->h[0] =3D cpu_lduw_data(env, addr + (3 << DF_HALF)); + pwd->h[1] =3D cpu_lduw_data(env, addr + (2 << DF_HALF)); + pwd->h[2] =3D cpu_lduw_data(env, addr + (1 << DF_HALF)); + pwd->h[3] =3D cpu_lduw_data(env, addr + (0 << DF_HALF)); + pwd->h[4] =3D cpu_lduw_data(env, addr + (7 << DF_HALF)); + pwd->h[5] =3D cpu_lduw_data(env, addr + (6 << DF_HALF)); + pwd->h[6] =3D cpu_lduw_data(env, addr + (5 << DF_HALF)); + pwd->h[7] =3D cpu_lduw_data(env, addr + (4 << DF_HALF)); +#endif +#endif +} + +void helper_msa_ld_w(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); + MEMOP_IDX(DF_WORD) +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->w[0] =3D helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETP= C()); + pwd->w[1] =3D helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETP= C()); + pwd->w[2] =3D helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETP= C()); + pwd->w[3] =3D helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETP= C()); +#else + pwd->w[0] =3D helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETP= C()); + pwd->w[1] =3D helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETP= C()); + pwd->w[2] =3D helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETP= C()); + pwd->w[3] =3D helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETP= C()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->w[0] =3D cpu_ldl_data(env, addr + (0 << DF_WORD)); + pwd->w[1] =3D cpu_ldl_data(env, addr + (1 << DF_WORD)); + pwd->w[2] =3D cpu_ldl_data(env, addr + (2 << DF_WORD)); + pwd->w[3] =3D cpu_ldl_data(env, addr + (3 << DF_WORD)); +#else + pwd->w[0] =3D cpu_ldl_data(env, addr + (1 << DF_WORD)); + pwd->w[1] =3D cpu_ldl_data(env, addr + (0 << DF_WORD)); + pwd->w[2] =3D cpu_ldl_data(env, addr + (3 << DF_WORD)); + pwd->w[3] =3D cpu_ldl_data(env, addr + (2 << DF_WORD)); +#endif +#endif +} + +void helper_msa_ld_d(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); + MEMOP_IDX(DF_DOUBLE) +#if !defined(CONFIG_USER_ONLY) + pwd->d[0] =3D helper_ret_ldq_mmu(env, addr + (0 << DF_DOUBLE), oi, GET= PC()); + pwd->d[1] =3D helper_ret_ldq_mmu(env, addr + (1 << DF_DOUBLE), oi, GET= PC()); +#else + pwd->d[0] =3D cpu_ldq_data(env, addr + (0 << DF_DOUBLE)); + pwd->d[1] =3D cpu_ldq_data(env, addr + (1 << DF_DOUBLE)); +#endif +} + +#define MSA_PAGESPAN(x) \ + ((((x) & ~TARGET_PAGE_MASK) + MSA_WRLEN / 8 - 1) >=3D TARGET_PAGE_= SIZE) + +static inline void ensure_writable_pages(CPUMIPSState *env, + target_ulong addr, + int mmu_idx, + uintptr_t retaddr) +{ + /* FIXME: Probe the actual accesses (pass and use a size) */ + if (unlikely(MSA_PAGESPAN(addr))) { + /* first page */ + probe_write(env, addr, 0, mmu_idx, retaddr); + /* second page */ + addr =3D (addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; + probe_write(env, addr, 0, mmu_idx, retaddr); + } +} + +void helper_msa_st_b(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); + int mmu_idx =3D cpu_mmu_index(env, false); + + MEMOP_IDX(DF_BYTE) + ensure_writable_pages(env, addr, mmu_idx, GETPC()); +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + helper_ret_stb_mmu(env, addr + (0 << DF_BYTE), pwd->b[0], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (1 << DF_BYTE), pwd->b[1], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (2 << DF_BYTE), pwd->b[2], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (3 << DF_BYTE), pwd->b[3], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (4 << DF_BYTE), pwd->b[4], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (5 << DF_BYTE), pwd->b[5], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (6 << DF_BYTE), pwd->b[6], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (7 << DF_BYTE), pwd->b[7], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (8 << DF_BYTE), pwd->b[8], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (9 << DF_BYTE), pwd->b[9], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[10], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[11], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[12], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[13], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[14], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[15], oi, GETPC(= )); +#else + helper_ret_stb_mmu(env, addr + (7 << DF_BYTE), pwd->b[0], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (6 << DF_BYTE), pwd->b[1], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (5 << DF_BYTE), pwd->b[2], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (4 << DF_BYTE), pwd->b[3], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (3 << DF_BYTE), pwd->b[4], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (2 << DF_BYTE), pwd->b[5], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (1 << DF_BYTE), pwd->b[6], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (0 << DF_BYTE), pwd->b[7], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[8], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[9], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[10], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[11], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[12], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[13], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (9 << DF_BYTE), pwd->b[14], oi, GETPC(= )); + helper_ret_stb_mmu(env, addr + (8 << DF_BYTE), pwd->b[15], oi, GETPC(= )); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + cpu_stb_data(env, addr + (0 << DF_BYTE), pwd->b[0]); + cpu_stb_data(env, addr + (1 << DF_BYTE), pwd->b[1]); + cpu_stb_data(env, addr + (2 << DF_BYTE), pwd->b[2]); + cpu_stb_data(env, addr + (3 << DF_BYTE), pwd->b[3]); + cpu_stb_data(env, addr + (4 << DF_BYTE), pwd->b[4]); + cpu_stb_data(env, addr + (5 << DF_BYTE), pwd->b[5]); + cpu_stb_data(env, addr + (6 << DF_BYTE), pwd->b[6]); + cpu_stb_data(env, addr + (7 << DF_BYTE), pwd->b[7]); + cpu_stb_data(env, addr + (8 << DF_BYTE), pwd->b[8]); + cpu_stb_data(env, addr + (9 << DF_BYTE), pwd->b[9]); + cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[10]); + cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[11]); + cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[12]); + cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[13]); + cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[14]); + cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[15]); +#else + cpu_stb_data(env, addr + (7 << DF_BYTE), pwd->b[0]); + cpu_stb_data(env, addr + (6 << DF_BYTE), pwd->b[1]); + cpu_stb_data(env, addr + (5 << DF_BYTE), pwd->b[2]); + cpu_stb_data(env, addr + (4 << DF_BYTE), pwd->b[3]); + cpu_stb_data(env, addr + (3 << DF_BYTE), pwd->b[4]); + cpu_stb_data(env, addr + (2 << DF_BYTE), pwd->b[5]); + cpu_stb_data(env, addr + (1 << DF_BYTE), pwd->b[6]); + cpu_stb_data(env, addr + (0 << DF_BYTE), pwd->b[7]); + cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[8]); + cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[9]); + cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[10]); + cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[11]); + cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[12]); + cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[13]); + cpu_stb_data(env, addr + (9 << DF_BYTE), pwd->b[14]); + cpu_stb_data(env, addr + (8 << DF_BYTE), pwd->b[15]); +#endif +#endif +} + +void helper_msa_st_h(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); + int mmu_idx =3D cpu_mmu_index(env, false); + + MEMOP_IDX(DF_HALF) + ensure_writable_pages(env, addr, mmu_idx, GETPC()); +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[0], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[1], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[2], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[3], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[4], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[5], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[6], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[7], oi, GETPC()); +#else + helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[0], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[1], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[2], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[3], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[4], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[5], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[6], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[7], oi, GETPC()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[0]); + cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[1]); + cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[2]); + cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[3]); + cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[4]); + cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[5]); + cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[6]); + cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[7]); +#else + cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[0]); + cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[1]); + cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[2]); + cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[3]); + cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[4]); + cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[5]); + cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[6]); + cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[7]); +#endif +#endif +} + +void helper_msa_st_w(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); + int mmu_idx =3D cpu_mmu_index(env, false); + + MEMOP_IDX(DF_WORD) + ensure_writable_pages(env, addr, mmu_idx, GETPC()); +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + helper_ret_stl_mmu(env, addr + (0 << DF_WORD), pwd->w[0], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (1 << DF_WORD), pwd->w[1], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (2 << DF_WORD), pwd->w[2], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (3 << DF_WORD), pwd->w[3], oi, GETPC()); +#else + helper_ret_stl_mmu(env, addr + (1 << DF_WORD), pwd->w[0], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (0 << DF_WORD), pwd->w[1], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (3 << DF_WORD), pwd->w[2], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (2 << DF_WORD), pwd->w[3], oi, GETPC()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[0]); + cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[1]); + cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[2]); + cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[3]); +#else + cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[0]); + cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[1]); + cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[2]); + cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[3]); +#endif +#endif +} + +void helper_msa_st_d(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); + int mmu_idx =3D cpu_mmu_index(env, false); + + MEMOP_IDX(DF_DOUBLE) + ensure_writable_pages(env, addr, mmu_idx, GETPC()); +#if !defined(CONFIG_USER_ONLY) + helper_ret_stq_mmu(env, addr + (0 << DF_DOUBLE), pwd->d[0], oi, GETPC(= )); + helper_ret_stq_mmu(env, addr + (1 << DF_DOUBLE), pwd->d[1], oi, GETPC(= )); +#else + cpu_stq_data(env, addr + (0 << DF_DOUBLE), pwd->d[0]); + cpu_stq_data(env, addr + (1 << DF_DOUBLE), pwd->d[1]); +#endif +} diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 5184a1838be..dd09a4c714a 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -1178,399 +1178,6 @@ void mips_cpu_do_transaction_failed(CPUState *cs, h= waddr physaddr, #endif /* !CONFIG_USER_ONLY */ =20 =20 -/* MSA */ -/* Data format min and max values */ -#define DF_BITS(df) (1 << ((df) + 3)) - -/* Element-by-element access macros */ -#define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df)) - -#if !defined(CONFIG_USER_ONLY) -#define MEMOP_IDX(DF) \ - TCGMemOpIdx oi =3D make_memop_idx(MO_TE | DF | MO_UNALN, \ - cpu_mmu_index(env, false)); -#else -#define MEMOP_IDX(DF) -#endif - -void helper_msa_ld_b(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); - MEMOP_IDX(DF_BYTE) -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->b[0] =3D helper_ret_ldub_mmu(env, addr + (0 << DF_BYTE), oi, GE= TPC()); - pwd->b[1] =3D helper_ret_ldub_mmu(env, addr + (1 << DF_BYTE), oi, GE= TPC()); - pwd->b[2] =3D helper_ret_ldub_mmu(env, addr + (2 << DF_BYTE), oi, GE= TPC()); - pwd->b[3] =3D helper_ret_ldub_mmu(env, addr + (3 << DF_BYTE), oi, GE= TPC()); - pwd->b[4] =3D helper_ret_ldub_mmu(env, addr + (4 << DF_BYTE), oi, GE= TPC()); - pwd->b[5] =3D helper_ret_ldub_mmu(env, addr + (5 << DF_BYTE), oi, GE= TPC()); - pwd->b[6] =3D helper_ret_ldub_mmu(env, addr + (6 << DF_BYTE), oi, GE= TPC()); - pwd->b[7] =3D helper_ret_ldub_mmu(env, addr + (7 << DF_BYTE), oi, GE= TPC()); - pwd->b[8] =3D helper_ret_ldub_mmu(env, addr + (8 << DF_BYTE), oi, GE= TPC()); - pwd->b[9] =3D helper_ret_ldub_mmu(env, addr + (9 << DF_BYTE), oi, GE= TPC()); - pwd->b[10] =3D helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GE= TPC()); - pwd->b[11] =3D helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GE= TPC()); - pwd->b[12] =3D helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GE= TPC()); - pwd->b[13] =3D helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GE= TPC()); - pwd->b[14] =3D helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GE= TPC()); - pwd->b[15] =3D helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GE= TPC()); -#else - pwd->b[0] =3D helper_ret_ldub_mmu(env, addr + (7 << DF_BYTE), oi, GE= TPC()); - pwd->b[1] =3D helper_ret_ldub_mmu(env, addr + (6 << DF_BYTE), oi, GE= TPC()); - pwd->b[2] =3D helper_ret_ldub_mmu(env, addr + (5 << DF_BYTE), oi, GE= TPC()); - pwd->b[3] =3D helper_ret_ldub_mmu(env, addr + (4 << DF_BYTE), oi, GE= TPC()); - pwd->b[4] =3D helper_ret_ldub_mmu(env, addr + (3 << DF_BYTE), oi, GE= TPC()); - pwd->b[5] =3D helper_ret_ldub_mmu(env, addr + (2 << DF_BYTE), oi, GE= TPC()); - pwd->b[6] =3D helper_ret_ldub_mmu(env, addr + (1 << DF_BYTE), oi, GE= TPC()); - pwd->b[7] =3D helper_ret_ldub_mmu(env, addr + (0 << DF_BYTE), oi, GE= TPC()); - pwd->b[8] =3D helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GE= TPC()); - pwd->b[9] =3D helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GE= TPC()); - pwd->b[10] =3D helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GE= TPC()); - pwd->b[11] =3D helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GE= TPC()); - pwd->b[12] =3D helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GE= TPC()); - pwd->b[13] =3D helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GE= TPC()); - pwd->b[14] =3D helper_ret_ldub_mmu(env, addr + (9 << DF_BYTE), oi, GE= TPC()); - pwd->b[15] =3D helper_ret_ldub_mmu(env, addr + (8 << DF_BYTE), oi, GE= TPC()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->b[0] =3D cpu_ldub_data(env, addr + (0 << DF_BYTE)); - pwd->b[1] =3D cpu_ldub_data(env, addr + (1 << DF_BYTE)); - pwd->b[2] =3D cpu_ldub_data(env, addr + (2 << DF_BYTE)); - pwd->b[3] =3D cpu_ldub_data(env, addr + (3 << DF_BYTE)); - pwd->b[4] =3D cpu_ldub_data(env, addr + (4 << DF_BYTE)); - pwd->b[5] =3D cpu_ldub_data(env, addr + (5 << DF_BYTE)); - pwd->b[6] =3D cpu_ldub_data(env, addr + (6 << DF_BYTE)); - pwd->b[7] =3D cpu_ldub_data(env, addr + (7 << DF_BYTE)); - pwd->b[8] =3D cpu_ldub_data(env, addr + (8 << DF_BYTE)); - pwd->b[9] =3D cpu_ldub_data(env, addr + (9 << DF_BYTE)); - pwd->b[10] =3D cpu_ldub_data(env, addr + (10 << DF_BYTE)); - pwd->b[11] =3D cpu_ldub_data(env, addr + (11 << DF_BYTE)); - pwd->b[12] =3D cpu_ldub_data(env, addr + (12 << DF_BYTE)); - pwd->b[13] =3D cpu_ldub_data(env, addr + (13 << DF_BYTE)); - pwd->b[14] =3D cpu_ldub_data(env, addr + (14 << DF_BYTE)); - pwd->b[15] =3D cpu_ldub_data(env, addr + (15 << DF_BYTE)); -#else - pwd->b[0] =3D cpu_ldub_data(env, addr + (7 << DF_BYTE)); - pwd->b[1] =3D cpu_ldub_data(env, addr + (6 << DF_BYTE)); - pwd->b[2] =3D cpu_ldub_data(env, addr + (5 << DF_BYTE)); - pwd->b[3] =3D cpu_ldub_data(env, addr + (4 << DF_BYTE)); - pwd->b[4] =3D cpu_ldub_data(env, addr + (3 << DF_BYTE)); - pwd->b[5] =3D cpu_ldub_data(env, addr + (2 << DF_BYTE)); - pwd->b[6] =3D cpu_ldub_data(env, addr + (1 << DF_BYTE)); - pwd->b[7] =3D cpu_ldub_data(env, addr + (0 << DF_BYTE)); - pwd->b[8] =3D cpu_ldub_data(env, addr + (15 << DF_BYTE)); - pwd->b[9] =3D cpu_ldub_data(env, addr + (14 << DF_BYTE)); - pwd->b[10] =3D cpu_ldub_data(env, addr + (13 << DF_BYTE)); - pwd->b[11] =3D cpu_ldub_data(env, addr + (12 << DF_BYTE)); - pwd->b[12] =3D cpu_ldub_data(env, addr + (11 << DF_BYTE)); - pwd->b[13] =3D cpu_ldub_data(env, addr + (10 << DF_BYTE)); - pwd->b[14] =3D cpu_ldub_data(env, addr + (9 << DF_BYTE)); - pwd->b[15] =3D cpu_ldub_data(env, addr + (8 << DF_BYTE)); -#endif -#endif -} - -void helper_msa_ld_h(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); - MEMOP_IDX(DF_HALF) -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->h[0] =3D helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETP= C()); - pwd->h[1] =3D helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETP= C()); - pwd->h[2] =3D helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETP= C()); - pwd->h[3] =3D helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETP= C()); - pwd->h[4] =3D helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETP= C()); - pwd->h[5] =3D helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETP= C()); - pwd->h[6] =3D helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETP= C()); - pwd->h[7] =3D helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETP= C()); -#else - pwd->h[0] =3D helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETP= C()); - pwd->h[1] =3D helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETP= C()); - pwd->h[2] =3D helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETP= C()); - pwd->h[3] =3D helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETP= C()); - pwd->h[4] =3D helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETP= C()); - pwd->h[5] =3D helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETP= C()); - pwd->h[6] =3D helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETP= C()); - pwd->h[7] =3D helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETP= C()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->h[0] =3D cpu_lduw_data(env, addr + (0 << DF_HALF)); - pwd->h[1] =3D cpu_lduw_data(env, addr + (1 << DF_HALF)); - pwd->h[2] =3D cpu_lduw_data(env, addr + (2 << DF_HALF)); - pwd->h[3] =3D cpu_lduw_data(env, addr + (3 << DF_HALF)); - pwd->h[4] =3D cpu_lduw_data(env, addr + (4 << DF_HALF)); - pwd->h[5] =3D cpu_lduw_data(env, addr + (5 << DF_HALF)); - pwd->h[6] =3D cpu_lduw_data(env, addr + (6 << DF_HALF)); - pwd->h[7] =3D cpu_lduw_data(env, addr + (7 << DF_HALF)); -#else - pwd->h[0] =3D cpu_lduw_data(env, addr + (3 << DF_HALF)); - pwd->h[1] =3D cpu_lduw_data(env, addr + (2 << DF_HALF)); - pwd->h[2] =3D cpu_lduw_data(env, addr + (1 << DF_HALF)); - pwd->h[3] =3D cpu_lduw_data(env, addr + (0 << DF_HALF)); - pwd->h[4] =3D cpu_lduw_data(env, addr + (7 << DF_HALF)); - pwd->h[5] =3D cpu_lduw_data(env, addr + (6 << DF_HALF)); - pwd->h[6] =3D cpu_lduw_data(env, addr + (5 << DF_HALF)); - pwd->h[7] =3D cpu_lduw_data(env, addr + (4 << DF_HALF)); -#endif -#endif -} - -void helper_msa_ld_w(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); - MEMOP_IDX(DF_WORD) -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->w[0] =3D helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETP= C()); - pwd->w[1] =3D helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETP= C()); - pwd->w[2] =3D helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETP= C()); - pwd->w[3] =3D helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETP= C()); -#else - pwd->w[0] =3D helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETP= C()); - pwd->w[1] =3D helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETP= C()); - pwd->w[2] =3D helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETP= C()); - pwd->w[3] =3D helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETP= C()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->w[0] =3D cpu_ldl_data(env, addr + (0 << DF_WORD)); - pwd->w[1] =3D cpu_ldl_data(env, addr + (1 << DF_WORD)); - pwd->w[2] =3D cpu_ldl_data(env, addr + (2 << DF_WORD)); - pwd->w[3] =3D cpu_ldl_data(env, addr + (3 << DF_WORD)); -#else - pwd->w[0] =3D cpu_ldl_data(env, addr + (1 << DF_WORD)); - pwd->w[1] =3D cpu_ldl_data(env, addr + (0 << DF_WORD)); - pwd->w[2] =3D cpu_ldl_data(env, addr + (3 << DF_WORD)); - pwd->w[3] =3D cpu_ldl_data(env, addr + (2 << DF_WORD)); -#endif -#endif -} - -void helper_msa_ld_d(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); - MEMOP_IDX(DF_DOUBLE) -#if !defined(CONFIG_USER_ONLY) - pwd->d[0] =3D helper_ret_ldq_mmu(env, addr + (0 << DF_DOUBLE), oi, GET= PC()); - pwd->d[1] =3D helper_ret_ldq_mmu(env, addr + (1 << DF_DOUBLE), oi, GET= PC()); -#else - pwd->d[0] =3D cpu_ldq_data(env, addr + (0 << DF_DOUBLE)); - pwd->d[1] =3D cpu_ldq_data(env, addr + (1 << DF_DOUBLE)); -#endif -} - -#define MSA_PAGESPAN(x) \ - ((((x) & ~TARGET_PAGE_MASK) + MSA_WRLEN / 8 - 1) >=3D TARGET_PAGE_= SIZE) - -static inline void ensure_writable_pages(CPUMIPSState *env, - target_ulong addr, - int mmu_idx, - uintptr_t retaddr) -{ - /* FIXME: Probe the actual accesses (pass and use a size) */ - if (unlikely(MSA_PAGESPAN(addr))) { - /* first page */ - probe_write(env, addr, 0, mmu_idx, retaddr); - /* second page */ - addr =3D (addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; - probe_write(env, addr, 0, mmu_idx, retaddr); - } -} - -void helper_msa_st_b(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); - int mmu_idx =3D cpu_mmu_index(env, false); - - MEMOP_IDX(DF_BYTE) - ensure_writable_pages(env, addr, mmu_idx, GETPC()); -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - helper_ret_stb_mmu(env, addr + (0 << DF_BYTE), pwd->b[0], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (1 << DF_BYTE), pwd->b[1], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (2 << DF_BYTE), pwd->b[2], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (3 << DF_BYTE), pwd->b[3], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (4 << DF_BYTE), pwd->b[4], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (5 << DF_BYTE), pwd->b[5], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (6 << DF_BYTE), pwd->b[6], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (7 << DF_BYTE), pwd->b[7], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (8 << DF_BYTE), pwd->b[8], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (9 << DF_BYTE), pwd->b[9], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[10], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[11], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[12], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[13], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[14], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[15], oi, GETPC(= )); -#else - helper_ret_stb_mmu(env, addr + (7 << DF_BYTE), pwd->b[0], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (6 << DF_BYTE), pwd->b[1], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (5 << DF_BYTE), pwd->b[2], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (4 << DF_BYTE), pwd->b[3], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (3 << DF_BYTE), pwd->b[4], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (2 << DF_BYTE), pwd->b[5], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (1 << DF_BYTE), pwd->b[6], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (0 << DF_BYTE), pwd->b[7], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[8], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[9], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[10], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[11], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[12], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[13], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (9 << DF_BYTE), pwd->b[14], oi, GETPC(= )); - helper_ret_stb_mmu(env, addr + (8 << DF_BYTE), pwd->b[15], oi, GETPC(= )); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - cpu_stb_data(env, addr + (0 << DF_BYTE), pwd->b[0]); - cpu_stb_data(env, addr + (1 << DF_BYTE), pwd->b[1]); - cpu_stb_data(env, addr + (2 << DF_BYTE), pwd->b[2]); - cpu_stb_data(env, addr + (3 << DF_BYTE), pwd->b[3]); - cpu_stb_data(env, addr + (4 << DF_BYTE), pwd->b[4]); - cpu_stb_data(env, addr + (5 << DF_BYTE), pwd->b[5]); - cpu_stb_data(env, addr + (6 << DF_BYTE), pwd->b[6]); - cpu_stb_data(env, addr + (7 << DF_BYTE), pwd->b[7]); - cpu_stb_data(env, addr + (8 << DF_BYTE), pwd->b[8]); - cpu_stb_data(env, addr + (9 << DF_BYTE), pwd->b[9]); - cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[10]); - cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[11]); - cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[12]); - cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[13]); - cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[14]); - cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[15]); -#else - cpu_stb_data(env, addr + (7 << DF_BYTE), pwd->b[0]); - cpu_stb_data(env, addr + (6 << DF_BYTE), pwd->b[1]); - cpu_stb_data(env, addr + (5 << DF_BYTE), pwd->b[2]); - cpu_stb_data(env, addr + (4 << DF_BYTE), pwd->b[3]); - cpu_stb_data(env, addr + (3 << DF_BYTE), pwd->b[4]); - cpu_stb_data(env, addr + (2 << DF_BYTE), pwd->b[5]); - cpu_stb_data(env, addr + (1 << DF_BYTE), pwd->b[6]); - cpu_stb_data(env, addr + (0 << DF_BYTE), pwd->b[7]); - cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[8]); - cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[9]); - cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[10]); - cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[11]); - cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[12]); - cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[13]); - cpu_stb_data(env, addr + (9 << DF_BYTE), pwd->b[14]); - cpu_stb_data(env, addr + (8 << DF_BYTE), pwd->b[15]); -#endif -#endif -} - -void helper_msa_st_h(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); - int mmu_idx =3D cpu_mmu_index(env, false); - - MEMOP_IDX(DF_HALF) - ensure_writable_pages(env, addr, mmu_idx, GETPC()); -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[0], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[1], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[2], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[3], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[4], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[5], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[6], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[7], oi, GETPC()); -#else - helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[0], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[1], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[2], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[3], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[4], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[5], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[6], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[7], oi, GETPC()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[0]); - cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[1]); - cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[2]); - cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[3]); - cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[4]); - cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[5]); - cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[6]); - cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[7]); -#else - cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[0]); - cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[1]); - cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[2]); - cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[3]); - cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[4]); - cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[5]); - cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[6]); - cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[7]); -#endif -#endif -} - -void helper_msa_st_w(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); - int mmu_idx =3D cpu_mmu_index(env, false); - - MEMOP_IDX(DF_WORD) - ensure_writable_pages(env, addr, mmu_idx, GETPC()); -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - helper_ret_stl_mmu(env, addr + (0 << DF_WORD), pwd->w[0], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (1 << DF_WORD), pwd->w[1], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (2 << DF_WORD), pwd->w[2], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (3 << DF_WORD), pwd->w[3], oi, GETPC()); -#else - helper_ret_stl_mmu(env, addr + (1 << DF_WORD), pwd->w[0], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (0 << DF_WORD), pwd->w[1], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (3 << DF_WORD), pwd->w[2], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (2 << DF_WORD), pwd->w[3], oi, GETPC()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[0]); - cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[1]); - cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[2]); - cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[3]); -#else - cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[0]); - cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[1]); - cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[2]); - cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[3]); -#endif -#endif -} - -void helper_msa_st_d(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd =3D &(env->active_fpu.fpr[wd].wr); - int mmu_idx =3D cpu_mmu_index(env, false); - - MEMOP_IDX(DF_DOUBLE) - ensure_writable_pages(env, addr, mmu_idx, GETPC()); -#if !defined(CONFIG_USER_ONLY) - helper_ret_stq_mmu(env, addr + (0 << DF_DOUBLE), pwd->d[0], oi, GETPC(= )); - helper_ret_stq_mmu(env, addr + (1 << DF_DOUBLE), pwd->d[1], oi, GETPC(= )); -#else - cpu_stq_data(env, addr + (0 << DF_DOUBLE), pwd->d[0]); - cpu_stq_data(env, addr + (1 << DF_DOUBLE), pwd->d[1]); -#endif -} - void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op) { #ifndef CONFIG_USER_ONLY diff --git a/target/mips/meson.build b/target/mips/meson.build index 681a5524c0e..f2b1b599abc 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -6,8 +6,9 @@ 'gdbstub.c', 'helper.c', 'lmmi_helper.c', - 'msa_helper.c', 'op_helper.c', + 'mod-mips-msa_helper.c', + 'translate.c', )) mips_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.41 as permitted sender) client-ip=209.85.221.41; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f41.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.41 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906544; cv=none; d=zohomail.com; s=zohoarc; b=jxtgDLZAIiECJEvF5264MwkUsj0x+jqqOwAbyL4/qANv0yXHNIZHGv8KibRNJmlRfIMxuBoE6EFuNr4wuRdht/DG7CGaAdkF6a6x1pIjtLiH0s9o8mG33z8N/zepccSMlTYcfRDDU+4b5PLrbS11DBRqwlYQds+7V9ola1lVjZ0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906544; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=NFuue+LTHum6VoJqYKvYdWIpH/gw7xw5rZVXgy/xi24=; b=RxjLt9w4BQitpKRczIz7QqvQuO1pPW4AHBEo8pP4AfdvaSlYCV4RybJsH701UECjs7TjL42uhCSx2OielVcr69FZnjfEBI/xliaJdH8HzKFtWm4AG1L0pGk6OKQnaVVwCl7Ifi560K15w11f32+kRiERoTGcxYanC8d/pxeo71I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.41 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) by mx.zohomail.com with SMTPS id 1605906544920414.92602510735753; Fri, 20 Nov 2020 13:09:04 -0800 (PST) Received: by mail-wr1-f41.google.com with SMTP id d12so11614951wrr.13 for ; Fri, 20 Nov 2020 13:09:04 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id f2sm6738132wre.63.2020.11.20.13.09.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NFuue+LTHum6VoJqYKvYdWIpH/gw7xw5rZVXgy/xi24=; b=GAsy7mdyl6zHsrVKjG1tONRaq8KrkjbtGkDpWy/Yh5wDLZWyRZKif6Q7GlXQRo9vre CvUjZunNH8qZ1mZWAHkAWmy6XfkHHzB1H9Vp2fDlXVHF6kKtH2zpL5iZ/YYHwmbqJjxy QQtZNOMbq5QrOOupmuaLqON1NNDuiskY3cSuOTe1GDCPORxN0oljyD+mzniPZGqlFFBN g4U+F8y3hQVBzC4J0s8msRPqO2FTOStezERWjOA0jlQg6mZHECtefuJbAby9oE0efqnz SVHBq5LOdn1nX5tHkdXa8/vPcS4dzGvxvXV71AOhuWCr8LaX0CcRrqBlo4aF3J7kND7l 4k0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=NFuue+LTHum6VoJqYKvYdWIpH/gw7xw5rZVXgy/xi24=; b=qeJienTK/kwMaOR4V83cxRfUJA76exELMUAYZLy4gSXoa+0tly/ohfQgG7FRsOr9G6 aT1L48oxITV8UDkaJh8cYMwnvzk5rfepGfuctuIDpgPmf7TpU491e1A41YSPh7nZF5e3 NIZv0x+Ll9ZK+cnvxkPS7BcSDTzwAjrmXrNvemD0DH/YEkmj0A7eEtXnKmZ8STshbysr Vm9g9CKwe4JoOjJb+NhTRx8XtWbhsj5TQJ/6DvcqYtQoBxm60Lkx0V/f6TKntaUpt65n SYIP/Gx8r021YES6Xuaf5KfyKiAZFjWEWZit8ncDSg8H1UApePt7NEvV3YtSP22L/v4q bxSw== X-Gm-Message-State: AOAM531JdiHTe4VGpbqUmn595Ea8wUgwmQovu+s1ODmdca6j3u3dmPo9 CQ8Ivhx+6nSm1P4AJ1Mcu90= X-Google-Smtp-Source: ABdhPJwaP6EVW9PfGYZIPWoNDIY2/5VkCNsyAeMzh84yswQ10qVgR1JFT3ebSDrnj5rX+FjcuWdTrg== X-Received: by 2002:adf:eb08:: with SMTP id s8mr19212697wrn.12.1605906542531; Fri, 20 Nov 2020 13:09:02 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 03/26] target/mips: Extract MSA helper definitions Date: Fri, 20 Nov 2020 22:08:21 +0100 Message-Id: <20201120210844.2625602-4-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Keep all MSA-related code altogether. Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/helper.h | 437 +------------------------ target/mips/mod-mips-msa_helper.h.inc | 443 ++++++++++++++++++++++++++ 2 files changed, 446 insertions(+), 434 deletions(-) create mode 100644 target/mips/mod-mips-msa_helper.h.inc diff --git a/target/mips/helper.h b/target/mips/helper.h index e97655dc0eb..a44f42c6201 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -781,438 +781,7 @@ DEF_HELPER_FLAGS_3(dmthlip, 0, void, tl, tl, env) DEF_HELPER_FLAGS_3(wrdsp, 0, void, tl, tl, env) DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env) =20 -/* MIPS SIMD Architecture */ - -DEF_HELPER_3(msa_nloc_b, void, env, i32, i32) -DEF_HELPER_3(msa_nloc_h, void, env, i32, i32) -DEF_HELPER_3(msa_nloc_w, void, env, i32, i32) -DEF_HELPER_3(msa_nloc_d, void, env, i32, i32) - -DEF_HELPER_3(msa_nlzc_b, void, env, i32, i32) -DEF_HELPER_3(msa_nlzc_h, void, env, i32, i32) -DEF_HELPER_3(msa_nlzc_w, void, env, i32, i32) -DEF_HELPER_3(msa_nlzc_d, void, env, i32, i32) - -DEF_HELPER_3(msa_pcnt_b, void, env, i32, i32) -DEF_HELPER_3(msa_pcnt_h, void, env, i32, i32) -DEF_HELPER_3(msa_pcnt_w, void, env, i32, i32) -DEF_HELPER_3(msa_pcnt_d, void, env, i32, i32) - -DEF_HELPER_4(msa_binsl_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsl_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsl_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsl_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_binsr_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsr_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsr_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsr_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_bclr_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bclr_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bclr_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bclr_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_bneg_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bneg_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bneg_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bneg_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_bset_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bset_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bset_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bset_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_add_a_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_add_a_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_add_a_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_add_a_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_adds_a_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_a_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_a_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_a_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_adds_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_adds_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_addv_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_addv_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_addv_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_addv_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_hadd_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hadd_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hadd_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_hadd_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hadd_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hadd_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_ave_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_ave_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_aver_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_aver_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_ceq_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ceq_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ceq_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ceq_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_cle_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_cle_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_clt_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_clt_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_div_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_div_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_max_a_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_a_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_a_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_a_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_u_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_a_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_a_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_a_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_a_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_mod_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_mod_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_maddv_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_maddv_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_maddv_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_maddv_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_msubv_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_msubv_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_msubv_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_msubv_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_mulv_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mulv_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mulv_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mulv_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_asub_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_asub_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_hsub_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hsub_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hsub_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_hsub_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hsub_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hsub_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_subs_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_subs_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_subsus_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsus_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsus_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsus_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_subsuu_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsuu_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsuu_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsuu_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_subv_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subv_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subv_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subv_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_ilvev_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvev_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvev_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvev_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvod_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvod_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvod_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvod_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvl_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvl_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvl_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvl_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvr_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvr_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvr_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvr_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_and_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_xor_v, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_pckev_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckev_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckev_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckev_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckod_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckod_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckod_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckod_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_sll_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sll_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sll_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sll_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_sra_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sra_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sra_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sra_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_srar_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srar_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srar_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srar_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_srl_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srl_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srl_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srl_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_srlr_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srlr_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srlr_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srlr_d, void, env, i32, i32, i32) - -DEF_HELPER_3(msa_move_v, void, env, i32, i32) - -DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_xori_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bmnzi_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bmzi_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bseli_b, void, env, i32, i32, i32) -DEF_HELPER_5(msa_shf_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_5(msa_addvi_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_subvi_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_maxi_s_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_maxi_u_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_mini_s_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_mini_u_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_ceqi_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_clti_s_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_clti_u_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_clei_s_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_clei_u_df, void, env, i32, i32, i32, s32) -DEF_HELPER_4(msa_ldi_df, void, env, i32, i32, s32) - -DEF_HELPER_5(msa_slli_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srai_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srli_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_bclri_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_bseti_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_bnegi_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_binsli_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_binsri_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_sat_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_sat_u_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srari_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srlri_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_5(msa_binsl_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_binsr_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_4(msa_dotp_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dotp_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dotp_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dotp_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dotp_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dotp_u_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_u_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_u_d, void, env, i32, i32, i32) -DEF_HELPER_5(msa_sld_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_splat_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32) -DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32) -DEF_HELPER_2(msa_cfcmsa, tl, env, i32) - -DEF_HELPER_5(msa_fcaf_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcun_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fceq_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcueq_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fclt_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcult_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcle_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcule_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsaf_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsun_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fseq_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsueq_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fslt_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsult_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsle_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsule_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fadd_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsub_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmul_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fdiv_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmadd_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmsub_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fexp2_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fexdo_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_ftq_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmin_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmin_a_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmax_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmax_a_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcor_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcune_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcne_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_mul_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_madd_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_msub_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsor_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsune_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsne_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_mulr_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_maddr_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_msubr_q_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_insert_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_insert_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_insert_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_insert_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_fsqrt_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_frsqrt_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_frcp_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_frint_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_flog2_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_fexupl_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_fexupr_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ffql_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ffqr_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ftint_s_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ftint_u_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ffint_s_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ffint_u_df, void, env, i32, i32, i32) - -#define MSALDST_PROTO(type) \ -DEF_HELPER_3(msa_ld_ ## type, void, env, i32, tl) \ -DEF_HELPER_3(msa_st_ ## type, void, env, i32, tl) -MSALDST_PROTO(b) -MSALDST_PROTO(h) -MSALDST_PROTO(w) -MSALDST_PROTO(d) -#undef MSALDST_PROTO - DEF_HELPER_3(cache, void, env, tl, i32) + +#include "mod-mips-msa_helper.h.inc" + diff --git a/target/mips/mod-mips-msa_helper.h.inc b/target/mips/mod-mips-m= sa_helper.h.inc new file mode 100644 index 00000000000..4963d1553a0 --- /dev/null +++ b/target/mips/mod-mips-msa_helper.h.inc @@ -0,0 +1,443 @@ +/* + * MIPS SIMD Architecture Module (MSA) helpers for QEMU. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +DEF_HELPER_3(msa_nloc_b, void, env, i32, i32) +DEF_HELPER_3(msa_nloc_h, void, env, i32, i32) +DEF_HELPER_3(msa_nloc_w, void, env, i32, i32) +DEF_HELPER_3(msa_nloc_d, void, env, i32, i32) + +DEF_HELPER_3(msa_nlzc_b, void, env, i32, i32) +DEF_HELPER_3(msa_nlzc_h, void, env, i32, i32) +DEF_HELPER_3(msa_nlzc_w, void, env, i32, i32) +DEF_HELPER_3(msa_nlzc_d, void, env, i32, i32) + +DEF_HELPER_3(msa_pcnt_b, void, env, i32, i32) +DEF_HELPER_3(msa_pcnt_h, void, env, i32, i32) +DEF_HELPER_3(msa_pcnt_w, void, env, i32, i32) +DEF_HELPER_3(msa_pcnt_d, void, env, i32, i32) + +DEF_HELPER_4(msa_binsl_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsl_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsl_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsl_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_binsr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsr_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_bclr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bclr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bclr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bclr_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_bneg_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bneg_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bneg_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bneg_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_bset_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bset_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bset_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bset_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_add_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_add_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_add_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_add_a_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_adds_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_a_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_adds_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_adds_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_addv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_addv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_addv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_addv_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_hadd_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_hadd_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_ave_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_ave_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_aver_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_aver_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_ceq_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ceq_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ceq_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ceq_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_cle_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_cle_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_clt_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_clt_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_div_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_div_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_max_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_a_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_mod_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_mod_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_maddv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_maddv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_maddv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_maddv_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_msubv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_msubv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_msubv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_msubv_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_mulv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mulv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mulv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mulv_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_asub_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_asub_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_hsub_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_hsub_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_subs_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_subs_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_subsus_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsus_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsus_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsus_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_subsuu_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsuu_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsuu_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsuu_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_subv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subv_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_ilvev_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvev_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvev_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvev_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_and_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_xor_v, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_pckev_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckev_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckev_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckev_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_sll_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sll_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sll_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sll_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_sra_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sra_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sra_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sra_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_srar_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srar_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srar_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srar_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_srl_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srl_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srl_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srl_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_srlr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srlr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srlr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srlr_d, void, env, i32, i32, i32) + +DEF_HELPER_3(msa_move_v, void, env, i32, i32) + +DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_xori_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bmnzi_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bmzi_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bseli_b, void, env, i32, i32, i32) +DEF_HELPER_5(msa_shf_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_5(msa_addvi_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_subvi_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_maxi_s_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_maxi_u_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_mini_s_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_mini_u_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_ceqi_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_clti_s_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_clti_u_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_clei_s_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_clei_u_df, void, env, i32, i32, i32, s32) +DEF_HELPER_4(msa_ldi_df, void, env, i32, i32, s32) + +DEF_HELPER_5(msa_slli_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_srai_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_srli_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_bclri_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_bseti_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_bnegi_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_binsli_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_binsri_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_sat_s_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_sat_u_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_srari_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_srlri_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_5(msa_binsl_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_binsr_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_4(msa_dotp_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dotp_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dotp_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dotp_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dotp_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dotp_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_u_d, void, env, i32, i32, i32) +DEF_HELPER_5(msa_sld_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_splat_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32) +DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32) +DEF_HELPER_2(msa_cfcmsa, tl, env, i32) + +DEF_HELPER_5(msa_fcaf_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcun_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fceq_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcueq_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fclt_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcult_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcle_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcule_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsaf_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsun_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fseq_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsueq_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fslt_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsult_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsle_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsule_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fadd_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsub_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmul_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fdiv_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmadd_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmsub_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fexp2_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fexdo_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_ftq_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmin_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmin_a_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmax_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmax_a_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcor_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcune_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcne_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_mul_q_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_madd_q_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_msub_q_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsor_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsune_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsne_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_mulr_q_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_maddr_q_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_msubr_q_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_fsqrt_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_frsqrt_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_frcp_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_frint_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_flog2_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_fexupl_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_fexupr_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ffql_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ffqr_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ftint_s_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ftint_u_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ffint_s_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ffint_u_df, void, env, i32, i32, i32) + +#define MSALDST_PROTO(type) \ +DEF_HELPER_3(msa_ld_ ## type, void, env, i32, tl) \ +DEF_HELPER_3(msa_st_ ## type, void, env, i32, tl) +MSALDST_PROTO(b) +MSALDST_PROTO(h) +MSALDST_PROTO(w) +MSALDST_PROTO(d) +#undef MSALDST_PROTO --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.52 as permitted sender) client-ip=209.85.128.52; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f52.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.52 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906550; cv=none; d=zohomail.com; s=zohoarc; b=ebqQL7tmWYT+7rf0VqX04yNQz21wtLrp4qdLfgqdHR5ZvOwdnGiw3hBjiAtWYFRAE+8TU+0f4AJi/MxV2hfE+a20a6e79rHOi9Z/2qsRWSl7rlWpW9/PnJDDtubblgMv0JSRSJZc9tKEvi8IJ6WowQQFIQErfY3NdDWX67Y+9Qs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906550; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=QcVY72ZXE1CEgB2rO5JqCuZKI4oLxdnolTz/dg+APdM=; b=BewB/6BjnvztAO2iuPlEFIZKF18vzy2zpg5Uuw4EMD39H8YDI3SVy6BlvdrucJijZPDQHUij2qU1sOv7R8mfoLHVK5TqqRF2qNuAnr2hnFO3qdnir20nXOWgDN25P6XSElkjGlc7YR3zdoDxLyuJiSRGcl+9LkzxvFkPLx82xIA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.52 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) by mx.zohomail.com with SMTPS id 1605906550860154.35065799953964; Fri, 20 Nov 2020 13:09:10 -0800 (PST) Received: by mail-wm1-f52.google.com with SMTP id a65so11257678wme.1 for ; Fri, 20 Nov 2020 13:09:09 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id d10sm6315262wro.89.2020.11.20.13.09.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QcVY72ZXE1CEgB2rO5JqCuZKI4oLxdnolTz/dg+APdM=; b=cINnFYAZiiKrMfP0VBwmRHr8qOLTI8zBImf771XzD4yhkoR7/QORrMlUP/uDbhZiKK WXvA4aPjlXpinaRfkjjd3XW0tTD8CXlf0M0Aiu7O3xS3zDYm0aVuO2GoKTth6gOk4xX3 IqK6WGKjjhWt4L6V0+BUuMiDMVTV68jRFG3N/wm2a9cpD9aV7nmqpypMCp3aDyFbGqT0 Vng8ONBUJTjsXuyP/C5BtwVnmlq+9Fp5F7VmBb4RkuxJX6QOLHeVP4OdRtyUoVvDNmeQ gQJN/n6UdFZ6WAT+II1OtBZsaR11y+Kfm1tS57sYaAgZIeKSgUVf6hr+Kxi0rFajX4ON tROw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=QcVY72ZXE1CEgB2rO5JqCuZKI4oLxdnolTz/dg+APdM=; b=OZ3a6rN9+IRSOSK7MRdhVsT80/cKnKaffFzZjProfs7xkiobrVQ1g1yod9FLo8BcdF fnq2oa50jwr8g9ohN8LWaZGTR8LEmY+hwbDyJdfe2THTtgqcU+YOCqdMiA6KaYNejnxk xqFI5dmPwIRiTGD+UqMvp4jOQHcZ7gXcSti66b8sxhoMbH/5+UJJhJpEk9Z9gHStsyfw CtTN6FRZuDR5WPTn/QfK4t9Ge6B3d+j00NxZQcdnj8rDQKrMN+BnJgVYlV2+T7WVxOUU 3n0wHlwhLLpKN597lkzhv2a1dgIwd/R3lu0s9as7MuT+bFhloGG0nzBLHWY0miACpIxv w9lw== X-Gm-Message-State: AOAM531syrTojvqyA3LLtO45RSvQtWGSvzpfRrOaOrcDjscgZC6gTrMn /3jzjV3vMi25pMQPsJ8WHLs= X-Google-Smtp-Source: ABdhPJwjP0OqroCwfQ2w9bNwVg5soW5aUlwCt6TVXn6YmfgK12G3UpsZpTAG54SL+nEmgesCoFsVHw== X-Received: by 2002:a1c:ab57:: with SMTP id u84mr11329976wme.99.1605906547884; Fri, 20 Nov 2020 13:09:07 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 04/26] target/mips: Extract MSA translation routines Date: Fri, 20 Nov 2020 22:08:22 +0100 Message-Id: <20201120210844.2625602-5-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract 2200 lines from the huge translate.c to a new file, 'mod-mips-msa_translate.c.inc'. As there are too many inter- dependencies we don't compile it as another object, but keep including it in the big translate.o. We gain in code maintainability. Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/translate.c | 2209 +-------------------- target/mips/mod-mips-msa_translate.c.inc | 2218 ++++++++++++++++++++++ 2 files changed, 2219 insertions(+), 2208 deletions(-) create mode 100644 target/mips/mod-mips-msa_translate.c.inc diff --git a/target/mips/translate.c b/target/mips/translate.c index 5ec9fd7e92a..0ad59731810 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1211,239 +1211,6 @@ enum { OPC_NMSUB_PS =3D 0x3E | OPC_CP3, }; =20 -/* MSA Opcodes */ -#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) -enum { - OPC_MSA_I8_00 =3D 0x00 | OPC_MSA, - OPC_MSA_I8_01 =3D 0x01 | OPC_MSA, - OPC_MSA_I8_02 =3D 0x02 | OPC_MSA, - OPC_MSA_I5_06 =3D 0x06 | OPC_MSA, - OPC_MSA_I5_07 =3D 0x07 | OPC_MSA, - OPC_MSA_BIT_09 =3D 0x09 | OPC_MSA, - OPC_MSA_BIT_0A =3D 0x0A | OPC_MSA, - OPC_MSA_3R_0D =3D 0x0D | OPC_MSA, - OPC_MSA_3R_0E =3D 0x0E | OPC_MSA, - OPC_MSA_3R_0F =3D 0x0F | OPC_MSA, - OPC_MSA_3R_10 =3D 0x10 | OPC_MSA, - OPC_MSA_3R_11 =3D 0x11 | OPC_MSA, - OPC_MSA_3R_12 =3D 0x12 | OPC_MSA, - OPC_MSA_3R_13 =3D 0x13 | OPC_MSA, - OPC_MSA_3R_14 =3D 0x14 | OPC_MSA, - OPC_MSA_3R_15 =3D 0x15 | OPC_MSA, - OPC_MSA_ELM =3D 0x19 | OPC_MSA, - OPC_MSA_3RF_1A =3D 0x1A | OPC_MSA, - OPC_MSA_3RF_1B =3D 0x1B | OPC_MSA, - OPC_MSA_3RF_1C =3D 0x1C | OPC_MSA, - OPC_MSA_VEC =3D 0x1E | OPC_MSA, - - /* MI10 instruction */ - OPC_LD_B =3D (0x20) | OPC_MSA, - OPC_LD_H =3D (0x21) | OPC_MSA, - OPC_LD_W =3D (0x22) | OPC_MSA, - OPC_LD_D =3D (0x23) | OPC_MSA, - OPC_ST_B =3D (0x24) | OPC_MSA, - OPC_ST_H =3D (0x25) | OPC_MSA, - OPC_ST_W =3D (0x26) | OPC_MSA, - OPC_ST_D =3D (0x27) | OPC_MSA, -}; - -enum { - /* I5 instruction df(bits 22..21) =3D _b, _h, _w, _d */ - OPC_ADDVI_df =3D (0x0 << 23) | OPC_MSA_I5_06, - OPC_CEQI_df =3D (0x0 << 23) | OPC_MSA_I5_07, - OPC_SUBVI_df =3D (0x1 << 23) | OPC_MSA_I5_06, - OPC_MAXI_S_df =3D (0x2 << 23) | OPC_MSA_I5_06, - OPC_CLTI_S_df =3D (0x2 << 23) | OPC_MSA_I5_07, - OPC_MAXI_U_df =3D (0x3 << 23) | OPC_MSA_I5_06, - OPC_CLTI_U_df =3D (0x3 << 23) | OPC_MSA_I5_07, - OPC_MINI_S_df =3D (0x4 << 23) | OPC_MSA_I5_06, - OPC_CLEI_S_df =3D (0x4 << 23) | OPC_MSA_I5_07, - OPC_MINI_U_df =3D (0x5 << 23) | OPC_MSA_I5_06, - OPC_CLEI_U_df =3D (0x5 << 23) | OPC_MSA_I5_07, - OPC_LDI_df =3D (0x6 << 23) | OPC_MSA_I5_07, - - /* I8 instruction */ - OPC_ANDI_B =3D (0x0 << 24) | OPC_MSA_I8_00, - OPC_BMNZI_B =3D (0x0 << 24) | OPC_MSA_I8_01, - OPC_SHF_B =3D (0x0 << 24) | OPC_MSA_I8_02, - OPC_ORI_B =3D (0x1 << 24) | OPC_MSA_I8_00, - OPC_BMZI_B =3D (0x1 << 24) | OPC_MSA_I8_01, - OPC_SHF_H =3D (0x1 << 24) | OPC_MSA_I8_02, - OPC_NORI_B =3D (0x2 << 24) | OPC_MSA_I8_00, - OPC_BSELI_B =3D (0x2 << 24) | OPC_MSA_I8_01, - OPC_SHF_W =3D (0x2 << 24) | OPC_MSA_I8_02, - OPC_XORI_B =3D (0x3 << 24) | OPC_MSA_I8_00, - - /* VEC/2R/2RF instruction */ - OPC_AND_V =3D (0x00 << 21) | OPC_MSA_VEC, - OPC_OR_V =3D (0x01 << 21) | OPC_MSA_VEC, - OPC_NOR_V =3D (0x02 << 21) | OPC_MSA_VEC, - OPC_XOR_V =3D (0x03 << 21) | OPC_MSA_VEC, - OPC_BMNZ_V =3D (0x04 << 21) | OPC_MSA_VEC, - OPC_BMZ_V =3D (0x05 << 21) | OPC_MSA_VEC, - OPC_BSEL_V =3D (0x06 << 21) | OPC_MSA_VEC, - - OPC_MSA_2R =3D (0x18 << 21) | OPC_MSA_VEC, - OPC_MSA_2RF =3D (0x19 << 21) | OPC_MSA_VEC, - - /* 2R instruction df(bits 17..16) =3D _b, _h, _w, _d */ - OPC_FILL_df =3D (0x00 << 18) | OPC_MSA_2R, - OPC_PCNT_df =3D (0x01 << 18) | OPC_MSA_2R, - OPC_NLOC_df =3D (0x02 << 18) | OPC_MSA_2R, - OPC_NLZC_df =3D (0x03 << 18) | OPC_MSA_2R, - - /* 2RF instruction df(bit 16) =3D _w, _d */ - OPC_FCLASS_df =3D (0x00 << 17) | OPC_MSA_2RF, - OPC_FTRUNC_S_df =3D (0x01 << 17) | OPC_MSA_2RF, - OPC_FTRUNC_U_df =3D (0x02 << 17) | OPC_MSA_2RF, - OPC_FSQRT_df =3D (0x03 << 17) | OPC_MSA_2RF, - OPC_FRSQRT_df =3D (0x04 << 17) | OPC_MSA_2RF, - OPC_FRCP_df =3D (0x05 << 17) | OPC_MSA_2RF, - OPC_FRINT_df =3D (0x06 << 17) | OPC_MSA_2RF, - OPC_FLOG2_df =3D (0x07 << 17) | OPC_MSA_2RF, - OPC_FEXUPL_df =3D (0x08 << 17) | OPC_MSA_2RF, - OPC_FEXUPR_df =3D (0x09 << 17) | OPC_MSA_2RF, - OPC_FFQL_df =3D (0x0A << 17) | OPC_MSA_2RF, - OPC_FFQR_df =3D (0x0B << 17) | OPC_MSA_2RF, - OPC_FTINT_S_df =3D (0x0C << 17) | OPC_MSA_2RF, - OPC_FTINT_U_df =3D (0x0D << 17) | OPC_MSA_2RF, - OPC_FFINT_S_df =3D (0x0E << 17) | OPC_MSA_2RF, - OPC_FFINT_U_df =3D (0x0F << 17) | OPC_MSA_2RF, - - /* 3R instruction df(bits 22..21) =3D _b, _h, _w, d */ - OPC_SLL_df =3D (0x0 << 23) | OPC_MSA_3R_0D, - OPC_ADDV_df =3D (0x0 << 23) | OPC_MSA_3R_0E, - OPC_CEQ_df =3D (0x0 << 23) | OPC_MSA_3R_0F, - OPC_ADD_A_df =3D (0x0 << 23) | OPC_MSA_3R_10, - OPC_SUBS_S_df =3D (0x0 << 23) | OPC_MSA_3R_11, - OPC_MULV_df =3D (0x0 << 23) | OPC_MSA_3R_12, - OPC_DOTP_S_df =3D (0x0 << 23) | OPC_MSA_3R_13, - OPC_SLD_df =3D (0x0 << 23) | OPC_MSA_3R_14, - OPC_VSHF_df =3D (0x0 << 23) | OPC_MSA_3R_15, - OPC_SRA_df =3D (0x1 << 23) | OPC_MSA_3R_0D, - OPC_SUBV_df =3D (0x1 << 23) | OPC_MSA_3R_0E, - OPC_ADDS_A_df =3D (0x1 << 23) | OPC_MSA_3R_10, - OPC_SUBS_U_df =3D (0x1 << 23) | OPC_MSA_3R_11, - OPC_MADDV_df =3D (0x1 << 23) | OPC_MSA_3R_12, - OPC_DOTP_U_df =3D (0x1 << 23) | OPC_MSA_3R_13, - OPC_SPLAT_df =3D (0x1 << 23) | OPC_MSA_3R_14, - OPC_SRAR_df =3D (0x1 << 23) | OPC_MSA_3R_15, - OPC_SRL_df =3D (0x2 << 23) | OPC_MSA_3R_0D, - OPC_MAX_S_df =3D (0x2 << 23) | OPC_MSA_3R_0E, - OPC_CLT_S_df =3D (0x2 << 23) | OPC_MSA_3R_0F, - OPC_ADDS_S_df =3D (0x2 << 23) | OPC_MSA_3R_10, - OPC_SUBSUS_U_df =3D (0x2 << 23) | OPC_MSA_3R_11, - OPC_MSUBV_df =3D (0x2 << 23) | OPC_MSA_3R_12, - OPC_DPADD_S_df =3D (0x2 << 23) | OPC_MSA_3R_13, - OPC_PCKEV_df =3D (0x2 << 23) | OPC_MSA_3R_14, - OPC_SRLR_df =3D (0x2 << 23) | OPC_MSA_3R_15, - OPC_BCLR_df =3D (0x3 << 23) | OPC_MSA_3R_0D, - OPC_MAX_U_df =3D (0x3 << 23) | OPC_MSA_3R_0E, - OPC_CLT_U_df =3D (0x3 << 23) | OPC_MSA_3R_0F, - OPC_ADDS_U_df =3D (0x3 << 23) | OPC_MSA_3R_10, - OPC_SUBSUU_S_df =3D (0x3 << 23) | OPC_MSA_3R_11, - OPC_DPADD_U_df =3D (0x3 << 23) | OPC_MSA_3R_13, - OPC_PCKOD_df =3D (0x3 << 23) | OPC_MSA_3R_14, - OPC_BSET_df =3D (0x4 << 23) | OPC_MSA_3R_0D, - OPC_MIN_S_df =3D (0x4 << 23) | OPC_MSA_3R_0E, - OPC_CLE_S_df =3D (0x4 << 23) | OPC_MSA_3R_0F, - OPC_AVE_S_df =3D (0x4 << 23) | OPC_MSA_3R_10, - OPC_ASUB_S_df =3D (0x4 << 23) | OPC_MSA_3R_11, - OPC_DIV_S_df =3D (0x4 << 23) | OPC_MSA_3R_12, - OPC_DPSUB_S_df =3D (0x4 << 23) | OPC_MSA_3R_13, - OPC_ILVL_df =3D (0x4 << 23) | OPC_MSA_3R_14, - OPC_HADD_S_df =3D (0x4 << 23) | OPC_MSA_3R_15, - OPC_BNEG_df =3D (0x5 << 23) | OPC_MSA_3R_0D, - OPC_MIN_U_df =3D (0x5 << 23) | OPC_MSA_3R_0E, - OPC_CLE_U_df =3D (0x5 << 23) | OPC_MSA_3R_0F, - OPC_AVE_U_df =3D (0x5 << 23) | OPC_MSA_3R_10, - OPC_ASUB_U_df =3D (0x5 << 23) | OPC_MSA_3R_11, - OPC_DIV_U_df =3D (0x5 << 23) | OPC_MSA_3R_12, - OPC_DPSUB_U_df =3D (0x5 << 23) | OPC_MSA_3R_13, - OPC_ILVR_df =3D (0x5 << 23) | OPC_MSA_3R_14, - OPC_HADD_U_df =3D (0x5 << 23) | OPC_MSA_3R_15, - OPC_BINSL_df =3D (0x6 << 23) | OPC_MSA_3R_0D, - OPC_MAX_A_df =3D (0x6 << 23) | OPC_MSA_3R_0E, - OPC_AVER_S_df =3D (0x6 << 23) | OPC_MSA_3R_10, - OPC_MOD_S_df =3D (0x6 << 23) | OPC_MSA_3R_12, - OPC_ILVEV_df =3D (0x6 << 23) | OPC_MSA_3R_14, - OPC_HSUB_S_df =3D (0x6 << 23) | OPC_MSA_3R_15, - OPC_BINSR_df =3D (0x7 << 23) | OPC_MSA_3R_0D, - OPC_MIN_A_df =3D (0x7 << 23) | OPC_MSA_3R_0E, - OPC_AVER_U_df =3D (0x7 << 23) | OPC_MSA_3R_10, - OPC_MOD_U_df =3D (0x7 << 23) | OPC_MSA_3R_12, - OPC_ILVOD_df =3D (0x7 << 23) | OPC_MSA_3R_14, - OPC_HSUB_U_df =3D (0x7 << 23) | OPC_MSA_3R_15, - - /* ELM instructions df(bits 21..16) =3D _b, _h, _w, _d */ - OPC_SLDI_df =3D (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM, - OPC_CTCMSA =3D (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM, - OPC_SPLATI_df =3D (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM, - OPC_CFCMSA =3D (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM, - OPC_COPY_S_df =3D (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM, - OPC_MOVE_V =3D (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM, - OPC_COPY_U_df =3D (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM, - OPC_INSERT_df =3D (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM, - OPC_INSVE_df =3D (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM, - - /* 3RF instruction _df(bit 21) =3D _w, _d */ - OPC_FCAF_df =3D (0x0 << 22) | OPC_MSA_3RF_1A, - OPC_FADD_df =3D (0x0 << 22) | OPC_MSA_3RF_1B, - OPC_FCUN_df =3D (0x1 << 22) | OPC_MSA_3RF_1A, - OPC_FSUB_df =3D (0x1 << 22) | OPC_MSA_3RF_1B, - OPC_FCOR_df =3D (0x1 << 22) | OPC_MSA_3RF_1C, - OPC_FCEQ_df =3D (0x2 << 22) | OPC_MSA_3RF_1A, - OPC_FMUL_df =3D (0x2 << 22) | OPC_MSA_3RF_1B, - OPC_FCUNE_df =3D (0x2 << 22) | OPC_MSA_3RF_1C, - OPC_FCUEQ_df =3D (0x3 << 22) | OPC_MSA_3RF_1A, - OPC_FDIV_df =3D (0x3 << 22) | OPC_MSA_3RF_1B, - OPC_FCNE_df =3D (0x3 << 22) | OPC_MSA_3RF_1C, - OPC_FCLT_df =3D (0x4 << 22) | OPC_MSA_3RF_1A, - OPC_FMADD_df =3D (0x4 << 22) | OPC_MSA_3RF_1B, - OPC_MUL_Q_df =3D (0x4 << 22) | OPC_MSA_3RF_1C, - OPC_FCULT_df =3D (0x5 << 22) | OPC_MSA_3RF_1A, - OPC_FMSUB_df =3D (0x5 << 22) | OPC_MSA_3RF_1B, - OPC_MADD_Q_df =3D (0x5 << 22) | OPC_MSA_3RF_1C, - OPC_FCLE_df =3D (0x6 << 22) | OPC_MSA_3RF_1A, - OPC_MSUB_Q_df =3D (0x6 << 22) | OPC_MSA_3RF_1C, - OPC_FCULE_df =3D (0x7 << 22) | OPC_MSA_3RF_1A, - OPC_FEXP2_df =3D (0x7 << 22) | OPC_MSA_3RF_1B, - OPC_FSAF_df =3D (0x8 << 22) | OPC_MSA_3RF_1A, - OPC_FEXDO_df =3D (0x8 << 22) | OPC_MSA_3RF_1B, - OPC_FSUN_df =3D (0x9 << 22) | OPC_MSA_3RF_1A, - OPC_FSOR_df =3D (0x9 << 22) | OPC_MSA_3RF_1C, - OPC_FSEQ_df =3D (0xA << 22) | OPC_MSA_3RF_1A, - OPC_FTQ_df =3D (0xA << 22) | OPC_MSA_3RF_1B, - OPC_FSUNE_df =3D (0xA << 22) | OPC_MSA_3RF_1C, - OPC_FSUEQ_df =3D (0xB << 22) | OPC_MSA_3RF_1A, - OPC_FSNE_df =3D (0xB << 22) | OPC_MSA_3RF_1C, - OPC_FSLT_df =3D (0xC << 22) | OPC_MSA_3RF_1A, - OPC_FMIN_df =3D (0xC << 22) | OPC_MSA_3RF_1B, - OPC_MULR_Q_df =3D (0xC << 22) | OPC_MSA_3RF_1C, - OPC_FSULT_df =3D (0xD << 22) | OPC_MSA_3RF_1A, - OPC_FMIN_A_df =3D (0xD << 22) | OPC_MSA_3RF_1B, - OPC_MADDR_Q_df =3D (0xD << 22) | OPC_MSA_3RF_1C, - OPC_FSLE_df =3D (0xE << 22) | OPC_MSA_3RF_1A, - OPC_FMAX_df =3D (0xE << 22) | OPC_MSA_3RF_1B, - OPC_MSUBR_Q_df =3D (0xE << 22) | OPC_MSA_3RF_1C, - OPC_FSULE_df =3D (0xF << 22) | OPC_MSA_3RF_1A, - OPC_FMAX_A_df =3D (0xF << 22) | OPC_MSA_3RF_1B, - - /* BIT instruction df(bits 22..16) =3D _B _H _W _D */ - OPC_SLLI_df =3D (0x0 << 23) | OPC_MSA_BIT_09, - OPC_SAT_S_df =3D (0x0 << 23) | OPC_MSA_BIT_0A, - OPC_SRAI_df =3D (0x1 << 23) | OPC_MSA_BIT_09, - OPC_SAT_U_df =3D (0x1 << 23) | OPC_MSA_BIT_0A, - OPC_SRLI_df =3D (0x2 << 23) | OPC_MSA_BIT_09, - OPC_SRARI_df =3D (0x2 << 23) | OPC_MSA_BIT_0A, - OPC_BCLRI_df =3D (0x3 << 23) | OPC_MSA_BIT_09, - OPC_SRLRI_df =3D (0x3 << 23) | OPC_MSA_BIT_0A, - OPC_BSETI_df =3D (0x4 << 23) | OPC_MSA_BIT_09, - OPC_BNEGI_df =3D (0x5 << 23) | OPC_MSA_BIT_09, - OPC_BINSLI_df =3D (0x6 << 23) | OPC_MSA_BIT_09, - OPC_BINSRI_df =3D (0x7 << 23) | OPC_MSA_BIT_09, -}; - =20 /* * @@ -2501,7 +2268,6 @@ static TCGv cpu_lladdr, cpu_llval; static TCGv_i32 hflags; static TCGv_i32 fpu_fcr0, fpu_fcr31; static TCGv_i64 fpu_f64[32]; -static TCGv_i64 msa_wr_d[64]; =20 #if defined(TARGET_MIPS64) /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) = */ @@ -2620,25 +2386,6 @@ static const char * const fregnames[] =3D { "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", }; =20 -static const char * const msaregnames[] =3D { - "w0.d0", "w0.d1", "w1.d0", "w1.d1", - "w2.d0", "w2.d1", "w3.d0", "w3.d1", - "w4.d0", "w4.d1", "w5.d0", "w5.d1", - "w6.d0", "w6.d1", "w7.d0", "w7.d1", - "w8.d0", "w8.d1", "w9.d0", "w9.d1", - "w10.d0", "w10.d1", "w11.d0", "w11.d1", - "w12.d0", "w12.d1", "w13.d0", "w13.d1", - "w14.d0", "w14.d1", "w15.d0", "w15.d1", - "w16.d0", "w16.d1", "w17.d0", "w17.d1", - "w18.d0", "w18.d1", "w19.d0", "w19.d1", - "w20.d0", "w20.d1", "w21.d0", "w21.d1", - "w22.d0", "w22.d1", "w23.d0", "w23.d1", - "w24.d0", "w24.d1", "w25.d0", "w25.d1", - "w26.d0", "w26.d1", "w27.d0", "w27.d1", - "w28.d0", "w28.d1", "w29.d0", "w29.d1", - "w30.d0", "w30.d1", "w31.d0", "w31.d1", -}; - #if !defined(TARGET_MIPS64) static const char * const mxuregnames[] =3D { "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8", @@ -28690,1961 +28437,7 @@ static void decode_opc_special3(CPUMIPSState *en= v, DisasContext *ctx) } } =20 -/* MIPS SIMD Architecture (MSA) */ -static inline int check_msa_access(DisasContext *ctx) -{ - if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) && - !(ctx->hflags & MIPS_HFLAG_F64))) { - generate_exception_end(ctx, EXCP_RI); - return 0; - } - - if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) { - if (ctx->insn_flags & ASE_MSA) { - generate_exception_end(ctx, EXCP_MSADIS); - return 0; - } else { - generate_exception_end(ctx, EXCP_RI); - return 0; - } - } - return 1; -} - -static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt) -{ - /* generates tcg ops to check if any element is 0 */ - /* Note this function only works with MSA_WRLEN =3D 128 */ - uint64_t eval_zero_or_big =3D 0; - uint64_t eval_big =3D 0; - TCGv_i64 t0 =3D tcg_temp_new_i64(); - TCGv_i64 t1 =3D tcg_temp_new_i64(); - switch (df) { - case DF_BYTE: - eval_zero_or_big =3D 0x0101010101010101ULL; - eval_big =3D 0x8080808080808080ULL; - break; - case DF_HALF: - eval_zero_or_big =3D 0x0001000100010001ULL; - eval_big =3D 0x8000800080008000ULL; - break; - case DF_WORD: - eval_zero_or_big =3D 0x0000000100000001ULL; - eval_big =3D 0x8000000080000000ULL; - break; - case DF_DOUBLE: - eval_zero_or_big =3D 0x0000000000000001ULL; - eval_big =3D 0x8000000000000000ULL; - break; - } - tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big); - tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]); - tcg_gen_andi_i64(t0, t0, eval_big); - tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big); - tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]); - tcg_gen_andi_i64(t1, t1, eval_big); - tcg_gen_or_i64(t0, t0, t1); - /* if all bits are zero then all elements are not zero */ - /* if some bit is non-zero then some element is zero */ - tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0); - tcg_gen_trunc_i64_tl(tresult, t0); - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -} - -static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t = op1) -{ - uint8_t df =3D (ctx->opcode >> 21) & 0x3; - uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; - int64_t s16 =3D (int16_t)ctx->opcode; - - check_msa_access(ctx); - - if (ctx->hflags & MIPS_HFLAG_BMASK) { - generate_exception_end(ctx, EXCP_RI); - return; - } - switch (op1) { - case OPC_BZ_V: - case OPC_BNZ_V: - { - TCGv_i64 t0 =3D tcg_temp_new_i64(); - tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]); - tcg_gen_setcondi_i64((op1 =3D=3D OPC_BZ_V) ? - TCG_COND_EQ : TCG_COND_NE, t0, t0, 0); - tcg_gen_trunc_i64_tl(bcond, t0); - tcg_temp_free_i64(t0); - } - break; - case OPC_BZ_B: - case OPC_BZ_H: - case OPC_BZ_W: - case OPC_BZ_D: - gen_check_zero_element(bcond, df, wt); - break; - case OPC_BNZ_B: - case OPC_BNZ_H: - case OPC_BNZ_W: - case OPC_BNZ_D: - gen_check_zero_element(bcond, df, wt); - tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0); - break; - } - - ctx->btarget =3D ctx->base.pc_next + (s16 << 2) + 4; - - ctx->hflags |=3D MIPS_HFLAG_BC; - ctx->hflags |=3D MIPS_HFLAG_BDS32; -} - -static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx) -{ -#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24))) - uint8_t i8 =3D (ctx->opcode >> 16) & 0xff; - uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; - uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 twd =3D tcg_const_i32(wd); - TCGv_i32 tws =3D tcg_const_i32(ws); - TCGv_i32 ti8 =3D tcg_const_i32(i8); - - switch (MASK_MSA_I8(ctx->opcode)) { - case OPC_ANDI_B: - gen_helper_msa_andi_b(cpu_env, twd, tws, ti8); - break; - case OPC_ORI_B: - gen_helper_msa_ori_b(cpu_env, twd, tws, ti8); - break; - case OPC_NORI_B: - gen_helper_msa_nori_b(cpu_env, twd, tws, ti8); - break; - case OPC_XORI_B: - gen_helper_msa_xori_b(cpu_env, twd, tws, ti8); - break; - case OPC_BMNZI_B: - gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8); - break; - case OPC_BMZI_B: - gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8); - break; - case OPC_BSELI_B: - gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8); - break; - case OPC_SHF_B: - case OPC_SHF_H: - case OPC_SHF_W: - { - uint8_t df =3D (ctx->opcode >> 24) & 0x3; - if (df =3D=3D DF_DOUBLE) { - generate_exception_end(ctx, EXCP_RI); - } else { - TCGv_i32 tdf =3D tcg_const_i32(df); - gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8); - tcg_temp_free_i32(tdf); - } - } - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(ti8); -} - -static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx) -{ -#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) - uint8_t df =3D (ctx->opcode >> 21) & 0x3; - int8_t s5 =3D (int8_t) sextract32(ctx->opcode, 16, 5); - uint8_t u5 =3D (ctx->opcode >> 16) & 0x1f; - uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; - uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 tdf =3D tcg_const_i32(df); - TCGv_i32 twd =3D tcg_const_i32(wd); - TCGv_i32 tws =3D tcg_const_i32(ws); - TCGv_i32 timm =3D tcg_temp_new_i32(); - tcg_gen_movi_i32(timm, u5); - - switch (MASK_MSA_I5(ctx->opcode)) { - case OPC_ADDVI_df: - gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_SUBVI_df: - gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_MAXI_S_df: - tcg_gen_movi_i32(timm, s5); - gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_MAXI_U_df: - gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_MINI_S_df: - tcg_gen_movi_i32(timm, s5); - gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_MINI_U_df: - gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_CEQI_df: - tcg_gen_movi_i32(timm, s5); - gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_CLTI_S_df: - tcg_gen_movi_i32(timm, s5); - gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_CLTI_U_df: - gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_CLEI_S_df: - tcg_gen_movi_i32(timm, s5); - gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_CLEI_U_df: - gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_LDI_df: - { - int32_t s10 =3D sextract32(ctx->opcode, 11, 10); - tcg_gen_movi_i32(timm, s10); - gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm); - } - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free_i32(tdf); - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(timm); -} - -static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx) -{ -#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) - uint8_t dfm =3D (ctx->opcode >> 16) & 0x7f; - uint32_t df =3D 0, m =3D 0; - uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; - uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 tdf; - TCGv_i32 tm; - TCGv_i32 twd; - TCGv_i32 tws; - - if ((dfm & 0x40) =3D=3D 0x00) { - m =3D dfm & 0x3f; - df =3D DF_DOUBLE; - } else if ((dfm & 0x60) =3D=3D 0x40) { - m =3D dfm & 0x1f; - df =3D DF_WORD; - } else if ((dfm & 0x70) =3D=3D 0x60) { - m =3D dfm & 0x0f; - df =3D DF_HALF; - } else if ((dfm & 0x78) =3D=3D 0x70) { - m =3D dfm & 0x7; - df =3D DF_BYTE; - } else { - generate_exception_end(ctx, EXCP_RI); - return; - } - - tdf =3D tcg_const_i32(df); - tm =3D tcg_const_i32(m); - twd =3D tcg_const_i32(wd); - tws =3D tcg_const_i32(ws); - - switch (MASK_MSA_BIT(ctx->opcode)) { - case OPC_SLLI_df: - gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SRAI_df: - gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SRLI_df: - gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_BCLRI_df: - gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_BSETI_df: - gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_BNEGI_df: - gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_BINSLI_df: - gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_BINSRI_df: - gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SAT_S_df: - gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SAT_U_df: - gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SRARI_df: - gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SRLRI_df: - gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm); - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free_i32(tdf); - tcg_temp_free_i32(tm); - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); -} - -static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) -{ -#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) - uint8_t df =3D (ctx->opcode >> 21) & 0x3; - uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; - uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; - uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 tdf =3D tcg_const_i32(df); - TCGv_i32 twd =3D tcg_const_i32(wd); - TCGv_i32 tws =3D tcg_const_i32(ws); - TCGv_i32 twt =3D tcg_const_i32(wt); - - switch (MASK_MSA_3R(ctx->opcode)) { - case OPC_BINSL_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_binsl_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_binsl_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_binsl_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_binsl_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_BINSR_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_binsr_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_binsr_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_binsr_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_binsr_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_BCLR_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_bclr_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_bclr_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_bclr_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_bclr_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_BNEG_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_bneg_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_bneg_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_bneg_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_bneg_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_BSET_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_bset_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_bset_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_bset_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_bset_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ADD_A_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_add_a_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_add_a_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_add_a_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_add_a_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ADDS_A_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_adds_a_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_adds_a_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_adds_a_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_adds_a_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ADDS_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_adds_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_adds_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_adds_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_adds_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ADDS_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_adds_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_adds_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_adds_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_adds_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ADDV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_addv_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_addv_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_addv_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_addv_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_AVE_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ave_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ave_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ave_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ave_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_AVE_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ave_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ave_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ave_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ave_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_AVER_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_aver_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_aver_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_aver_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_aver_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_AVER_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_aver_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_aver_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_aver_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_aver_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_CEQ_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ceq_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ceq_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ceq_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ceq_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_CLE_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_cle_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_cle_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_cle_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_cle_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_CLE_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_cle_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_cle_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_cle_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_cle_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_CLT_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_clt_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_clt_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_clt_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_clt_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_CLT_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_clt_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_clt_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_clt_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_clt_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DIV_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_div_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_div_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_div_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_div_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DIV_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_div_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_div_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_div_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_div_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MAX_A_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_max_a_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_max_a_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_max_a_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_max_a_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MAX_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_max_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_max_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_max_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_max_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MAX_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_max_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_max_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_max_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_max_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MIN_A_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_min_a_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_min_a_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_min_a_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_min_a_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MIN_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_min_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_min_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_min_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_min_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MIN_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_min_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_min_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_min_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_min_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MOD_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_mod_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_mod_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_mod_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_mod_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MOD_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_mod_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_mod_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_mod_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_mod_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MADDV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_maddv_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_maddv_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_maddv_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_maddv_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MSUBV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_msubv_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_msubv_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_msubv_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_msubv_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ASUB_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_asub_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_asub_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_asub_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_asub_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ASUB_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_asub_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_asub_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_asub_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_asub_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ILVEV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ilvev_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ilvev_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ilvev_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ilvev_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ILVOD_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ilvod_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ilvod_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ilvod_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ilvod_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ILVL_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ilvl_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ilvl_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ilvl_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ilvl_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ILVR_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ilvr_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ilvr_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ilvr_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ilvr_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_PCKEV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_pckev_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_pckev_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_pckev_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_pckev_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_PCKOD_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_pckod_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_pckod_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_pckod_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_pckod_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SLL_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_sll_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_sll_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_sll_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_sll_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SRA_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_sra_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_sra_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_sra_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_sra_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SRAR_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_srar_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_srar_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_srar_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_srar_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SRL_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_srl_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_srl_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_srl_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_srl_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SRLR_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_srlr_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_srlr_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_srlr_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_srlr_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SUBS_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_subs_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_subs_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_subs_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_subs_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MULV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_mulv_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_mulv_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_mulv_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_mulv_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SLD_df: - gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_VSHF_df: - gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_SUBV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_subv_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_subv_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_subv_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_subv_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SUBS_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_subs_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_subs_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_subs_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_subs_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SPLAT_df: - gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_SUBSUS_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_subsus_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_subsus_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_subsus_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_subsus_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SUBSUU_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_subsuu_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_subsuu_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_subsuu_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_subsuu_s_d(cpu_env, twd, tws, twt); - break; - } - break; - - case OPC_DOTP_S_df: - case OPC_DOTP_U_df: - case OPC_DPADD_S_df: - case OPC_DPADD_U_df: - case OPC_DPSUB_S_df: - case OPC_HADD_S_df: - case OPC_DPSUB_U_df: - case OPC_HADD_U_df: - case OPC_HSUB_S_df: - case OPC_HSUB_U_df: - if (df =3D=3D DF_BYTE) { - generate_exception_end(ctx, EXCP_RI); - break; - } - switch (MASK_MSA_3R(ctx->opcode)) { - case OPC_HADD_S_df: - switch (df) { - case DF_HALF: - gen_helper_msa_hadd_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_hadd_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_hadd_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_HADD_U_df: - switch (df) { - case DF_HALF: - gen_helper_msa_hadd_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_hadd_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_hadd_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_HSUB_S_df: - switch (df) { - case DF_HALF: - gen_helper_msa_hsub_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_hsub_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_hsub_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_HSUB_U_df: - switch (df) { - case DF_HALF: - gen_helper_msa_hsub_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_hsub_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_hsub_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DOTP_S_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dotp_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dotp_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dotp_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DOTP_U_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dotp_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dotp_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dotp_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DPADD_S_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dpadd_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dpadd_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dpadd_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DPADD_U_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dpadd_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dpadd_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dpadd_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DPSUB_S_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dpsub_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dpsub_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dpsub_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DPSUB_U_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dpsub_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dpsub_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dpsub_u_d(cpu_env, twd, tws, twt); - break; - } - break; - } - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - break; - } - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(twt); - tcg_temp_free_i32(tdf); -} - -static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx) -{ -#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16))) - uint8_t source =3D (ctx->opcode >> 11) & 0x1f; - uint8_t dest =3D (ctx->opcode >> 6) & 0x1f; - TCGv telm =3D tcg_temp_new(); - TCGv_i32 tsr =3D tcg_const_i32(source); - TCGv_i32 tdt =3D tcg_const_i32(dest); - - switch (MASK_MSA_ELM_DF3E(ctx->opcode)) { - case OPC_CTCMSA: - gen_load_gpr(telm, source); - gen_helper_msa_ctcmsa(cpu_env, telm, tdt); - break; - case OPC_CFCMSA: - gen_helper_msa_cfcmsa(telm, cpu_env, tsr); - gen_store_gpr(telm, dest); - break; - case OPC_MOVE_V: - gen_helper_msa_move_v(cpu_env, tdt, tsr); - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free(telm); - tcg_temp_free_i32(tdt); - tcg_temp_free_i32(tsr); -} - -static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t = df, - uint32_t n) -{ -#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) - uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; - uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 tws =3D tcg_const_i32(ws); - TCGv_i32 twd =3D tcg_const_i32(wd); - TCGv_i32 tn =3D tcg_const_i32(n); - TCGv_i32 tdf =3D tcg_const_i32(df); - - switch (MASK_MSA_ELM(ctx->opcode)) { - case OPC_SLDI_df: - gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn); - break; - case OPC_SPLATI_df: - gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn); - break; - case OPC_INSVE_df: - gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn); - break; - case OPC_COPY_S_df: - case OPC_COPY_U_df: - case OPC_INSERT_df: -#if !defined(TARGET_MIPS64) - /* Double format valid only for MIPS64 */ - if (df =3D=3D DF_DOUBLE) { - generate_exception_end(ctx, EXCP_RI); - break; - } - if ((MASK_MSA_ELM(ctx->opcode) =3D=3D OPC_COPY_U_df) && - (df =3D=3D DF_WORD)) { - generate_exception_end(ctx, EXCP_RI); - break; - } -#endif - switch (MASK_MSA_ELM(ctx->opcode)) { - case OPC_COPY_S_df: - if (likely(wd !=3D 0)) { - switch (df) { - case DF_BYTE: - gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn); - break; - case DF_HALF: - gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn); - break; - case DF_WORD: - gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn); - break; -#if defined(TARGET_MIPS64) - case DF_DOUBLE: - gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn); - break; -#endif - default: - assert(0); - } - } - break; - case OPC_COPY_U_df: - if (likely(wd !=3D 0)) { - switch (df) { - case DF_BYTE: - gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn); - break; - case DF_HALF: - gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn); - break; -#if defined(TARGET_MIPS64) - case DF_WORD: - gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn); - break; -#endif - default: - assert(0); - } - } - break; - case OPC_INSERT_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_insert_b(cpu_env, twd, tws, tn); - break; - case DF_HALF: - gen_helper_msa_insert_h(cpu_env, twd, tws, tn); - break; - case DF_WORD: - gen_helper_msa_insert_w(cpu_env, twd, tws, tn); - break; -#if defined(TARGET_MIPS64) - case DF_DOUBLE: - gen_helper_msa_insert_d(cpu_env, twd, tws, tn); - break; -#endif - default: - assert(0); - } - break; - } - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - } - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(tn); - tcg_temp_free_i32(tdf); -} - -static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx) -{ - uint8_t dfn =3D (ctx->opcode >> 16) & 0x3f; - uint32_t df =3D 0, n =3D 0; - - if ((dfn & 0x30) =3D=3D 0x00) { - n =3D dfn & 0x0f; - df =3D DF_BYTE; - } else if ((dfn & 0x38) =3D=3D 0x20) { - n =3D dfn & 0x07; - df =3D DF_HALF; - } else if ((dfn & 0x3c) =3D=3D 0x30) { - n =3D dfn & 0x03; - df =3D DF_WORD; - } else if ((dfn & 0x3e) =3D=3D 0x38) { - n =3D dfn & 0x01; - df =3D DF_DOUBLE; - } else if (dfn =3D=3D 0x3E) { - /* CTCMSA, CFCMSA, MOVE.V */ - gen_msa_elm_3e(env, ctx); - return; - } else { - generate_exception_end(ctx, EXCP_RI); - return; - } - - gen_msa_elm_df(env, ctx, df, n); -} - -static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx) -{ -#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) - uint8_t df =3D (ctx->opcode >> 21) & 0x1; - uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; - uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; - uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 twd =3D tcg_const_i32(wd); - TCGv_i32 tws =3D tcg_const_i32(ws); - TCGv_i32 twt =3D tcg_const_i32(wt); - TCGv_i32 tdf =3D tcg_temp_new_i32(); - - /* adjust df value for floating-point instruction */ - tcg_gen_movi_i32(tdf, df + 2); - - switch (MASK_MSA_3RF(ctx->opcode)) { - case OPC_FCAF_df: - gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FADD_df: - gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCUN_df: - gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSUB_df: - gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCOR_df: - gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCEQ_df: - gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMUL_df: - gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCUNE_df: - gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCUEQ_df: - gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FDIV_df: - gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCNE_df: - gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCLT_df: - gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMADD_df: - gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MUL_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCULT_df: - gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMSUB_df: - gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MADD_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCLE_df: - gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MSUB_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCULE_df: - gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FEXP2_df: - gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSAF_df: - gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FEXDO_df: - gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSUN_df: - gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSOR_df: - gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSEQ_df: - gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FTQ_df: - gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSUNE_df: - gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSUEQ_df: - gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSNE_df: - gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSLT_df: - gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMIN_df: - gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MULR_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSULT_df: - gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMIN_A_df: - gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MADDR_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSLE_df: - gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMAX_df: - gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MSUBR_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSULE_df: - gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMAX_A_df: - gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt); - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(twt); - tcg_temp_free_i32(tdf); -} - -static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx) -{ -#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \ - (op & (0x7 << 18))) - uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; - uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; - uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; - uint8_t df =3D (ctx->opcode >> 16) & 0x3; - TCGv_i32 twd =3D tcg_const_i32(wd); - TCGv_i32 tws =3D tcg_const_i32(ws); - TCGv_i32 twt =3D tcg_const_i32(wt); - TCGv_i32 tdf =3D tcg_const_i32(df); - - switch (MASK_MSA_2R(ctx->opcode)) { - case OPC_FILL_df: -#if !defined(TARGET_MIPS64) - /* Double format valid only for MIPS64 */ - if (df =3D=3D DF_DOUBLE) { - generate_exception_end(ctx, EXCP_RI); - break; - } -#endif - gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */ - break; - case OPC_NLOC_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_nloc_b(cpu_env, twd, tws); - break; - case DF_HALF: - gen_helper_msa_nloc_h(cpu_env, twd, tws); - break; - case DF_WORD: - gen_helper_msa_nloc_w(cpu_env, twd, tws); - break; - case DF_DOUBLE: - gen_helper_msa_nloc_d(cpu_env, twd, tws); - break; - } - break; - case OPC_NLZC_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_nlzc_b(cpu_env, twd, tws); - break; - case DF_HALF: - gen_helper_msa_nlzc_h(cpu_env, twd, tws); - break; - case DF_WORD: - gen_helper_msa_nlzc_w(cpu_env, twd, tws); - break; - case DF_DOUBLE: - gen_helper_msa_nlzc_d(cpu_env, twd, tws); - break; - } - break; - case OPC_PCNT_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_pcnt_b(cpu_env, twd, tws); - break; - case DF_HALF: - gen_helper_msa_pcnt_h(cpu_env, twd, tws); - break; - case DF_WORD: - gen_helper_msa_pcnt_w(cpu_env, twd, tws); - break; - case DF_DOUBLE: - gen_helper_msa_pcnt_d(cpu_env, twd, tws); - break; - } - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(twt); - tcg_temp_free_i32(tdf); -} - -static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx) -{ -#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \ - (op & (0xf << 17))) - uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; - uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; - uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; - uint8_t df =3D (ctx->opcode >> 16) & 0x1; - TCGv_i32 twd =3D tcg_const_i32(wd); - TCGv_i32 tws =3D tcg_const_i32(ws); - TCGv_i32 twt =3D tcg_const_i32(wt); - /* adjust df value for floating-point instruction */ - TCGv_i32 tdf =3D tcg_const_i32(df + 2); - - switch (MASK_MSA_2RF(ctx->opcode)) { - case OPC_FCLASS_df: - gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws); - break; - case OPC_FTRUNC_S_df: - gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws); - break; - case OPC_FTRUNC_U_df: - gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws); - break; - case OPC_FSQRT_df: - gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws); - break; - case OPC_FRSQRT_df: - gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws); - break; - case OPC_FRCP_df: - gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws); - break; - case OPC_FRINT_df: - gen_helper_msa_frint_df(cpu_env, tdf, twd, tws); - break; - case OPC_FLOG2_df: - gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws); - break; - case OPC_FEXUPL_df: - gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws); - break; - case OPC_FEXUPR_df: - gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws); - break; - case OPC_FFQL_df: - gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws); - break; - case OPC_FFQR_df: - gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws); - break; - case OPC_FTINT_S_df: - gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws); - break; - case OPC_FTINT_U_df: - gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws); - break; - case OPC_FFINT_S_df: - gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws); - break; - case OPC_FFINT_U_df: - gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(twt); - tcg_temp_free_i32(tdf); -} - -static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx) -{ -#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21))) - uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; - uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; - uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; - TCGv_i32 twd =3D tcg_const_i32(wd); - TCGv_i32 tws =3D tcg_const_i32(ws); - TCGv_i32 twt =3D tcg_const_i32(wt); - - switch (MASK_MSA_VEC(ctx->opcode)) { - case OPC_AND_V: - gen_helper_msa_and_v(cpu_env, twd, tws, twt); - break; - case OPC_OR_V: - gen_helper_msa_or_v(cpu_env, twd, tws, twt); - break; - case OPC_NOR_V: - gen_helper_msa_nor_v(cpu_env, twd, tws, twt); - break; - case OPC_XOR_V: - gen_helper_msa_xor_v(cpu_env, twd, tws, twt); - break; - case OPC_BMNZ_V: - gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt); - break; - case OPC_BMZ_V: - gen_helper_msa_bmz_v(cpu_env, twd, tws, twt); - break; - case OPC_BSEL_V: - gen_helper_msa_bsel_v(cpu_env, twd, tws, twt); - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(twt); -} - -static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx) -{ - switch (MASK_MSA_VEC(ctx->opcode)) { - case OPC_AND_V: - case OPC_OR_V: - case OPC_NOR_V: - case OPC_XOR_V: - case OPC_BMNZ_V: - case OPC_BMZ_V: - case OPC_BSEL_V: - gen_msa_vec_v(env, ctx); - break; - case OPC_MSA_2R: - gen_msa_2r(env, ctx); - break; - case OPC_MSA_2RF: - gen_msa_2rf(env, ctx); - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -static void gen_msa(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D ctx->opcode; - check_insn(ctx, ASE_MSA); - check_msa_access(ctx); - - switch (MASK_MSA_MINOR(opcode)) { - case OPC_MSA_I8_00: - case OPC_MSA_I8_01: - case OPC_MSA_I8_02: - gen_msa_i8(env, ctx); - break; - case OPC_MSA_I5_06: - case OPC_MSA_I5_07: - gen_msa_i5(env, ctx); - break; - case OPC_MSA_BIT_09: - case OPC_MSA_BIT_0A: - gen_msa_bit(env, ctx); - break; - case OPC_MSA_3R_0D: - case OPC_MSA_3R_0E: - case OPC_MSA_3R_0F: - case OPC_MSA_3R_10: - case OPC_MSA_3R_11: - case OPC_MSA_3R_12: - case OPC_MSA_3R_13: - case OPC_MSA_3R_14: - case OPC_MSA_3R_15: - gen_msa_3r(env, ctx); - break; - case OPC_MSA_ELM: - gen_msa_elm(env, ctx); - break; - case OPC_MSA_3RF_1A: - case OPC_MSA_3RF_1B: - case OPC_MSA_3RF_1C: - gen_msa_3rf(env, ctx); - break; - case OPC_MSA_VEC: - gen_msa_vec(env, ctx); - break; - case OPC_LD_B: - case OPC_LD_H: - case OPC_LD_W: - case OPC_LD_D: - case OPC_ST_B: - case OPC_ST_H: - case OPC_ST_W: - case OPC_ST_D: - { - int32_t s10 =3D sextract32(ctx->opcode, 16, 10); - uint8_t rs =3D (ctx->opcode >> 11) & 0x1f; - uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; - uint8_t df =3D (ctx->opcode >> 0) & 0x3; - - TCGv_i32 twd =3D tcg_const_i32(wd); - TCGv taddr =3D tcg_temp_new(); - gen_base_offset_addr(ctx, taddr, rs, s10 << df); - - switch (MASK_MSA_MINOR(opcode)) { - case OPC_LD_B: - gen_helper_msa_ld_b(cpu_env, twd, taddr); - break; - case OPC_LD_H: - gen_helper_msa_ld_h(cpu_env, twd, taddr); - break; - case OPC_LD_W: - gen_helper_msa_ld_w(cpu_env, twd, taddr); - break; - case OPC_LD_D: - gen_helper_msa_ld_d(cpu_env, twd, taddr); - break; - case OPC_ST_B: - gen_helper_msa_st_b(cpu_env, twd, taddr); - break; - case OPC_ST_H: - gen_helper_msa_st_h(cpu_env, twd, taddr); - break; - case OPC_ST_W: - gen_helper_msa_st_w(cpu_env, twd, taddr); - break; - case OPC_ST_D: - gen_helper_msa_st_d(cpu_env, twd, taddr); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free(taddr); - } - break; - default: - MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); - break; - } - -} +#include "mod-mips-msa_translate.c.inc" =20 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) { diff --git a/target/mips/mod-mips-msa_translate.c.inc b/target/mips/mod-mip= s-msa_translate.c.inc new file mode 100644 index 00000000000..ef2f0fea0d9 --- /dev/null +++ b/target/mips/mod-mips-msa_translate.c.inc @@ -0,0 +1,2218 @@ +/* + * MIPS SIMD Architecture Module (MSA) translation routines + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) +enum { + OPC_MSA_I8_00 =3D 0x00 | OPC_MSA, + OPC_MSA_I8_01 =3D 0x01 | OPC_MSA, + OPC_MSA_I8_02 =3D 0x02 | OPC_MSA, + OPC_MSA_I5_06 =3D 0x06 | OPC_MSA, + OPC_MSA_I5_07 =3D 0x07 | OPC_MSA, + OPC_MSA_BIT_09 =3D 0x09 | OPC_MSA, + OPC_MSA_BIT_0A =3D 0x0A | OPC_MSA, + OPC_MSA_3R_0D =3D 0x0D | OPC_MSA, + OPC_MSA_3R_0E =3D 0x0E | OPC_MSA, + OPC_MSA_3R_0F =3D 0x0F | OPC_MSA, + OPC_MSA_3R_10 =3D 0x10 | OPC_MSA, + OPC_MSA_3R_11 =3D 0x11 | OPC_MSA, + OPC_MSA_3R_12 =3D 0x12 | OPC_MSA, + OPC_MSA_3R_13 =3D 0x13 | OPC_MSA, + OPC_MSA_3R_14 =3D 0x14 | OPC_MSA, + OPC_MSA_3R_15 =3D 0x15 | OPC_MSA, + OPC_MSA_ELM =3D 0x19 | OPC_MSA, + OPC_MSA_3RF_1A =3D 0x1A | OPC_MSA, + OPC_MSA_3RF_1B =3D 0x1B | OPC_MSA, + OPC_MSA_3RF_1C =3D 0x1C | OPC_MSA, + OPC_MSA_VEC =3D 0x1E | OPC_MSA, + + /* MI10 instruction */ + OPC_LD_B =3D (0x20) | OPC_MSA, + OPC_LD_H =3D (0x21) | OPC_MSA, + OPC_LD_W =3D (0x22) | OPC_MSA, + OPC_LD_D =3D (0x23) | OPC_MSA, + OPC_ST_B =3D (0x24) | OPC_MSA, + OPC_ST_H =3D (0x25) | OPC_MSA, + OPC_ST_W =3D (0x26) | OPC_MSA, + OPC_ST_D =3D (0x27) | OPC_MSA, +}; + +enum { + /* I5 instruction df(bits 22..21) =3D _b, _h, _w, _d */ + OPC_ADDVI_df =3D (0x0 << 23) | OPC_MSA_I5_06, + OPC_CEQI_df =3D (0x0 << 23) | OPC_MSA_I5_07, + OPC_SUBVI_df =3D (0x1 << 23) | OPC_MSA_I5_06, + OPC_MAXI_S_df =3D (0x2 << 23) | OPC_MSA_I5_06, + OPC_CLTI_S_df =3D (0x2 << 23) | OPC_MSA_I5_07, + OPC_MAXI_U_df =3D (0x3 << 23) | OPC_MSA_I5_06, + OPC_CLTI_U_df =3D (0x3 << 23) | OPC_MSA_I5_07, + OPC_MINI_S_df =3D (0x4 << 23) | OPC_MSA_I5_06, + OPC_CLEI_S_df =3D (0x4 << 23) | OPC_MSA_I5_07, + OPC_MINI_U_df =3D (0x5 << 23) | OPC_MSA_I5_06, + OPC_CLEI_U_df =3D (0x5 << 23) | OPC_MSA_I5_07, + OPC_LDI_df =3D (0x6 << 23) | OPC_MSA_I5_07, + + /* I8 instruction */ + OPC_ANDI_B =3D (0x0 << 24) | OPC_MSA_I8_00, + OPC_BMNZI_B =3D (0x0 << 24) | OPC_MSA_I8_01, + OPC_SHF_B =3D (0x0 << 24) | OPC_MSA_I8_02, + OPC_ORI_B =3D (0x1 << 24) | OPC_MSA_I8_00, + OPC_BMZI_B =3D (0x1 << 24) | OPC_MSA_I8_01, + OPC_SHF_H =3D (0x1 << 24) | OPC_MSA_I8_02, + OPC_NORI_B =3D (0x2 << 24) | OPC_MSA_I8_00, + OPC_BSELI_B =3D (0x2 << 24) | OPC_MSA_I8_01, + OPC_SHF_W =3D (0x2 << 24) | OPC_MSA_I8_02, + OPC_XORI_B =3D (0x3 << 24) | OPC_MSA_I8_00, + + /* VEC/2R/2RF instruction */ + OPC_AND_V =3D (0x00 << 21) | OPC_MSA_VEC, + OPC_OR_V =3D (0x01 << 21) | OPC_MSA_VEC, + OPC_NOR_V =3D (0x02 << 21) | OPC_MSA_VEC, + OPC_XOR_V =3D (0x03 << 21) | OPC_MSA_VEC, + OPC_BMNZ_V =3D (0x04 << 21) | OPC_MSA_VEC, + OPC_BMZ_V =3D (0x05 << 21) | OPC_MSA_VEC, + OPC_BSEL_V =3D (0x06 << 21) | OPC_MSA_VEC, + + OPC_MSA_2R =3D (0x18 << 21) | OPC_MSA_VEC, + OPC_MSA_2RF =3D (0x19 << 21) | OPC_MSA_VEC, + + /* 2R instruction df(bits 17..16) =3D _b, _h, _w, _d */ + OPC_FILL_df =3D (0x00 << 18) | OPC_MSA_2R, + OPC_PCNT_df =3D (0x01 << 18) | OPC_MSA_2R, + OPC_NLOC_df =3D (0x02 << 18) | OPC_MSA_2R, + OPC_NLZC_df =3D (0x03 << 18) | OPC_MSA_2R, + + /* 2RF instruction df(bit 16) =3D _w, _d */ + OPC_FCLASS_df =3D (0x00 << 17) | OPC_MSA_2RF, + OPC_FTRUNC_S_df =3D (0x01 << 17) | OPC_MSA_2RF, + OPC_FTRUNC_U_df =3D (0x02 << 17) | OPC_MSA_2RF, + OPC_FSQRT_df =3D (0x03 << 17) | OPC_MSA_2RF, + OPC_FRSQRT_df =3D (0x04 << 17) | OPC_MSA_2RF, + OPC_FRCP_df =3D (0x05 << 17) | OPC_MSA_2RF, + OPC_FRINT_df =3D (0x06 << 17) | OPC_MSA_2RF, + OPC_FLOG2_df =3D (0x07 << 17) | OPC_MSA_2RF, + OPC_FEXUPL_df =3D (0x08 << 17) | OPC_MSA_2RF, + OPC_FEXUPR_df =3D (0x09 << 17) | OPC_MSA_2RF, + OPC_FFQL_df =3D (0x0A << 17) | OPC_MSA_2RF, + OPC_FFQR_df =3D (0x0B << 17) | OPC_MSA_2RF, + OPC_FTINT_S_df =3D (0x0C << 17) | OPC_MSA_2RF, + OPC_FTINT_U_df =3D (0x0D << 17) | OPC_MSA_2RF, + OPC_FFINT_S_df =3D (0x0E << 17) | OPC_MSA_2RF, + OPC_FFINT_U_df =3D (0x0F << 17) | OPC_MSA_2RF, + + /* 3R instruction df(bits 22..21) =3D _b, _h, _w, d */ + OPC_SLL_df =3D (0x0 << 23) | OPC_MSA_3R_0D, + OPC_ADDV_df =3D (0x0 << 23) | OPC_MSA_3R_0E, + OPC_CEQ_df =3D (0x0 << 23) | OPC_MSA_3R_0F, + OPC_ADD_A_df =3D (0x0 << 23) | OPC_MSA_3R_10, + OPC_SUBS_S_df =3D (0x0 << 23) | OPC_MSA_3R_11, + OPC_MULV_df =3D (0x0 << 23) | OPC_MSA_3R_12, + OPC_DOTP_S_df =3D (0x0 << 23) | OPC_MSA_3R_13, + OPC_SLD_df =3D (0x0 << 23) | OPC_MSA_3R_14, + OPC_VSHF_df =3D (0x0 << 23) | OPC_MSA_3R_15, + OPC_SRA_df =3D (0x1 << 23) | OPC_MSA_3R_0D, + OPC_SUBV_df =3D (0x1 << 23) | OPC_MSA_3R_0E, + OPC_ADDS_A_df =3D (0x1 << 23) | OPC_MSA_3R_10, + OPC_SUBS_U_df =3D (0x1 << 23) | OPC_MSA_3R_11, + OPC_MADDV_df =3D (0x1 << 23) | OPC_MSA_3R_12, + OPC_DOTP_U_df =3D (0x1 << 23) | OPC_MSA_3R_13, + OPC_SPLAT_df =3D (0x1 << 23) | OPC_MSA_3R_14, + OPC_SRAR_df =3D (0x1 << 23) | OPC_MSA_3R_15, + OPC_SRL_df =3D (0x2 << 23) | OPC_MSA_3R_0D, + OPC_MAX_S_df =3D (0x2 << 23) | OPC_MSA_3R_0E, + OPC_CLT_S_df =3D (0x2 << 23) | OPC_MSA_3R_0F, + OPC_ADDS_S_df =3D (0x2 << 23) | OPC_MSA_3R_10, + OPC_SUBSUS_U_df =3D (0x2 << 23) | OPC_MSA_3R_11, + OPC_MSUBV_df =3D (0x2 << 23) | OPC_MSA_3R_12, + OPC_DPADD_S_df =3D (0x2 << 23) | OPC_MSA_3R_13, + OPC_PCKEV_df =3D (0x2 << 23) | OPC_MSA_3R_14, + OPC_SRLR_df =3D (0x2 << 23) | OPC_MSA_3R_15, + OPC_BCLR_df =3D (0x3 << 23) | OPC_MSA_3R_0D, + OPC_MAX_U_df =3D (0x3 << 23) | OPC_MSA_3R_0E, + OPC_CLT_U_df =3D (0x3 << 23) | OPC_MSA_3R_0F, + OPC_ADDS_U_df =3D (0x3 << 23) | OPC_MSA_3R_10, + OPC_SUBSUU_S_df =3D (0x3 << 23) | OPC_MSA_3R_11, + OPC_DPADD_U_df =3D (0x3 << 23) | OPC_MSA_3R_13, + OPC_PCKOD_df =3D (0x3 << 23) | OPC_MSA_3R_14, + OPC_BSET_df =3D (0x4 << 23) | OPC_MSA_3R_0D, + OPC_MIN_S_df =3D (0x4 << 23) | OPC_MSA_3R_0E, + OPC_CLE_S_df =3D (0x4 << 23) | OPC_MSA_3R_0F, + OPC_AVE_S_df =3D (0x4 << 23) | OPC_MSA_3R_10, + OPC_ASUB_S_df =3D (0x4 << 23) | OPC_MSA_3R_11, + OPC_DIV_S_df =3D (0x4 << 23) | OPC_MSA_3R_12, + OPC_DPSUB_S_df =3D (0x4 << 23) | OPC_MSA_3R_13, + OPC_ILVL_df =3D (0x4 << 23) | OPC_MSA_3R_14, + OPC_HADD_S_df =3D (0x4 << 23) | OPC_MSA_3R_15, + OPC_BNEG_df =3D (0x5 << 23) | OPC_MSA_3R_0D, + OPC_MIN_U_df =3D (0x5 << 23) | OPC_MSA_3R_0E, + OPC_CLE_U_df =3D (0x5 << 23) | OPC_MSA_3R_0F, + OPC_AVE_U_df =3D (0x5 << 23) | OPC_MSA_3R_10, + OPC_ASUB_U_df =3D (0x5 << 23) | OPC_MSA_3R_11, + OPC_DIV_U_df =3D (0x5 << 23) | OPC_MSA_3R_12, + OPC_DPSUB_U_df =3D (0x5 << 23) | OPC_MSA_3R_13, + OPC_ILVR_df =3D (0x5 << 23) | OPC_MSA_3R_14, + OPC_HADD_U_df =3D (0x5 << 23) | OPC_MSA_3R_15, + OPC_BINSL_df =3D (0x6 << 23) | OPC_MSA_3R_0D, + OPC_MAX_A_df =3D (0x6 << 23) | OPC_MSA_3R_0E, + OPC_AVER_S_df =3D (0x6 << 23) | OPC_MSA_3R_10, + OPC_MOD_S_df =3D (0x6 << 23) | OPC_MSA_3R_12, + OPC_ILVEV_df =3D (0x6 << 23) | OPC_MSA_3R_14, + OPC_HSUB_S_df =3D (0x6 << 23) | OPC_MSA_3R_15, + OPC_BINSR_df =3D (0x7 << 23) | OPC_MSA_3R_0D, + OPC_MIN_A_df =3D (0x7 << 23) | OPC_MSA_3R_0E, + OPC_AVER_U_df =3D (0x7 << 23) | OPC_MSA_3R_10, + OPC_MOD_U_df =3D (0x7 << 23) | OPC_MSA_3R_12, + OPC_ILVOD_df =3D (0x7 << 23) | OPC_MSA_3R_14, + OPC_HSUB_U_df =3D (0x7 << 23) | OPC_MSA_3R_15, + + /* ELM instructions df(bits 21..16) =3D _b, _h, _w, _d */ + OPC_SLDI_df =3D (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM, + OPC_CTCMSA =3D (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM, + OPC_SPLATI_df =3D (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM, + OPC_CFCMSA =3D (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM, + OPC_COPY_S_df =3D (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM, + OPC_MOVE_V =3D (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM, + OPC_COPY_U_df =3D (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM, + OPC_INSERT_df =3D (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM, + OPC_INSVE_df =3D (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM, + + /* 3RF instruction _df(bit 21) =3D _w, _d */ + OPC_FCAF_df =3D (0x0 << 22) | OPC_MSA_3RF_1A, + OPC_FADD_df =3D (0x0 << 22) | OPC_MSA_3RF_1B, + OPC_FCUN_df =3D (0x1 << 22) | OPC_MSA_3RF_1A, + OPC_FSUB_df =3D (0x1 << 22) | OPC_MSA_3RF_1B, + OPC_FCOR_df =3D (0x1 << 22) | OPC_MSA_3RF_1C, + OPC_FCEQ_df =3D (0x2 << 22) | OPC_MSA_3RF_1A, + OPC_FMUL_df =3D (0x2 << 22) | OPC_MSA_3RF_1B, + OPC_FCUNE_df =3D (0x2 << 22) | OPC_MSA_3RF_1C, + OPC_FCUEQ_df =3D (0x3 << 22) | OPC_MSA_3RF_1A, + OPC_FDIV_df =3D (0x3 << 22) | OPC_MSA_3RF_1B, + OPC_FCNE_df =3D (0x3 << 22) | OPC_MSA_3RF_1C, + OPC_FCLT_df =3D (0x4 << 22) | OPC_MSA_3RF_1A, + OPC_FMADD_df =3D (0x4 << 22) | OPC_MSA_3RF_1B, + OPC_MUL_Q_df =3D (0x4 << 22) | OPC_MSA_3RF_1C, + OPC_FCULT_df =3D (0x5 << 22) | OPC_MSA_3RF_1A, + OPC_FMSUB_df =3D (0x5 << 22) | OPC_MSA_3RF_1B, + OPC_MADD_Q_df =3D (0x5 << 22) | OPC_MSA_3RF_1C, + OPC_FCLE_df =3D (0x6 << 22) | OPC_MSA_3RF_1A, + OPC_MSUB_Q_df =3D (0x6 << 22) | OPC_MSA_3RF_1C, + OPC_FCULE_df =3D (0x7 << 22) | OPC_MSA_3RF_1A, + OPC_FEXP2_df =3D (0x7 << 22) | OPC_MSA_3RF_1B, + OPC_FSAF_df =3D (0x8 << 22) | OPC_MSA_3RF_1A, + OPC_FEXDO_df =3D (0x8 << 22) | OPC_MSA_3RF_1B, + OPC_FSUN_df =3D (0x9 << 22) | OPC_MSA_3RF_1A, + OPC_FSOR_df =3D (0x9 << 22) | OPC_MSA_3RF_1C, + OPC_FSEQ_df =3D (0xA << 22) | OPC_MSA_3RF_1A, + OPC_FTQ_df =3D (0xA << 22) | OPC_MSA_3RF_1B, + OPC_FSUNE_df =3D (0xA << 22) | OPC_MSA_3RF_1C, + OPC_FSUEQ_df =3D (0xB << 22) | OPC_MSA_3RF_1A, + OPC_FSNE_df =3D (0xB << 22) | OPC_MSA_3RF_1C, + OPC_FSLT_df =3D (0xC << 22) | OPC_MSA_3RF_1A, + OPC_FMIN_df =3D (0xC << 22) | OPC_MSA_3RF_1B, + OPC_MULR_Q_df =3D (0xC << 22) | OPC_MSA_3RF_1C, + OPC_FSULT_df =3D (0xD << 22) | OPC_MSA_3RF_1A, + OPC_FMIN_A_df =3D (0xD << 22) | OPC_MSA_3RF_1B, + OPC_MADDR_Q_df =3D (0xD << 22) | OPC_MSA_3RF_1C, + OPC_FSLE_df =3D (0xE << 22) | OPC_MSA_3RF_1A, + OPC_FMAX_df =3D (0xE << 22) | OPC_MSA_3RF_1B, + OPC_MSUBR_Q_df =3D (0xE << 22) | OPC_MSA_3RF_1C, + OPC_FSULE_df =3D (0xF << 22) | OPC_MSA_3RF_1A, + OPC_FMAX_A_df =3D (0xF << 22) | OPC_MSA_3RF_1B, + + /* BIT instruction df(bits 22..16) =3D _B _H _W _D */ + OPC_SLLI_df =3D (0x0 << 23) | OPC_MSA_BIT_09, + OPC_SAT_S_df =3D (0x0 << 23) | OPC_MSA_BIT_0A, + OPC_SRAI_df =3D (0x1 << 23) | OPC_MSA_BIT_09, + OPC_SAT_U_df =3D (0x1 << 23) | OPC_MSA_BIT_0A, + OPC_SRLI_df =3D (0x2 << 23) | OPC_MSA_BIT_09, + OPC_SRARI_df =3D (0x2 << 23) | OPC_MSA_BIT_0A, + OPC_BCLRI_df =3D (0x3 << 23) | OPC_MSA_BIT_09, + OPC_SRLRI_df =3D (0x3 << 23) | OPC_MSA_BIT_0A, + OPC_BSETI_df =3D (0x4 << 23) | OPC_MSA_BIT_09, + OPC_BNEGI_df =3D (0x5 << 23) | OPC_MSA_BIT_09, + OPC_BINSLI_df =3D (0x6 << 23) | OPC_MSA_BIT_09, + OPC_BINSRI_df =3D (0x7 << 23) | OPC_MSA_BIT_09, +}; + +static const char * const msaregnames[] =3D { + "w0.d0", "w0.d1", "w1.d0", "w1.d1", + "w2.d0", "w2.d1", "w3.d0", "w3.d1", + "w4.d0", "w4.d1", "w5.d0", "w5.d1", + "w6.d0", "w6.d1", "w7.d0", "w7.d1", + "w8.d0", "w8.d1", "w9.d0", "w9.d1", + "w10.d0", "w10.d1", "w11.d0", "w11.d1", + "w12.d0", "w12.d1", "w13.d0", "w13.d1", + "w14.d0", "w14.d1", "w15.d0", "w15.d1", + "w16.d0", "w16.d1", "w17.d0", "w17.d1", + "w18.d0", "w18.d1", "w19.d0", "w19.d1", + "w20.d0", "w20.d1", "w21.d0", "w21.d1", + "w22.d0", "w22.d1", "w23.d0", "w23.d1", + "w24.d0", "w24.d1", "w25.d0", "w25.d1", + "w26.d0", "w26.d1", "w27.d0", "w27.d1", + "w28.d0", "w28.d1", "w29.d0", "w29.d1", + "w30.d0", "w30.d1", "w31.d0", "w31.d1", +}; + +static TCGv_i64 msa_wr_d[64]; + +static inline int check_msa_access(DisasContext *ctx) +{ + if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) && + !(ctx->hflags & MIPS_HFLAG_F64))) { + generate_exception_end(ctx, EXCP_RI); + return 0; + } + + if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) { + if (ctx->insn_flags & ASE_MSA) { + generate_exception_end(ctx, EXCP_MSADIS); + return 0; + } else { + generate_exception_end(ctx, EXCP_RI); + return 0; + } + } + return 1; +} + +static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt) +{ + /* generates tcg ops to check if any element is 0 */ + /* Note this function only works with MSA_WRLEN =3D 128 */ + uint64_t eval_zero_or_big =3D 0; + uint64_t eval_big =3D 0; + TCGv_i64 t0 =3D tcg_temp_new_i64(); + TCGv_i64 t1 =3D tcg_temp_new_i64(); + switch (df) { + case DF_BYTE: + eval_zero_or_big =3D 0x0101010101010101ULL; + eval_big =3D 0x8080808080808080ULL; + break; + case DF_HALF: + eval_zero_or_big =3D 0x0001000100010001ULL; + eval_big =3D 0x8000800080008000ULL; + break; + case DF_WORD: + eval_zero_or_big =3D 0x0000000100000001ULL; + eval_big =3D 0x8000000080000000ULL; + break; + case DF_DOUBLE: + eval_zero_or_big =3D 0x0000000000000001ULL; + eval_big =3D 0x8000000000000000ULL; + break; + } + tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big); + tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]); + tcg_gen_andi_i64(t0, t0, eval_big); + tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big); + tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]); + tcg_gen_andi_i64(t1, t1, eval_big); + tcg_gen_or_i64(t0, t0, t1); + /* if all bits are zero then all elements are not zero */ + /* if some bit is non-zero then some element is zero */ + tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0); + tcg_gen_trunc_i64_tl(tresult, t0); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); +} + +static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t = op1) +{ + uint8_t df =3D (ctx->opcode >> 21) & 0x3; + uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; + int64_t s16 =3D (int16_t)ctx->opcode; + + check_msa_access(ctx); + + if (ctx->hflags & MIPS_HFLAG_BMASK) { + generate_exception_end(ctx, EXCP_RI); + return; + } + switch (op1) { + case OPC_BZ_V: + case OPC_BNZ_V: + { + TCGv_i64 t0 =3D tcg_temp_new_i64(); + tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]); + tcg_gen_setcondi_i64((op1 =3D=3D OPC_BZ_V) ? + TCG_COND_EQ : TCG_COND_NE, t0, t0, 0); + tcg_gen_trunc_i64_tl(bcond, t0); + tcg_temp_free_i64(t0); + } + break; + case OPC_BZ_B: + case OPC_BZ_H: + case OPC_BZ_W: + case OPC_BZ_D: + gen_check_zero_element(bcond, df, wt); + break; + case OPC_BNZ_B: + case OPC_BNZ_H: + case OPC_BNZ_W: + case OPC_BNZ_D: + gen_check_zero_element(bcond, df, wt); + tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0); + break; + } + + ctx->btarget =3D ctx->base.pc_next + (s16 << 2) + 4; + + ctx->hflags |=3D MIPS_HFLAG_BC; + ctx->hflags |=3D MIPS_HFLAG_BDS32; +} + +static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24))) + uint8_t i8 =3D (ctx->opcode >> 16) & 0xff; + uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; + uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 twd =3D tcg_const_i32(wd); + TCGv_i32 tws =3D tcg_const_i32(ws); + TCGv_i32 ti8 =3D tcg_const_i32(i8); + + switch (MASK_MSA_I8(ctx->opcode)) { + case OPC_ANDI_B: + gen_helper_msa_andi_b(cpu_env, twd, tws, ti8); + break; + case OPC_ORI_B: + gen_helper_msa_ori_b(cpu_env, twd, tws, ti8); + break; + case OPC_NORI_B: + gen_helper_msa_nori_b(cpu_env, twd, tws, ti8); + break; + case OPC_XORI_B: + gen_helper_msa_xori_b(cpu_env, twd, tws, ti8); + break; + case OPC_BMNZI_B: + gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8); + break; + case OPC_BMZI_B: + gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8); + break; + case OPC_BSELI_B: + gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8); + break; + case OPC_SHF_B: + case OPC_SHF_H: + case OPC_SHF_W: + { + uint8_t df =3D (ctx->opcode >> 24) & 0x3; + if (df =3D=3D DF_DOUBLE) { + generate_exception_end(ctx, EXCP_RI); + } else { + TCGv_i32 tdf =3D tcg_const_i32(df); + gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8); + tcg_temp_free_i32(tdf); + } + } + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(ti8); +} + +static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) + uint8_t df =3D (ctx->opcode >> 21) & 0x3; + int8_t s5 =3D (int8_t) sextract32(ctx->opcode, 16, 5); + uint8_t u5 =3D (ctx->opcode >> 16) & 0x1f; + uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; + uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 tdf =3D tcg_const_i32(df); + TCGv_i32 twd =3D tcg_const_i32(wd); + TCGv_i32 tws =3D tcg_const_i32(ws); + TCGv_i32 timm =3D tcg_temp_new_i32(); + tcg_gen_movi_i32(timm, u5); + + switch (MASK_MSA_I5(ctx->opcode)) { + case OPC_ADDVI_df: + gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_SUBVI_df: + gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_MAXI_S_df: + tcg_gen_movi_i32(timm, s5); + gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_MAXI_U_df: + gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_MINI_S_df: + tcg_gen_movi_i32(timm, s5); + gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_MINI_U_df: + gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_CEQI_df: + tcg_gen_movi_i32(timm, s5); + gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_CLTI_S_df: + tcg_gen_movi_i32(timm, s5); + gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_CLTI_U_df: + gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_CLEI_S_df: + tcg_gen_movi_i32(timm, s5); + gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_CLEI_U_df: + gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_LDI_df: + { + int32_t s10 =3D sextract32(ctx->opcode, 11, 10); + tcg_gen_movi_i32(timm, s10); + gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm); + } + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free_i32(tdf); + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(timm); +} + +static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) + uint8_t dfm =3D (ctx->opcode >> 16) & 0x7f; + uint32_t df =3D 0, m =3D 0; + uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; + uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 tdf; + TCGv_i32 tm; + TCGv_i32 twd; + TCGv_i32 tws; + + if ((dfm & 0x40) =3D=3D 0x00) { + m =3D dfm & 0x3f; + df =3D DF_DOUBLE; + } else if ((dfm & 0x60) =3D=3D 0x40) { + m =3D dfm & 0x1f; + df =3D DF_WORD; + } else if ((dfm & 0x70) =3D=3D 0x60) { + m =3D dfm & 0x0f; + df =3D DF_HALF; + } else if ((dfm & 0x78) =3D=3D 0x70) { + m =3D dfm & 0x7; + df =3D DF_BYTE; + } else { + generate_exception_end(ctx, EXCP_RI); + return; + } + + tdf =3D tcg_const_i32(df); + tm =3D tcg_const_i32(m); + twd =3D tcg_const_i32(wd); + tws =3D tcg_const_i32(ws); + + switch (MASK_MSA_BIT(ctx->opcode)) { + case OPC_SLLI_df: + gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SRAI_df: + gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SRLI_df: + gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_BCLRI_df: + gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_BSETI_df: + gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_BNEGI_df: + gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_BINSLI_df: + gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_BINSRI_df: + gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SAT_S_df: + gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SAT_U_df: + gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SRARI_df: + gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SRLRI_df: + gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm); + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free_i32(tdf); + tcg_temp_free_i32(tm); + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); +} + +static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) + uint8_t df =3D (ctx->opcode >> 21) & 0x3; + uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; + uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; + uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 tdf =3D tcg_const_i32(df); + TCGv_i32 twd =3D tcg_const_i32(wd); + TCGv_i32 tws =3D tcg_const_i32(ws); + TCGv_i32 twt =3D tcg_const_i32(wt); + + switch (MASK_MSA_3R(ctx->opcode)) { + case OPC_BINSL_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_binsl_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_binsl_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_binsl_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_binsl_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BINSR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_binsr_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_binsr_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_binsr_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_binsr_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BCLR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_bclr_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_bclr_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_bclr_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_bclr_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BNEG_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_bneg_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_bneg_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_bneg_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_bneg_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BSET_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_bset_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_bset_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_bset_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_bset_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ADD_A_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_add_a_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_add_a_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_add_a_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_add_a_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ADDS_A_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_adds_a_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_adds_a_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_adds_a_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_adds_a_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ADDS_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_adds_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_adds_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_adds_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_adds_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ADDS_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_adds_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_adds_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_adds_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_adds_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ADDV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_addv_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_addv_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_addv_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_addv_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_AVE_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ave_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ave_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ave_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ave_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_AVE_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ave_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ave_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ave_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ave_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_AVER_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_aver_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_aver_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_aver_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_aver_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_AVER_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_aver_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_aver_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_aver_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_aver_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CEQ_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ceq_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ceq_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ceq_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ceq_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CLE_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_cle_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_cle_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_cle_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_cle_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CLE_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_cle_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_cle_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_cle_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_cle_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CLT_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_clt_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_clt_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_clt_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_clt_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CLT_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_clt_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_clt_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_clt_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_clt_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DIV_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_div_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_div_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_div_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_div_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DIV_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_div_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_div_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_div_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_div_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MAX_A_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_max_a_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_max_a_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_max_a_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_max_a_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MAX_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_max_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_max_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_max_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_max_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MAX_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_max_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_max_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_max_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_max_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MIN_A_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_min_a_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_min_a_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_min_a_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_min_a_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MIN_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_min_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_min_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_min_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_min_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MIN_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_min_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_min_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_min_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_min_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MOD_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_mod_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_mod_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_mod_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_mod_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MOD_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_mod_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_mod_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_mod_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_mod_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MADDV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_maddv_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_maddv_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_maddv_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_maddv_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MSUBV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_msubv_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_msubv_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_msubv_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_msubv_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ASUB_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_asub_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_asub_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_asub_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_asub_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ASUB_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_asub_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_asub_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_asub_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_asub_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ILVEV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ilvev_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ilvev_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ilvev_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ilvev_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ILVOD_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ilvod_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ilvod_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ilvod_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ilvod_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ILVL_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ilvl_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ilvl_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ilvl_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ilvl_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ILVR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ilvr_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ilvr_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ilvr_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ilvr_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_PCKEV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_pckev_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_pckev_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_pckev_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_pckev_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_PCKOD_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_pckod_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_pckod_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_pckod_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_pckod_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SLL_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_sll_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_sll_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_sll_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_sll_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SRA_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_sra_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_sra_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_sra_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_sra_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SRAR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_srar_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_srar_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_srar_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_srar_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SRL_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_srl_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_srl_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_srl_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_srl_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SRLR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_srlr_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_srlr_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_srlr_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_srlr_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SUBS_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_subs_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_subs_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_subs_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_subs_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MULV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_mulv_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_mulv_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_mulv_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_mulv_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SLD_df: + gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_VSHF_df: + gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_SUBV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_subv_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_subv_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_subv_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_subv_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SUBS_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_subs_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_subs_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_subs_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_subs_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SPLAT_df: + gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_SUBSUS_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_subsus_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_subsus_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_subsus_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_subsus_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SUBSUU_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_subsuu_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_subsuu_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_subsuu_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_subsuu_s_d(cpu_env, twd, tws, twt); + break; + } + break; + + case OPC_DOTP_S_df: + case OPC_DOTP_U_df: + case OPC_DPADD_S_df: + case OPC_DPADD_U_df: + case OPC_DPSUB_S_df: + case OPC_HADD_S_df: + case OPC_DPSUB_U_df: + case OPC_HADD_U_df: + case OPC_HSUB_S_df: + case OPC_HSUB_U_df: + if (df =3D=3D DF_BYTE) { + generate_exception_end(ctx, EXCP_RI); + break; + } + switch (MASK_MSA_3R(ctx->opcode)) { + case OPC_HADD_S_df: + switch (df) { + case DF_HALF: + gen_helper_msa_hadd_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_hadd_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_hadd_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_HADD_U_df: + switch (df) { + case DF_HALF: + gen_helper_msa_hadd_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_hadd_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_hadd_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_HSUB_S_df: + switch (df) { + case DF_HALF: + gen_helper_msa_hsub_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_hsub_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_hsub_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_HSUB_U_df: + switch (df) { + case DF_HALF: + gen_helper_msa_hsub_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_hsub_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_hsub_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DOTP_S_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dotp_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dotp_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dotp_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DOTP_U_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dotp_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dotp_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dotp_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DPADD_S_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dpadd_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dpadd_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dpadd_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DPADD_U_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dpadd_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dpadd_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dpadd_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DPSUB_S_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dpsub_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dpsub_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dpsub_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DPSUB_U_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dpsub_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dpsub_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dpsub_u_d(cpu_env, twd, tws, twt); + break; + } + break; + } + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + break; + } + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(twt); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16))) + uint8_t source =3D (ctx->opcode >> 11) & 0x1f; + uint8_t dest =3D (ctx->opcode >> 6) & 0x1f; + TCGv telm =3D tcg_temp_new(); + TCGv_i32 tsr =3D tcg_const_i32(source); + TCGv_i32 tdt =3D tcg_const_i32(dest); + + switch (MASK_MSA_ELM_DF3E(ctx->opcode)) { + case OPC_CTCMSA: + gen_load_gpr(telm, source); + gen_helper_msa_ctcmsa(cpu_env, telm, tdt); + break; + case OPC_CFCMSA: + gen_helper_msa_cfcmsa(telm, cpu_env, tsr); + gen_store_gpr(telm, dest); + break; + case OPC_MOVE_V: + gen_helper_msa_move_v(cpu_env, tdt, tsr); + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free(telm); + tcg_temp_free_i32(tdt); + tcg_temp_free_i32(tsr); +} + +static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t = df, + uint32_t n) +{ +#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) + uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; + uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 tws =3D tcg_const_i32(ws); + TCGv_i32 twd =3D tcg_const_i32(wd); + TCGv_i32 tn =3D tcg_const_i32(n); + TCGv_i32 tdf =3D tcg_const_i32(df); + + switch (MASK_MSA_ELM(ctx->opcode)) { + case OPC_SLDI_df: + gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_SPLATI_df: + gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_INSVE_df: + gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_COPY_S_df: + case OPC_COPY_U_df: + case OPC_INSERT_df: +#if !defined(TARGET_MIPS64) + /* Double format valid only for MIPS64 */ + if (df =3D=3D DF_DOUBLE) { + generate_exception_end(ctx, EXCP_RI); + break; + } + if ((MASK_MSA_ELM(ctx->opcode) =3D=3D OPC_COPY_U_df) && + (df =3D=3D DF_WORD)) { + generate_exception_end(ctx, EXCP_RI); + break; + } +#endif + switch (MASK_MSA_ELM(ctx->opcode)) { + case OPC_COPY_S_df: + if (likely(wd !=3D 0)) { + switch (df) { + case DF_BYTE: + gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn); + break; + case DF_HALF: + gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn); + break; + case DF_WORD: + gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn); + break; +#if defined(TARGET_MIPS64) + case DF_DOUBLE: + gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn); + break; +#endif + default: + assert(0); + } + } + break; + case OPC_COPY_U_df: + if (likely(wd !=3D 0)) { + switch (df) { + case DF_BYTE: + gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn); + break; + case DF_HALF: + gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn); + break; +#if defined(TARGET_MIPS64) + case DF_WORD: + gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn); + break; +#endif + default: + assert(0); + } + } + break; + case OPC_INSERT_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_insert_b(cpu_env, twd, tws, tn); + break; + case DF_HALF: + gen_helper_msa_insert_h(cpu_env, twd, tws, tn); + break; + case DF_WORD: + gen_helper_msa_insert_w(cpu_env, twd, tws, tn); + break; +#if defined(TARGET_MIPS64) + case DF_DOUBLE: + gen_helper_msa_insert_d(cpu_env, twd, tws, tn); + break; +#endif + default: + assert(0); + } + break; + } + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + } + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(tn); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx) +{ + uint8_t dfn =3D (ctx->opcode >> 16) & 0x3f; + uint32_t df =3D 0, n =3D 0; + + if ((dfn & 0x30) =3D=3D 0x00) { + n =3D dfn & 0x0f; + df =3D DF_BYTE; + } else if ((dfn & 0x38) =3D=3D 0x20) { + n =3D dfn & 0x07; + df =3D DF_HALF; + } else if ((dfn & 0x3c) =3D=3D 0x30) { + n =3D dfn & 0x03; + df =3D DF_WORD; + } else if ((dfn & 0x3e) =3D=3D 0x38) { + n =3D dfn & 0x01; + df =3D DF_DOUBLE; + } else if (dfn =3D=3D 0x3E) { + /* CTCMSA, CFCMSA, MOVE.V */ + gen_msa_elm_3e(env, ctx); + return; + } else { + generate_exception_end(ctx, EXCP_RI); + return; + } + + gen_msa_elm_df(env, ctx, df, n); +} + +static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) + uint8_t df =3D (ctx->opcode >> 21) & 0x1; + uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; + uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; + uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 twd =3D tcg_const_i32(wd); + TCGv_i32 tws =3D tcg_const_i32(ws); + TCGv_i32 twt =3D tcg_const_i32(wt); + TCGv_i32 tdf =3D tcg_temp_new_i32(); + + /* adjust df value for floating-point instruction */ + tcg_gen_movi_i32(tdf, df + 2); + + switch (MASK_MSA_3RF(ctx->opcode)) { + case OPC_FCAF_df: + gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FADD_df: + gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCUN_df: + gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSUB_df: + gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCOR_df: + gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCEQ_df: + gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMUL_df: + gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCUNE_df: + gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCUEQ_df: + gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FDIV_df: + gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCNE_df: + gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCLT_df: + gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMADD_df: + gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MUL_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCULT_df: + gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMSUB_df: + gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MADD_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCLE_df: + gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MSUB_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCULE_df: + gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FEXP2_df: + gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSAF_df: + gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FEXDO_df: + gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSUN_df: + gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSOR_df: + gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSEQ_df: + gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FTQ_df: + gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSUNE_df: + gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSUEQ_df: + gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSNE_df: + gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSLT_df: + gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMIN_df: + gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MULR_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSULT_df: + gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMIN_A_df: + gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MADDR_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSLE_df: + gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMAX_df: + gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MSUBR_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSULE_df: + gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMAX_A_df: + gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt); + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(twt); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \ + (op & (0x7 << 18))) + uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; + uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; + uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; + uint8_t df =3D (ctx->opcode >> 16) & 0x3; + TCGv_i32 twd =3D tcg_const_i32(wd); + TCGv_i32 tws =3D tcg_const_i32(ws); + TCGv_i32 twt =3D tcg_const_i32(wt); + TCGv_i32 tdf =3D tcg_const_i32(df); + + switch (MASK_MSA_2R(ctx->opcode)) { + case OPC_FILL_df: +#if !defined(TARGET_MIPS64) + /* Double format valid only for MIPS64 */ + if (df =3D=3D DF_DOUBLE) { + generate_exception_end(ctx, EXCP_RI); + break; + } +#endif + gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */ + break; + case OPC_NLOC_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_nloc_b(cpu_env, twd, tws); + break; + case DF_HALF: + gen_helper_msa_nloc_h(cpu_env, twd, tws); + break; + case DF_WORD: + gen_helper_msa_nloc_w(cpu_env, twd, tws); + break; + case DF_DOUBLE: + gen_helper_msa_nloc_d(cpu_env, twd, tws); + break; + } + break; + case OPC_NLZC_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_nlzc_b(cpu_env, twd, tws); + break; + case DF_HALF: + gen_helper_msa_nlzc_h(cpu_env, twd, tws); + break; + case DF_WORD: + gen_helper_msa_nlzc_w(cpu_env, twd, tws); + break; + case DF_DOUBLE: + gen_helper_msa_nlzc_d(cpu_env, twd, tws); + break; + } + break; + case OPC_PCNT_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_pcnt_b(cpu_env, twd, tws); + break; + case DF_HALF: + gen_helper_msa_pcnt_h(cpu_env, twd, tws); + break; + case DF_WORD: + gen_helper_msa_pcnt_w(cpu_env, twd, tws); + break; + case DF_DOUBLE: + gen_helper_msa_pcnt_d(cpu_env, twd, tws); + break; + } + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(twt); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \ + (op & (0xf << 17))) + uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; + uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; + uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; + uint8_t df =3D (ctx->opcode >> 16) & 0x1; + TCGv_i32 twd =3D tcg_const_i32(wd); + TCGv_i32 tws =3D tcg_const_i32(ws); + TCGv_i32 twt =3D tcg_const_i32(wt); + /* adjust df value for floating-point instruction */ + TCGv_i32 tdf =3D tcg_const_i32(df + 2); + + switch (MASK_MSA_2RF(ctx->opcode)) { + case OPC_FCLASS_df: + gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws); + break; + case OPC_FTRUNC_S_df: + gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws); + break; + case OPC_FTRUNC_U_df: + gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws); + break; + case OPC_FSQRT_df: + gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws); + break; + case OPC_FRSQRT_df: + gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws); + break; + case OPC_FRCP_df: + gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws); + break; + case OPC_FRINT_df: + gen_helper_msa_frint_df(cpu_env, tdf, twd, tws); + break; + case OPC_FLOG2_df: + gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws); + break; + case OPC_FEXUPL_df: + gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws); + break; + case OPC_FEXUPR_df: + gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws); + break; + case OPC_FFQL_df: + gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws); + break; + case OPC_FFQR_df: + gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws); + break; + case OPC_FTINT_S_df: + gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws); + break; + case OPC_FTINT_U_df: + gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws); + break; + case OPC_FFINT_S_df: + gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws); + break; + case OPC_FFINT_U_df: + gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(twt); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx) +{ +#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21))) + uint8_t wt =3D (ctx->opcode >> 16) & 0x1f; + uint8_t ws =3D (ctx->opcode >> 11) & 0x1f; + uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; + TCGv_i32 twd =3D tcg_const_i32(wd); + TCGv_i32 tws =3D tcg_const_i32(ws); + TCGv_i32 twt =3D tcg_const_i32(wt); + + switch (MASK_MSA_VEC(ctx->opcode)) { + case OPC_AND_V: + gen_helper_msa_and_v(cpu_env, twd, tws, twt); + break; + case OPC_OR_V: + gen_helper_msa_or_v(cpu_env, twd, tws, twt); + break; + case OPC_NOR_V: + gen_helper_msa_nor_v(cpu_env, twd, tws, twt); + break; + case OPC_XOR_V: + gen_helper_msa_xor_v(cpu_env, twd, tws, twt); + break; + case OPC_BMNZ_V: + gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt); + break; + case OPC_BMZ_V: + gen_helper_msa_bmz_v(cpu_env, twd, tws, twt); + break; + case OPC_BSEL_V: + gen_helper_msa_bsel_v(cpu_env, twd, tws, twt); + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(twt); +} + +static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx) +{ + switch (MASK_MSA_VEC(ctx->opcode)) { + case OPC_AND_V: + case OPC_OR_V: + case OPC_NOR_V: + case OPC_XOR_V: + case OPC_BMNZ_V: + case OPC_BMZ_V: + case OPC_BSEL_V: + gen_msa_vec_v(env, ctx); + break; + case OPC_MSA_2R: + gen_msa_2r(env, ctx); + break; + case OPC_MSA_2RF: + gen_msa_2rf(env, ctx); + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +static void gen_msa(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D ctx->opcode; + check_insn(ctx, ASE_MSA); + check_msa_access(ctx); + + switch (MASK_MSA_MINOR(opcode)) { + case OPC_MSA_I8_00: + case OPC_MSA_I8_01: + case OPC_MSA_I8_02: + gen_msa_i8(env, ctx); + break; + case OPC_MSA_I5_06: + case OPC_MSA_I5_07: + gen_msa_i5(env, ctx); + break; + case OPC_MSA_BIT_09: + case OPC_MSA_BIT_0A: + gen_msa_bit(env, ctx); + break; + case OPC_MSA_3R_0D: + case OPC_MSA_3R_0E: + case OPC_MSA_3R_0F: + case OPC_MSA_3R_10: + case OPC_MSA_3R_11: + case OPC_MSA_3R_12: + case OPC_MSA_3R_13: + case OPC_MSA_3R_14: + case OPC_MSA_3R_15: + gen_msa_3r(env, ctx); + break; + case OPC_MSA_ELM: + gen_msa_elm(env, ctx); + break; + case OPC_MSA_3RF_1A: + case OPC_MSA_3RF_1B: + case OPC_MSA_3RF_1C: + gen_msa_3rf(env, ctx); + break; + case OPC_MSA_VEC: + gen_msa_vec(env, ctx); + break; + case OPC_LD_B: + case OPC_LD_H: + case OPC_LD_W: + case OPC_LD_D: + case OPC_ST_B: + case OPC_ST_H: + case OPC_ST_W: + case OPC_ST_D: + { + int32_t s10 =3D sextract32(ctx->opcode, 16, 10); + uint8_t rs =3D (ctx->opcode >> 11) & 0x1f; + uint8_t wd =3D (ctx->opcode >> 6) & 0x1f; + uint8_t df =3D (ctx->opcode >> 0) & 0x3; + + TCGv_i32 twd =3D tcg_const_i32(wd); + TCGv taddr =3D tcg_temp_new(); + gen_base_offset_addr(ctx, taddr, rs, s10 << df); + + switch (MASK_MSA_MINOR(opcode)) { + case OPC_LD_B: + gen_helper_msa_ld_b(cpu_env, twd, taddr); + break; + case OPC_LD_H: + gen_helper_msa_ld_h(cpu_env, twd, taddr); + break; + case OPC_LD_W: + gen_helper_msa_ld_w(cpu_env, twd, taddr); + break; + case OPC_LD_D: + gen_helper_msa_ld_d(cpu_env, twd, taddr); + break; + case OPC_ST_B: + gen_helper_msa_st_b(cpu_env, twd, taddr); + break; + case OPC_ST_H: + gen_helper_msa_st_h(cpu_env, twd, taddr); + break; + case OPC_ST_W: + gen_helper_msa_st_w(cpu_env, twd, taddr); + break; + case OPC_ST_D: + gen_helper_msa_st_d(cpu_env, twd, taddr); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free(taddr); + } + break; + default: + MIPS_INVAL("MSA instruction"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.48 as permitted sender) client-ip=209.85.221.48; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f48.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.48 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906555; cv=none; d=zohomail.com; s=zohoarc; b=De+8kftSeCzLi3DjbCKkU6uFpexGmk7ng36r0lg56uu7Q5+8pDbWqLsMs6csrm/tG2WKNf1HGklIAe8PIQ2/L+LcuNCR7TQ4U7MYwHD+UyDVdh+E5OcbgMZclnUEUc1tbXzHxaH0a7ISkT4/G/kFQgvPxq3W5/g3XRmGzb4X404= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906555; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=KhtgoDZLQcdddctuxNL94IkH0wF2YFhr3cZ6vXZZOCw=; b=cbWTzSQJzX2s8REKlN0mdLoF/Pl/HZ/VbTJLgwALVOycHb3vNn6MbG4gbK73jGOvJMwGb5/Y2wI8fL5xyp7pSDgs5ynqAh7AQG+Sd9l3m9Wp+GE6I5fLlHX+gbjqQYRZNGlgmioDXDe5k/dY2hwBJWvMdAzZTA4Y8mOhJu0gPNQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.48 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) by mx.zohomail.com with SMTPS id 1605906555161619.867076509643; Fri, 20 Nov 2020 13:09:15 -0800 (PST) Received: by mail-wr1-f48.google.com with SMTP id l1so11664428wrb.9 for ; Fri, 20 Nov 2020 13:09:14 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id f16sm6335737wrp.66.2020.11.20.13.09.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KhtgoDZLQcdddctuxNL94IkH0wF2YFhr3cZ6vXZZOCw=; b=qZvs/x6nBVrRxKs1ouIF7QLnwzfY+AqXYDxxTQuu0d+3mFSGWgUw9LL/L4UsqPMZs2 CZsJypLK1xP/2MUyYyGGtWhKD1DsXIzu9OjQpEihi/l+038l6CoMx3mJkbkWN3xyJXhy pAaaAlKy8/p7D/CbJQHaHBf29qOFOCGM8pzcmiWaqtMFFGtdlCgk7n7dtQNuyD/oh9vN x4phKyJAr80dnvnZwXzF3L/kCvmMC2w4NBEYQOD0oiEdpdzIQaFnqX23O2EHsBT7/Q8f ZzE2N1ynKNVP0mf6+qtmUEcTRvw9oPUtCmyeNoAB/xj8gyx+n5YUhVGrWPx7inVe3AMI 8ukA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=KhtgoDZLQcdddctuxNL94IkH0wF2YFhr3cZ6vXZZOCw=; b=GKWGGegSKjoSvImD+U3P/nV+v2FsRo2XktEUfHyrHRoknzOLndeUq6jzmaXac6eY7L DOmrOkZGi37/VsZEdCc8JNag6SlbDx/MFp1/AuE+6i1syL/xCHyz+ZEet9LfA0T0TJZR JrmHiOOxo5lPzHcfjvzCeVlp0HXk2CuZ2/A3kf0Jqs4gigI687B0FKGrIVU3FvTZl8x3 rxKSQq9RsOI+reHA4oco9APueEOq+GsfnxIOW9+OumO3jtrC5DYPUXdIChyfk4+q8IwK VkF5DX1wLoXawjpD9a5CiQXJ8qB31TsJRPKYn2VQ96BHuNYljJ7wRjB+X+9goKnIZ8P0 EFHg== X-Gm-Message-State: AOAM533DnQ4BNuxMVY3TjoUUkdIb1ki7PONm5pNnIya61ICw0sKVLPS6 93CKhvO64prvYiyu6tUKgMYXPbPi+tU= X-Google-Smtp-Source: ABdhPJwX/ZV+AsLlpM4QaMIYzXa525D4B2c0R9LTzBsC1lNUJbQOZiT0K9gBDhq4mXIadRas3XBH2A== X-Received: by 2002:a5d:618b:: with SMTP id j11mr17738280wru.161.1605906553317; Fri, 20 Nov 2020 13:09:13 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 05/26] target/mips: Rename dsp_helper.c as mod-mips-dsp_helper.c Date: Fri, 20 Nov 2020 22:08:23 +0100 Message-Id: <20201120210844.2625602-6-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) 'MIPS DSP' is defined as a Module by MIPS, rename it as mod-mips-dsp_helper.c. Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/{dsp_helper.c =3D> mod-mips-dsp_helper.c} | 0 target/mips/meson.build | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename target/mips/{dsp_helper.c =3D> mod-mips-dsp_helper.c} (100%) diff --git a/target/mips/dsp_helper.c b/target/mips/mod-mips-dsp_helper.c similarity index 100% rename from target/mips/dsp_helper.c rename to target/mips/mod-mips-dsp_helper.c diff --git a/target/mips/meson.build b/target/mips/meson.build index f2b1b599abc..cc4677d94dc 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -1,12 +1,12 @@ mips_ss =3D ss.source_set() mips_ss.add(files( 'cpu.c', - 'dsp_helper.c', 'fpu_helper.c', 'gdbstub.c', 'helper.c', 'lmmi_helper.c', 'op_helper.c', + 'mod-mips-dsp_helper.c', 'mod-mips-msa_helper.c', =20 'translate.c', --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.65 as permitted sender) client-ip=209.85.221.65; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f65.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.65 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail(p=none dis=none) header.from=amsat.org ARC-Seal: i=1; a=rsa-sha256; t=1605906560; cv=none; d=zohomail.com; s=zohoarc; b=EkLWFPGaZzAthhqV84V+7MFvVnZO5VVQELx+DCTTvD4xiE3NZlQ7t9wkgBDoi+xBJj4KHdmKTXGvD8UlpQA9CLtYkxzymyefHWuL0emkmqdiZ+u4DJoFff1cCUAOPnDJDfywi+nXMwqH6InRB6QGhTPS8EyykgtcXu+/+G3aMTo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906560; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=1IM1vS41dRxHKbpNRTwRziKTYa/fRFjLkjueuUpxpB0=; b=nGH4sxknZViYdmKaNaVVfmKkjzOGQjy4VjeXKRl2nnnVbozlGP4VV65Oq0DRx0Yp7XyR1EcmvfG1e4L9iUSHwzLIzFStXFurVBNSykF5m8YRonQOrdcu76dITjXETtb/a2vZpxjwtBef6Kl//x+uU1JwhYdb8n/aYfteondG26I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.65 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail-wr1-f65.google.com (mail-wr1-f65.google.com [209.85.221.65]) by mx.zohomail.com with SMTPS id 1605906560618201.1240098462672; Fri, 20 Nov 2020 13:09:20 -0800 (PST) Received: by mail-wr1-f65.google.com with SMTP id 23so11667809wrc.8 for ; Fri, 20 Nov 2020 13:09:19 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id q5sm6594656wrf.41.2020.11.20.13.09.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1IM1vS41dRxHKbpNRTwRziKTYa/fRFjLkjueuUpxpB0=; b=Ysl47Dn8GZJSM0SaqXiWDtV/q4axEIsJ4gknlhttu8VM9R2EaT85sXsKAj4Ui59afm 7orSD2o3o9ge5heIQf+2tVgRZ4JI4AXT85sIOyvxiG3DeSw3jcgMj/sr7ngLQWGkqnAj B/pLHnnam/nEnCuFcPnZ9Rd6FjRmd9XAykQ164hrZlGAvxf7fbfCYyxlMZax5oSMPHZJ EnrEkkJOJpdhtIYzIcxk4idCvN0zWY7/04wGxVGoEWrLCrCWFmAP5HPmtAZa9CqwP25i ZoXcFdyEHqKNZjkAYC7b8dcVHLy6eOHmsOpDUalfTXffLmwjMu8Np/Ms99ZeNCV2acP1 zopA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=1IM1vS41dRxHKbpNRTwRziKTYa/fRFjLkjueuUpxpB0=; b=t/35XnmgcSk65J/ePiv+swu7oUuLLnPng3WFPhB/hW9yfi7fJ2JrYTIdLIpSUhQpNB sX0Y9NNqW9uP7d6//26o4Zf3gJK/ForxH3e8PmK7cISxtec10v51QR2g42XEISa3GafG QsqZwM96TWhgoQF1+4I7xJeBJ1mtBoOgHOsSnySpDU28qf3CLmJzhEH3KXqgEsib+wiu lMbLO+lgWWnyUKo432YUctW7jQhHD4N5Ymvrga4GS9VRVbqtGEIfSW86cDJFOAUIlwoS aVQCVQd+6kbbEcIND2BOhFTAPCtyIAsAWPCJz+9NPW99SRMAC1hhezP96GAMD/RZwnpK kGdQ== X-Gm-Message-State: AOAM532L78n2NFnxYMesJgh+3nXLgtFCAn7RCgJ7yy+NKtzkHr55QLMN f3+AKmg3qQe4itMnNbzRg5k= X-Google-Smtp-Source: ABdhPJzLF/SZ+SKwyN/yvJu3JoHpJhkGdq9M+N6M287mhfwpg33/iFN82FhfBZ3g17h8fo8zDJooeQ== X-Received: by 2002:adf:f2c7:: with SMTP id d7mr18480465wrp.142.1605906558459; Fri, 20 Nov 2020 13:09:18 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 06/26] target/mips: Extract DSP helper definitions Date: Fri, 20 Nov 2020 22:08:24 +0100 Message-Id: <20201120210844.2625602-7-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) 'MIPS DSP' is defined as a Module by MIPS. Extract the helper definitions to 'mod-mips-dsp_helper.h.inc'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/helper.h | 335 +------------------------ target/mips/mod-mips-dsp_helper.h.inc | 344 ++++++++++++++++++++++++++ 2 files changed, 345 insertions(+), 334 deletions(-) create mode 100644 target/mips/mod-mips-dsp_helper.h.inc diff --git a/target/mips/helper.h b/target/mips/helper.h index a44f42c6201..bce869f3718 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -447,341 +447,8 @@ DEF_HELPER_FLAGS_2(pasubub, TCG_CALL_NO_RWG_SE, i64, = i64, i64) DEF_HELPER_FLAGS_1(biadd, TCG_CALL_NO_RWG_SE, i64, i64) DEF_HELPER_FLAGS_1(pmovmskb, TCG_CALL_NO_RWG_SE, i64, i64) =20 -/*** MIPS DSP ***/ -/* DSP Arithmetic Sub-class insns */ -DEF_HELPER_FLAGS_3(addq_ph, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(addq_s_ph, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(addq_qh, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(addq_s_qh, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(addq_s_w, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(addq_pw, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(addq_s_pw, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(addu_qb, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(addu_s_qb, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_2(adduh_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(adduh_r_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_3(addu_ph, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(addu_s_ph, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_2(addqh_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(addqh_r_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(addqh_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(addqh_r_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(addu_ob, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(addu_s_ob, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_2(adduh_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(adduh_r_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_3(addu_qh, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(addu_s_qh, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(subq_ph, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(subq_s_ph, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(subq_qh, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(subq_s_qh, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(subq_s_w, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(subq_pw, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(subq_s_pw, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(subu_qb, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(subu_s_qb, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_2(subuh_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(subuh_r_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_3(subu_ph, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(subu_s_ph, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_2(subqh_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(subqh_r_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(subqh_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(subqh_r_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(subu_ob, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(subu_s_ob, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_2(subuh_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(subuh_r_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_3(subu_qh, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(subu_s_qh, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(addsc, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(addwc, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_2(modsub, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_1(raddu_w_qb, TCG_CALL_NO_RWG_SE, tl, tl) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_1(raddu_l_ob, TCG_CALL_NO_RWG_SE, tl, tl) -#endif -DEF_HELPER_FLAGS_2(absq_s_qb, 0, tl, tl, env) -DEF_HELPER_FLAGS_2(absq_s_ph, 0, tl, tl, env) -DEF_HELPER_FLAGS_2(absq_s_w, 0, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_2(absq_s_ob, 0, tl, tl, env) -DEF_HELPER_FLAGS_2(absq_s_qh, 0, tl, tl, env) -DEF_HELPER_FLAGS_2(absq_s_pw, 0, tl, tl, env) -#endif -DEF_HELPER_FLAGS_2(precr_qb_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(precrq_qb_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_3(precr_sra_ph_w, TCG_CALL_NO_RWG_SE, - tl, i32, tl, tl) -DEF_HELPER_FLAGS_3(precr_sra_r_ph_w, TCG_CALL_NO_RWG_SE, - tl, i32, tl, tl) -DEF_HELPER_FLAGS_2(precrq_ph_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_3(precrq_rs_ph_w, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_2(precr_ob_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_3(precr_sra_qh_pw, - TCG_CALL_NO_RWG_SE, tl, tl, tl, i32) -DEF_HELPER_FLAGS_3(precr_sra_r_qh_pw, - TCG_CALL_NO_RWG_SE, tl, tl, tl, i32) -DEF_HELPER_FLAGS_2(precrq_ob_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(precrq_qh_pw, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_3(precrq_rs_qh_pw, - TCG_CALL_NO_RWG_SE, tl, tl, tl, env) -DEF_HELPER_FLAGS_2(precrq_pw_l, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#endif -DEF_HELPER_FLAGS_3(precrqu_s_qb_ph, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(precrqu_s_ob_qh, - TCG_CALL_NO_RWG_SE, tl, tl, tl, env) - -DEF_HELPER_FLAGS_1(preceq_pw_qhl, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(preceq_pw_qhr, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(preceq_pw_qhla, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(preceq_pw_qhra, TCG_CALL_NO_RWG_SE, tl, tl) -#endif -DEF_HELPER_FLAGS_1(precequ_ph_qbl, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(precequ_ph_qbr, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(precequ_ph_qbla, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(precequ_ph_qbra, TCG_CALL_NO_RWG_SE, tl, tl) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_1(precequ_qh_obl, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(precequ_qh_obr, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(precequ_qh_obla, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(precequ_qh_obra, TCG_CALL_NO_RWG_SE, tl, tl) -#endif -DEF_HELPER_FLAGS_1(preceu_ph_qbl, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(preceu_ph_qbr, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(preceu_ph_qbla, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(preceu_ph_qbra, TCG_CALL_NO_RWG_SE, tl, tl) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_1(preceu_qh_obl, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(preceu_qh_obr, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(preceu_qh_obla, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_1(preceu_qh_obra, TCG_CALL_NO_RWG_SE, tl, tl) -#endif - -/* DSP GPR-Based Shift Sub-class insns */ -DEF_HELPER_FLAGS_3(shll_qb, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(shll_ob, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(shll_ph, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(shll_s_ph, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(shll_qh, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(shll_s_qh, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(shll_s_w, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(shll_pw, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(shll_s_pw, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_2(shrl_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(shrl_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_2(shrl_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(shrl_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#endif -DEF_HELPER_FLAGS_2(shra_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(shra_r_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_2(shra_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(shra_r_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#endif -DEF_HELPER_FLAGS_2(shra_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(shra_r_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(shra_r_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_2(shra_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(shra_r_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(shra_pw, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(shra_r_pw, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#endif - -/* DSP Multiply Sub-class insns */ -DEF_HELPER_FLAGS_3(muleu_s_ph_qbl, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(muleu_s_ph_qbr, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(muleu_s_qh_obl, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(muleu_s_qh_obr, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(mulq_rs_ph, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(mulq_rs_qh, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(muleq_s_w_phl, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(muleq_s_w_phr, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(muleq_s_pw_qhl, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(muleq_s_pw_qhr, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_4(dpau_h_qbl, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(dpau_h_qbr, 0, void, i32, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_4(dpau_h_obl, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(dpau_h_obr, 0, void, tl, tl, i32, env) -#endif -DEF_HELPER_FLAGS_4(dpsu_h_qbl, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(dpsu_h_qbr, 0, void, i32, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_4(dpsu_h_obl, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(dpsu_h_obr, 0, void, tl, tl, i32, env) -#endif -DEF_HELPER_FLAGS_4(dpa_w_ph, 0, void, i32, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_4(dpa_w_qh, 0, void, tl, tl, i32, env) -#endif -DEF_HELPER_FLAGS_4(dpax_w_ph, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(dpaq_s_w_ph, 0, void, i32, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_4(dpaq_s_w_qh, 0, void, tl, tl, i32, env) -#endif -DEF_HELPER_FLAGS_4(dpaqx_s_w_ph, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(dpaqx_sa_w_ph, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(dps_w_ph, 0, void, i32, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_4(dps_w_qh, 0, void, tl, tl, i32, env) -#endif -DEF_HELPER_FLAGS_4(dpsx_w_ph, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(dpsq_s_w_ph, 0, void, i32, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_4(dpsq_s_w_qh, 0, void, tl, tl, i32, env) -#endif -DEF_HELPER_FLAGS_4(dpsqx_s_w_ph, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(dpsqx_sa_w_ph, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(mulsaq_s_w_ph, 0, void, i32, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_4(mulsaq_s_w_qh, 0, void, tl, tl, i32, env) -#endif -DEF_HELPER_FLAGS_4(dpaq_sa_l_w, 0, void, i32, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_4(dpaq_sa_l_pw, 0, void, tl, tl, i32, env) -#endif -DEF_HELPER_FLAGS_4(dpsq_sa_l_w, 0, void, i32, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_4(dpsq_sa_l_pw, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(mulsaq_s_l_pw, 0, void, tl, tl, i32, env) -#endif -DEF_HELPER_FLAGS_4(maq_s_w_phl, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(maq_s_w_phr, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(maq_sa_w_phl, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_4(maq_sa_w_phr, 0, void, i32, tl, tl, env) -DEF_HELPER_FLAGS_3(mul_ph, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(mul_s_ph, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(mulq_s_ph, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(mulq_s_w, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(mulq_rs_w, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_4(mulsa_w_ph, 0, void, i32, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_4(maq_s_w_qhll, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(maq_s_w_qhlr, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(maq_s_w_qhrl, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(maq_s_w_qhrr, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(maq_sa_w_qhll, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(maq_sa_w_qhlr, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(maq_sa_w_qhrl, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(maq_sa_w_qhrr, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(maq_s_l_pwl, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(maq_s_l_pwr, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(dmadd, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(dmaddu, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(dmsub, 0, void, tl, tl, i32, env) -DEF_HELPER_FLAGS_4(dmsubu, 0, void, tl, tl, i32, env) -#endif - -/* DSP Bit/Manipulation Sub-class insns */ -DEF_HELPER_FLAGS_1(bitrev, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_FLAGS_3(insv, 0, tl, env, tl, tl) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(dinsv, 0, tl, env, tl, tl) -#endif - -/* DSP Compare-Pick Sub-class insns */ -DEF_HELPER_FLAGS_3(cmpu_eq_qb, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmpu_lt_qb, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmpu_le_qb, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_2(cmpgu_eq_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(cmpgu_lt_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(cmpgu_le_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_3(cmp_eq_ph, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmp_lt_ph, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmp_le_ph, 0, void, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(cmpu_eq_ob, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmpu_lt_ob, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmpu_le_ob, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmpgdu_eq_ob, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(cmpgdu_lt_ob, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(cmpgdu_le_ob, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_2(cmpgu_eq_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(cmpgu_lt_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_2(cmpgu_le_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) -DEF_HELPER_FLAGS_3(cmp_eq_qh, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmp_lt_qh, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmp_le_qh, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmp_eq_pw, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmp_lt_pw, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_3(cmp_le_pw, 0, void, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(pick_qb, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(pick_ph, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(pick_ob, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(pick_qh, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(pick_pw, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_2(packrl_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_2(packrl_pw, TCG_CALL_NO_RWG_SE, tl, tl, tl) -#endif - -/* DSP Accumulator and DSPControl Access Sub-class insns */ -DEF_HELPER_FLAGS_3(extr_w, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(extr_r_w, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(extr_rs_w, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(dextr_w, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(dextr_r_w, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(dextr_rs_w, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(dextr_l, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(dextr_r_l, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(dextr_rs_l, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(extr_s_h, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(dextr_s_h, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(extp, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(extpdp, 0, tl, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(dextp, 0, tl, tl, tl, env) -DEF_HELPER_FLAGS_3(dextpdp, 0, tl, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(shilo, 0, void, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(dshilo, 0, void, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(mthlip, 0, void, tl, tl, env) -#if defined(TARGET_MIPS64) -DEF_HELPER_FLAGS_3(dmthlip, 0, void, tl, tl, env) -#endif -DEF_HELPER_FLAGS_3(wrdsp, 0, void, tl, tl, env) -DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env) - DEF_HELPER_3(cache, void, env, tl, i32) =20 +#include "mod-mips-dsp_helper.h.inc" #include "mod-mips-msa_helper.h.inc" =20 diff --git a/target/mips/mod-mips-dsp_helper.h.inc b/target/mips/mod-mips-d= sp_helper.h.inc new file mode 100644 index 00000000000..83f188a697e --- /dev/null +++ b/target/mips/mod-mips-dsp_helper.h.inc @@ -0,0 +1,344 @@ +/* + * MIPS ASE DSP instruction emulation helpers for QEMU. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +/* DSP Arithmetic Sub-class insns */ +DEF_HELPER_FLAGS_3(addq_ph, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(addq_s_ph, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(addq_qh, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(addq_s_qh, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(addq_s_w, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(addq_pw, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(addq_s_pw, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(addu_qb, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(addu_s_qb, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_2(adduh_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(adduh_r_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(addu_ph, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(addu_s_ph, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_2(addqh_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(addqh_r_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(addqh_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(addqh_r_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(addu_ob, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(addu_s_ob, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_2(adduh_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(adduh_r_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(addu_qh, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(addu_s_qh, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(subq_ph, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(subq_s_ph, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(subq_qh, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(subq_s_qh, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(subq_s_w, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(subq_pw, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(subq_s_pw, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(subu_qb, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(subu_s_qb, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_2(subuh_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(subuh_r_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(subu_ph, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(subu_s_ph, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_2(subqh_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(subqh_r_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(subqh_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(subqh_r_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(subu_ob, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(subu_s_ob, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_2(subuh_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(subuh_r_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(subu_qh, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(subu_s_qh, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(addsc, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(addwc, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_2(modsub, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_1(raddu_w_qb, TCG_CALL_NO_RWG_SE, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_1(raddu_l_ob, TCG_CALL_NO_RWG_SE, tl, tl) +#endif +DEF_HELPER_FLAGS_2(absq_s_qb, 0, tl, tl, env) +DEF_HELPER_FLAGS_2(absq_s_ph, 0, tl, tl, env) +DEF_HELPER_FLAGS_2(absq_s_w, 0, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_2(absq_s_ob, 0, tl, tl, env) +DEF_HELPER_FLAGS_2(absq_s_qh, 0, tl, tl, env) +DEF_HELPER_FLAGS_2(absq_s_pw, 0, tl, tl, env) +#endif +DEF_HELPER_FLAGS_2(precr_qb_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(precrq_qb_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(precr_sra_ph_w, TCG_CALL_NO_RWG_SE, + tl, i32, tl, tl) +DEF_HELPER_FLAGS_3(precr_sra_r_ph_w, TCG_CALL_NO_RWG_SE, + tl, i32, tl, tl) +DEF_HELPER_FLAGS_2(precrq_ph_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(precrq_rs_ph_w, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_2(precr_ob_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(precr_sra_qh_pw, + TCG_CALL_NO_RWG_SE, tl, tl, tl, i32) +DEF_HELPER_FLAGS_3(precr_sra_r_qh_pw, + TCG_CALL_NO_RWG_SE, tl, tl, tl, i32) +DEF_HELPER_FLAGS_2(precrq_ob_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(precrq_qh_pw, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(precrq_rs_qh_pw, + TCG_CALL_NO_RWG_SE, tl, tl, tl, env) +DEF_HELPER_FLAGS_2(precrq_pw_l, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#endif +DEF_HELPER_FLAGS_3(precrqu_s_qb_ph, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(precrqu_s_ob_qh, + TCG_CALL_NO_RWG_SE, tl, tl, tl, env) + +DEF_HELPER_FLAGS_1(preceq_pw_qhl, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(preceq_pw_qhr, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(preceq_pw_qhla, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(preceq_pw_qhra, TCG_CALL_NO_RWG_SE, tl, tl) +#endif +DEF_HELPER_FLAGS_1(precequ_ph_qbl, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(precequ_ph_qbr, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(precequ_ph_qbla, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(precequ_ph_qbra, TCG_CALL_NO_RWG_SE, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_1(precequ_qh_obl, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(precequ_qh_obr, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(precequ_qh_obla, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(precequ_qh_obra, TCG_CALL_NO_RWG_SE, tl, tl) +#endif +DEF_HELPER_FLAGS_1(preceu_ph_qbl, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(preceu_ph_qbr, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(preceu_ph_qbla, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(preceu_ph_qbra, TCG_CALL_NO_RWG_SE, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_1(preceu_qh_obl, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(preceu_qh_obr, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(preceu_qh_obla, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(preceu_qh_obra, TCG_CALL_NO_RWG_SE, tl, tl) +#endif + +/* DSP GPR-Based Shift Sub-class insns */ +DEF_HELPER_FLAGS_3(shll_qb, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(shll_ob, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(shll_ph, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(shll_s_ph, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(shll_qh, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(shll_s_qh, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(shll_s_w, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(shll_pw, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(shll_s_pw, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_2(shrl_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(shrl_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_2(shrl_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(shrl_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#endif +DEF_HELPER_FLAGS_2(shra_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(shra_r_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_2(shra_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(shra_r_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#endif +DEF_HELPER_FLAGS_2(shra_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(shra_r_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(shra_r_w, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_2(shra_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(shra_r_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(shra_pw, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(shra_r_pw, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#endif + +/* DSP Multiply Sub-class insns */ +DEF_HELPER_FLAGS_3(muleu_s_ph_qbl, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(muleu_s_ph_qbr, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(muleu_s_qh_obl, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(muleu_s_qh_obr, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(mulq_rs_ph, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(mulq_rs_qh, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(muleq_s_w_phl, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(muleq_s_w_phr, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(muleq_s_pw_qhl, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(muleq_s_pw_qhr, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_4(dpau_h_qbl, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(dpau_h_qbr, 0, void, i32, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_4(dpau_h_obl, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(dpau_h_obr, 0, void, tl, tl, i32, env) +#endif +DEF_HELPER_FLAGS_4(dpsu_h_qbl, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(dpsu_h_qbr, 0, void, i32, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_4(dpsu_h_obl, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(dpsu_h_obr, 0, void, tl, tl, i32, env) +#endif +DEF_HELPER_FLAGS_4(dpa_w_ph, 0, void, i32, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_4(dpa_w_qh, 0, void, tl, tl, i32, env) +#endif +DEF_HELPER_FLAGS_4(dpax_w_ph, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(dpaq_s_w_ph, 0, void, i32, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_4(dpaq_s_w_qh, 0, void, tl, tl, i32, env) +#endif +DEF_HELPER_FLAGS_4(dpaqx_s_w_ph, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(dpaqx_sa_w_ph, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(dps_w_ph, 0, void, i32, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_4(dps_w_qh, 0, void, tl, tl, i32, env) +#endif +DEF_HELPER_FLAGS_4(dpsx_w_ph, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(dpsq_s_w_ph, 0, void, i32, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_4(dpsq_s_w_qh, 0, void, tl, tl, i32, env) +#endif +DEF_HELPER_FLAGS_4(dpsqx_s_w_ph, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(dpsqx_sa_w_ph, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(mulsaq_s_w_ph, 0, void, i32, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_4(mulsaq_s_w_qh, 0, void, tl, tl, i32, env) +#endif +DEF_HELPER_FLAGS_4(dpaq_sa_l_w, 0, void, i32, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_4(dpaq_sa_l_pw, 0, void, tl, tl, i32, env) +#endif +DEF_HELPER_FLAGS_4(dpsq_sa_l_w, 0, void, i32, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_4(dpsq_sa_l_pw, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(mulsaq_s_l_pw, 0, void, tl, tl, i32, env) +#endif +DEF_HELPER_FLAGS_4(maq_s_w_phl, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(maq_s_w_phr, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(maq_sa_w_phl, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_4(maq_sa_w_phr, 0, void, i32, tl, tl, env) +DEF_HELPER_FLAGS_3(mul_ph, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(mul_s_ph, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(mulq_s_ph, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(mulq_s_w, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(mulq_rs_w, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_4(mulsa_w_ph, 0, void, i32, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_4(maq_s_w_qhll, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(maq_s_w_qhlr, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(maq_s_w_qhrl, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(maq_s_w_qhrr, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(maq_sa_w_qhll, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(maq_sa_w_qhlr, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(maq_sa_w_qhrl, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(maq_sa_w_qhrr, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(maq_s_l_pwl, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(maq_s_l_pwr, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(dmadd, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(dmaddu, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(dmsub, 0, void, tl, tl, i32, env) +DEF_HELPER_FLAGS_4(dmsubu, 0, void, tl, tl, i32, env) +#endif + +/* DSP Bit/Manipulation Sub-class insns */ +DEF_HELPER_FLAGS_1(bitrev, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_3(insv, 0, tl, env, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(dinsv, 0, tl, env, tl, tl) +#endif + +/* DSP Compare-Pick Sub-class insns */ +DEF_HELPER_FLAGS_3(cmpu_eq_qb, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmpu_lt_qb, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmpu_le_qb, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_2(cmpgu_eq_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(cmpgu_lt_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(cmpgu_le_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(cmp_eq_ph, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmp_lt_ph, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmp_le_ph, 0, void, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(cmpu_eq_ob, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmpu_lt_ob, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmpu_le_ob, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmpgdu_eq_ob, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(cmpgdu_lt_ob, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(cmpgdu_le_ob, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_2(cmpgu_eq_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(cmpgu_lt_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(cmpgu_le_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(cmp_eq_qh, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmp_lt_qh, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmp_le_qh, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmp_eq_pw, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmp_lt_pw, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_3(cmp_le_pw, 0, void, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(pick_qb, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(pick_ph, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(pick_ob, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(pick_qh, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(pick_pw, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_2(packrl_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_2(packrl_pw, TCG_CALL_NO_RWG_SE, tl, tl, tl) +#endif + +/* DSP Accumulator and DSPControl Access Sub-class insns */ +DEF_HELPER_FLAGS_3(extr_w, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(extr_r_w, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(extr_rs_w, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(dextr_w, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(dextr_r_w, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(dextr_rs_w, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(dextr_l, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(dextr_r_l, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(dextr_rs_l, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(extr_s_h, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(dextr_s_h, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(extp, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(extpdp, 0, tl, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(dextp, 0, tl, tl, tl, env) +DEF_HELPER_FLAGS_3(dextpdp, 0, tl, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(shilo, 0, void, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(dshilo, 0, void, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(mthlip, 0, void, tl, tl, env) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(dmthlip, 0, void, tl, tl, env) +#endif +DEF_HELPER_FLAGS_3(wrdsp, 0, void, tl, tl, env) +DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env) --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.49 as permitted sender) client-ip=209.85.128.49; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f49.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.49 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906567; cv=none; d=zohomail.com; s=zohoarc; b=bPMSJ6ft5Th9GGXBNYbh63sgeELJz6U5fFRn6AA0vpgys8EenjpDCAbwxQ3ECi/F6kDEcEgPw0yKXGiGLpx63eWKV/8qSfJd2SaZG0qmtoAVMBrBs9GClld+GiB69bfK+fT0LTDnLCZ/a3W12s14OPPJsLo2zdSavYrvG9aaPDI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906567; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=6SIkxWaaQp35qzc6ZClnfjG412MKQqGjOGfS9dBV5so=; b=dYe37WqeA3N1gqZIYlkbLNIR8l3vPtRwD+ljatb6Qv6e+blwGqTXFA0xVZ+pna9h3Sta61eypMR2/kzDF85weNUnrEWn4TSVo/oM9cBOIjpq8al/P0HdHmWtqiZOI2MqPuUAcm18yoHA1RtxHOus/DhKCXZswMSEBL+nRmBNpaI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.49 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) by mx.zohomail.com with SMTPS id 1605906567066526.9475313297776; Fri, 20 Nov 2020 13:09:27 -0800 (PST) Received: by mail-wm1-f49.google.com with SMTP id s13so11238944wmh.4 for ; Fri, 20 Nov 2020 13:09:25 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id q7sm7077888wrg.95.2020.11.20.13.09.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6SIkxWaaQp35qzc6ZClnfjG412MKQqGjOGfS9dBV5so=; b=LAZxxrgCi6iStiyw8dAqg9A9qZjo/xza7LuG8ZONzLlPESzfOKkx2yVmSri6BaAOMm pFb6+/LDzdIhcHIKwPxpiZNQioNofCTqbm0f+UCDkkkVanqAE10fWY+CW/9IIpu5jRFB GaaIZFKTBhQizC3gc8qCtGRZ8ABNgZntk2krrPjSw8you6sSbtjQgeKAFW+ly/pYh+Qv 8TG4vbEHMk2Wqj1tMzIhBb3NJ2Oyx+FkUUc2Ej0wFD4RraSYQRoOCaJ/pPpnyXKgSwYt yvLqc0qg0djI8FZjC7Tul60qT47k/8QoTgtbFuwkU3N6vHd5rWF449zbPvqqNf+Hu1eD PRmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=6SIkxWaaQp35qzc6ZClnfjG412MKQqGjOGfS9dBV5so=; b=dTDq0HIEw+jgmtkviFjBHOkjMvw2KJeCRnc8qsuCtyqeVvTGX50mMSyGK+kZjl5HEe VhIe6jcKPoSuvzqMhFqPPp2x9HqlYIj5yYcBXg67nB8TfvCiasvenjRuPPbFBaofo21a BixdoORtjjVncm0dz1I45nBZidgg/389Eo2ZpNOyOo4GpF/JfFQPJUEI/yq8htMFXGk6 mZBUMM3yTKWHMZ9B/935/u3RfFPTy4B0AAsHEZDj0Iub6J/9PHiX4u9ju3MtbQToT8J4 Qson7oWBaPgKLaQZ/o4C6zhddJ2TVhx6PpIEWt9h4MJIQWPdtFkHr33N3+sNTmY/ibGw oqYw== X-Gm-Message-State: AOAM532npoduu+AUnpJWYnl9QFySA2pP/d9VDkSWHmrnDHX/HtYuysmj 0eVIzEJOU/tAB/ZToz+Xbkc= X-Google-Smtp-Source: ABdhPJztVmippT4NJCCkyTe6ANoX+tMO3SrGdl0i3FfCsA0/lLLbl1/JSGUo3vEEGf+Cw0ExVR06sg== X-Received: by 2002:a1c:44f:: with SMTP id 76mr12190675wme.181.1605906564108; Fri, 20 Nov 2020 13:09:24 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 07/26] target/mips: Extract DSP translation routines Date: Fri, 20 Nov 2020 22:08:25 +0100 Message-Id: <20201120210844.2625602-8-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract 2150 lines from the huge translate.c to a new file, 'mod-mips-dsp_translate.c.inc'. As there are too many inter- dependencies we don't compile it as another object, but keep including it in the big translate.o. We gain in code maintainability. Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/mod-mips-dsp_helper.c | 2 + target/mips/translate.c | 2150 +-------------------- target/mips/mod-mips-dsp_translate.c.inc | 2158 ++++++++++++++++++++++ 3 files changed, 2164 insertions(+), 2146 deletions(-) create mode 100644 target/mips/mod-mips-dsp_translate.c.inc diff --git a/target/mips/mod-mips-dsp_helper.c b/target/mips/mod-mips-dsp_h= elper.c index 09b6e5fb15a..10a965bd20d 100644 --- a/target/mips/mod-mips-dsp_helper.c +++ b/target/mips/mod-mips-dsp_helper.c @@ -15,6 +15,8 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later */ =20 #include "qemu/osdep.h" diff --git a/target/mips/translate.c b/target/mips/translate.c index 0ad59731810..bc581a7a7a7 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -405,35 +405,6 @@ enum { OPC_DMOD_G_2E =3D 0x26 | OPC_SPECIAL3, OPC_DMODU_G_2E =3D 0x27 | OPC_SPECIAL3, =20 - /* MIPS DSP Load */ - OPC_LX_DSP =3D 0x0A | OPC_SPECIAL3, - /* MIPS DSP Arithmetic */ - OPC_ADDU_QB_DSP =3D 0x10 | OPC_SPECIAL3, - OPC_ADDU_OB_DSP =3D 0x14 | OPC_SPECIAL3, - OPC_ABSQ_S_PH_DSP =3D 0x12 | OPC_SPECIAL3, - OPC_ABSQ_S_QH_DSP =3D 0x16 | OPC_SPECIAL3, - /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */ - /* OPC_ADDUH_QB_DSP =3D 0x18 | OPC_SPECIAL3, */ - OPC_CMPU_EQ_QB_DSP =3D 0x11 | OPC_SPECIAL3, - OPC_CMPU_EQ_OB_DSP =3D 0x15 | OPC_SPECIAL3, - /* MIPS DSP GPR-Based Shift Sub-class */ - OPC_SHLL_QB_DSP =3D 0x13 | OPC_SPECIAL3, - OPC_SHLL_OB_DSP =3D 0x17 | OPC_SPECIAL3, - /* MIPS DSP Multiply Sub-class insns */ - /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */ - /* OPC_MUL_PH_DSP =3D 0x18 | OPC_SPECIAL3, */ - OPC_DPA_W_PH_DSP =3D 0x30 | OPC_SPECIAL3, - OPC_DPAQ_W_QH_DSP =3D 0x34 | OPC_SPECIAL3, - /* DSP Bit/Manipulation Sub-class */ - OPC_INSV_DSP =3D 0x0C | OPC_SPECIAL3, - OPC_DINSV_DSP =3D 0x0D | OPC_SPECIAL3, - /* MIPS DSP Append Sub-class */ - OPC_APPEND_DSP =3D 0x31 | OPC_SPECIAL3, - OPC_DAPPEND_DSP =3D 0x35 | OPC_SPECIAL3, - /* MIPS DSP Accumulator and DSPControl Access Sub-class */ - OPC_EXTR_W_DSP =3D 0x38 | OPC_SPECIAL3, - OPC_DEXTR_W_DSP =3D 0x3C | OPC_SPECIAL3, - /* EVA */ OPC_LWLE =3D 0x19 | OPC_SPECIAL3, OPC_LWRE =3D 0x1A | OPC_SPECIAL3, @@ -540,407 +511,6 @@ enum { OPC_BPOSGE64 =3D (0x1D << 16) | OPC_REGIMM, }; =20 -#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -/* MIPS DSP Load */ -enum { - OPC_LBUX =3D (0x06 << 6) | OPC_LX_DSP, - OPC_LHX =3D (0x04 << 6) | OPC_LX_DSP, - OPC_LWX =3D (0x00 << 6) | OPC_LX_DSP, - OPC_LDX =3D (0x08 << 6) | OPC_LX_DSP, -}; - -#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Arithmetic Sub-class */ - OPC_ADDQ_PH =3D (0x0A << 6) | OPC_ADDU_QB_DSP, - OPC_ADDQ_S_PH =3D (0x0E << 6) | OPC_ADDU_QB_DSP, - OPC_ADDQ_S_W =3D (0x16 << 6) | OPC_ADDU_QB_DSP, - OPC_ADDU_QB =3D (0x00 << 6) | OPC_ADDU_QB_DSP, - OPC_ADDU_S_QB =3D (0x04 << 6) | OPC_ADDU_QB_DSP, - OPC_ADDU_PH =3D (0x08 << 6) | OPC_ADDU_QB_DSP, - OPC_ADDU_S_PH =3D (0x0C << 6) | OPC_ADDU_QB_DSP, - OPC_SUBQ_PH =3D (0x0B << 6) | OPC_ADDU_QB_DSP, - OPC_SUBQ_S_PH =3D (0x0F << 6) | OPC_ADDU_QB_DSP, - OPC_SUBQ_S_W =3D (0x17 << 6) | OPC_ADDU_QB_DSP, - OPC_SUBU_QB =3D (0x01 << 6) | OPC_ADDU_QB_DSP, - OPC_SUBU_S_QB =3D (0x05 << 6) | OPC_ADDU_QB_DSP, - OPC_SUBU_PH =3D (0x09 << 6) | OPC_ADDU_QB_DSP, - OPC_SUBU_S_PH =3D (0x0D << 6) | OPC_ADDU_QB_DSP, - OPC_ADDSC =3D (0x10 << 6) | OPC_ADDU_QB_DSP, - OPC_ADDWC =3D (0x11 << 6) | OPC_ADDU_QB_DSP, - OPC_MODSUB =3D (0x12 << 6) | OPC_ADDU_QB_DSP, - OPC_RADDU_W_QB =3D (0x14 << 6) | OPC_ADDU_QB_DSP, - /* MIPS DSP Multiply Sub-class insns */ - OPC_MULEU_S_PH_QBL =3D (0x06 << 6) | OPC_ADDU_QB_DSP, - OPC_MULEU_S_PH_QBR =3D (0x07 << 6) | OPC_ADDU_QB_DSP, - OPC_MULQ_RS_PH =3D (0x1F << 6) | OPC_ADDU_QB_DSP, - OPC_MULEQ_S_W_PHL =3D (0x1C << 6) | OPC_ADDU_QB_DSP, - OPC_MULEQ_S_W_PHR =3D (0x1D << 6) | OPC_ADDU_QB_DSP, - OPC_MULQ_S_PH =3D (0x1E << 6) | OPC_ADDU_QB_DSP, -}; - -#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E -#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Arithmetic Sub-class */ - OPC_ADDUH_QB =3D (0x00 << 6) | OPC_ADDUH_QB_DSP, - OPC_ADDUH_R_QB =3D (0x02 << 6) | OPC_ADDUH_QB_DSP, - OPC_ADDQH_PH =3D (0x08 << 6) | OPC_ADDUH_QB_DSP, - OPC_ADDQH_R_PH =3D (0x0A << 6) | OPC_ADDUH_QB_DSP, - OPC_ADDQH_W =3D (0x10 << 6) | OPC_ADDUH_QB_DSP, - OPC_ADDQH_R_W =3D (0x12 << 6) | OPC_ADDUH_QB_DSP, - OPC_SUBUH_QB =3D (0x01 << 6) | OPC_ADDUH_QB_DSP, - OPC_SUBUH_R_QB =3D (0x03 << 6) | OPC_ADDUH_QB_DSP, - OPC_SUBQH_PH =3D (0x09 << 6) | OPC_ADDUH_QB_DSP, - OPC_SUBQH_R_PH =3D (0x0B << 6) | OPC_ADDUH_QB_DSP, - OPC_SUBQH_W =3D (0x11 << 6) | OPC_ADDUH_QB_DSP, - OPC_SUBQH_R_W =3D (0x13 << 6) | OPC_ADDUH_QB_DSP, - /* MIPS DSP Multiply Sub-class insns */ - OPC_MUL_PH =3D (0x0C << 6) | OPC_ADDUH_QB_DSP, - OPC_MUL_S_PH =3D (0x0E << 6) | OPC_ADDUH_QB_DSP, - OPC_MULQ_S_W =3D (0x16 << 6) | OPC_ADDUH_QB_DSP, - OPC_MULQ_RS_W =3D (0x17 << 6) | OPC_ADDUH_QB_DSP, -}; - -#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Arithmetic Sub-class */ - OPC_ABSQ_S_QB =3D (0x01 << 6) | OPC_ABSQ_S_PH_DSP, - OPC_ABSQ_S_PH =3D (0x09 << 6) | OPC_ABSQ_S_PH_DSP, - OPC_ABSQ_S_W =3D (0x11 << 6) | OPC_ABSQ_S_PH_DSP, - OPC_PRECEQ_W_PHL =3D (0x0C << 6) | OPC_ABSQ_S_PH_DSP, - OPC_PRECEQ_W_PHR =3D (0x0D << 6) | OPC_ABSQ_S_PH_DSP, - OPC_PRECEQU_PH_QBL =3D (0x04 << 6) | OPC_ABSQ_S_PH_DSP, - OPC_PRECEQU_PH_QBR =3D (0x05 << 6) | OPC_ABSQ_S_PH_DSP, - OPC_PRECEQU_PH_QBLA =3D (0x06 << 6) | OPC_ABSQ_S_PH_DSP, - OPC_PRECEQU_PH_QBRA =3D (0x07 << 6) | OPC_ABSQ_S_PH_DSP, - OPC_PRECEU_PH_QBL =3D (0x1C << 6) | OPC_ABSQ_S_PH_DSP, - OPC_PRECEU_PH_QBR =3D (0x1D << 6) | OPC_ABSQ_S_PH_DSP, - OPC_PRECEU_PH_QBLA =3D (0x1E << 6) | OPC_ABSQ_S_PH_DSP, - OPC_PRECEU_PH_QBRA =3D (0x1F << 6) | OPC_ABSQ_S_PH_DSP, - /* DSP Bit/Manipulation Sub-class */ - OPC_BITREV =3D (0x1B << 6) | OPC_ABSQ_S_PH_DSP, - OPC_REPL_QB =3D (0x02 << 6) | OPC_ABSQ_S_PH_DSP, - OPC_REPLV_QB =3D (0x03 << 6) | OPC_ABSQ_S_PH_DSP, - OPC_REPL_PH =3D (0x0A << 6) | OPC_ABSQ_S_PH_DSP, - OPC_REPLV_PH =3D (0x0B << 6) | OPC_ABSQ_S_PH_DSP, -}; - -#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Arithmetic Sub-class */ - OPC_PRECR_QB_PH =3D (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_PRECRQ_QB_PH =3D (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_PRECR_SRA_PH_W =3D (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_PRECR_SRA_R_PH_W =3D (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_PRECRQ_PH_W =3D (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_PRECRQ_RS_PH_W =3D (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_PRECRQU_S_QB_PH =3D (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, - /* DSP Compare-Pick Sub-class */ - OPC_CMPU_EQ_QB =3D (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMPU_LT_QB =3D (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMPU_LE_QB =3D (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMPGU_EQ_QB =3D (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMPGU_LT_QB =3D (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMPGU_LE_QB =3D (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMPGDU_EQ_QB =3D (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMPGDU_LT_QB =3D (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMPGDU_LE_QB =3D (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMP_EQ_PH =3D (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMP_LT_PH =3D (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_CMP_LE_PH =3D (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_PICK_QB =3D (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_PICK_PH =3D (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, - OPC_PACKRL_PH =3D (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, -}; - -#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP GPR-Based Shift Sub-class */ - OPC_SHLL_QB =3D (0x00 << 6) | OPC_SHLL_QB_DSP, - OPC_SHLLV_QB =3D (0x02 << 6) | OPC_SHLL_QB_DSP, - OPC_SHLL_PH =3D (0x08 << 6) | OPC_SHLL_QB_DSP, - OPC_SHLLV_PH =3D (0x0A << 6) | OPC_SHLL_QB_DSP, - OPC_SHLL_S_PH =3D (0x0C << 6) | OPC_SHLL_QB_DSP, - OPC_SHLLV_S_PH =3D (0x0E << 6) | OPC_SHLL_QB_DSP, - OPC_SHLL_S_W =3D (0x14 << 6) | OPC_SHLL_QB_DSP, - OPC_SHLLV_S_W =3D (0x16 << 6) | OPC_SHLL_QB_DSP, - OPC_SHRL_QB =3D (0x01 << 6) | OPC_SHLL_QB_DSP, - OPC_SHRLV_QB =3D (0x03 << 6) | OPC_SHLL_QB_DSP, - OPC_SHRL_PH =3D (0x19 << 6) | OPC_SHLL_QB_DSP, - OPC_SHRLV_PH =3D (0x1B << 6) | OPC_SHLL_QB_DSP, - OPC_SHRA_QB =3D (0x04 << 6) | OPC_SHLL_QB_DSP, - OPC_SHRA_R_QB =3D (0x05 << 6) | OPC_SHLL_QB_DSP, - OPC_SHRAV_QB =3D (0x06 << 6) | OPC_SHLL_QB_DSP, - OPC_SHRAV_R_QB =3D (0x07 << 6) | OPC_SHLL_QB_DSP, - OPC_SHRA_PH =3D (0x09 << 6) | OPC_SHLL_QB_DSP, - OPC_SHRAV_PH =3D (0x0B << 6) | OPC_SHLL_QB_DSP, - OPC_SHRA_R_PH =3D (0x0D << 6) | OPC_SHLL_QB_DSP, - OPC_SHRAV_R_PH =3D (0x0F << 6) | OPC_SHLL_QB_DSP, - OPC_SHRA_R_W =3D (0x15 << 6) | OPC_SHLL_QB_DSP, - OPC_SHRAV_R_W =3D (0x17 << 6) | OPC_SHLL_QB_DSP, -}; - -#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Multiply Sub-class insns */ - OPC_DPAU_H_QBL =3D (0x03 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPAU_H_QBR =3D (0x07 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPSU_H_QBL =3D (0x0B << 6) | OPC_DPA_W_PH_DSP, - OPC_DPSU_H_QBR =3D (0x0F << 6) | OPC_DPA_W_PH_DSP, - OPC_DPA_W_PH =3D (0x00 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPAX_W_PH =3D (0x08 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPAQ_S_W_PH =3D (0x04 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPAQX_S_W_PH =3D (0x18 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPAQX_SA_W_PH =3D (0x1A << 6) | OPC_DPA_W_PH_DSP, - OPC_DPS_W_PH =3D (0x01 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPSX_W_PH =3D (0x09 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPSQ_S_W_PH =3D (0x05 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPSQX_S_W_PH =3D (0x19 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPSQX_SA_W_PH =3D (0x1B << 6) | OPC_DPA_W_PH_DSP, - OPC_MULSAQ_S_W_PH =3D (0x06 << 6) | OPC_DPA_W_PH_DSP, - OPC_DPAQ_SA_L_W =3D (0x0C << 6) | OPC_DPA_W_PH_DSP, - OPC_DPSQ_SA_L_W =3D (0x0D << 6) | OPC_DPA_W_PH_DSP, - OPC_MAQ_S_W_PHL =3D (0x14 << 6) | OPC_DPA_W_PH_DSP, - OPC_MAQ_S_W_PHR =3D (0x16 << 6) | OPC_DPA_W_PH_DSP, - OPC_MAQ_SA_W_PHL =3D (0x10 << 6) | OPC_DPA_W_PH_DSP, - OPC_MAQ_SA_W_PHR =3D (0x12 << 6) | OPC_DPA_W_PH_DSP, - OPC_MULSA_W_PH =3D (0x02 << 6) | OPC_DPA_W_PH_DSP, -}; - -#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* DSP Bit/Manipulation Sub-class */ - OPC_INSV =3D (0x00 << 6) | OPC_INSV_DSP, -}; - -#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Append Sub-class */ - OPC_APPEND =3D (0x00 << 6) | OPC_APPEND_DSP, - OPC_PREPEND =3D (0x01 << 6) | OPC_APPEND_DSP, - OPC_BALIGN =3D (0x10 << 6) | OPC_APPEND_DSP, -}; - -#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Accumulator and DSPControl Access Sub-class */ - OPC_EXTR_W =3D (0x00 << 6) | OPC_EXTR_W_DSP, - OPC_EXTR_R_W =3D (0x04 << 6) | OPC_EXTR_W_DSP, - OPC_EXTR_RS_W =3D (0x06 << 6) | OPC_EXTR_W_DSP, - OPC_EXTR_S_H =3D (0x0E << 6) | OPC_EXTR_W_DSP, - OPC_EXTRV_S_H =3D (0x0F << 6) | OPC_EXTR_W_DSP, - OPC_EXTRV_W =3D (0x01 << 6) | OPC_EXTR_W_DSP, - OPC_EXTRV_R_W =3D (0x05 << 6) | OPC_EXTR_W_DSP, - OPC_EXTRV_RS_W =3D (0x07 << 6) | OPC_EXTR_W_DSP, - OPC_EXTP =3D (0x02 << 6) | OPC_EXTR_W_DSP, - OPC_EXTPV =3D (0x03 << 6) | OPC_EXTR_W_DSP, - OPC_EXTPDP =3D (0x0A << 6) | OPC_EXTR_W_DSP, - OPC_EXTPDPV =3D (0x0B << 6) | OPC_EXTR_W_DSP, - OPC_SHILO =3D (0x1A << 6) | OPC_EXTR_W_DSP, - OPC_SHILOV =3D (0x1B << 6) | OPC_EXTR_W_DSP, - OPC_MTHLIP =3D (0x1F << 6) | OPC_EXTR_W_DSP, - OPC_WRDSP =3D (0x13 << 6) | OPC_EXTR_W_DSP, - OPC_RDDSP =3D (0x12 << 6) | OPC_EXTR_W_DSP, -}; - -#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Arithmetic Sub-class */ - OPC_PRECEQ_L_PWL =3D (0x14 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEQ_L_PWR =3D (0x15 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEQ_PW_QHL =3D (0x0C << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEQ_PW_QHR =3D (0x0D << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEQ_PW_QHLA =3D (0x0E << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEQ_PW_QHRA =3D (0x0F << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEQU_QH_OBL =3D (0x04 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEQU_QH_OBR =3D (0x05 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEQU_QH_OBLA =3D (0x06 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEQU_QH_OBRA =3D (0x07 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEU_QH_OBL =3D (0x1C << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEU_QH_OBR =3D (0x1D << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEU_QH_OBLA =3D (0x1E << 6) | OPC_ABSQ_S_QH_DSP, - OPC_PRECEU_QH_OBRA =3D (0x1F << 6) | OPC_ABSQ_S_QH_DSP, - OPC_ABSQ_S_OB =3D (0x01 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_ABSQ_S_PW =3D (0x11 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_ABSQ_S_QH =3D (0x09 << 6) | OPC_ABSQ_S_QH_DSP, - /* DSP Bit/Manipulation Sub-class */ - OPC_REPL_OB =3D (0x02 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_REPL_PW =3D (0x12 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_REPL_QH =3D (0x0A << 6) | OPC_ABSQ_S_QH_DSP, - OPC_REPLV_OB =3D (0x03 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_REPLV_PW =3D (0x13 << 6) | OPC_ABSQ_S_QH_DSP, - OPC_REPLV_QH =3D (0x0B << 6) | OPC_ABSQ_S_QH_DSP, -}; - -#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Multiply Sub-class insns */ - OPC_MULEQ_S_PW_QHL =3D (0x1C << 6) | OPC_ADDU_OB_DSP, - OPC_MULEQ_S_PW_QHR =3D (0x1D << 6) | OPC_ADDU_OB_DSP, - OPC_MULEU_S_QH_OBL =3D (0x06 << 6) | OPC_ADDU_OB_DSP, - OPC_MULEU_S_QH_OBR =3D (0x07 << 6) | OPC_ADDU_OB_DSP, - OPC_MULQ_RS_QH =3D (0x1F << 6) | OPC_ADDU_OB_DSP, - /* MIPS DSP Arithmetic Sub-class */ - OPC_RADDU_L_OB =3D (0x14 << 6) | OPC_ADDU_OB_DSP, - OPC_SUBQ_PW =3D (0x13 << 6) | OPC_ADDU_OB_DSP, - OPC_SUBQ_S_PW =3D (0x17 << 6) | OPC_ADDU_OB_DSP, - OPC_SUBQ_QH =3D (0x0B << 6) | OPC_ADDU_OB_DSP, - OPC_SUBQ_S_QH =3D (0x0F << 6) | OPC_ADDU_OB_DSP, - OPC_SUBU_OB =3D (0x01 << 6) | OPC_ADDU_OB_DSP, - OPC_SUBU_S_OB =3D (0x05 << 6) | OPC_ADDU_OB_DSP, - OPC_SUBU_QH =3D (0x09 << 6) | OPC_ADDU_OB_DSP, - OPC_SUBU_S_QH =3D (0x0D << 6) | OPC_ADDU_OB_DSP, - OPC_SUBUH_OB =3D (0x19 << 6) | OPC_ADDU_OB_DSP, - OPC_SUBUH_R_OB =3D (0x1B << 6) | OPC_ADDU_OB_DSP, - OPC_ADDQ_PW =3D (0x12 << 6) | OPC_ADDU_OB_DSP, - OPC_ADDQ_S_PW =3D (0x16 << 6) | OPC_ADDU_OB_DSP, - OPC_ADDQ_QH =3D (0x0A << 6) | OPC_ADDU_OB_DSP, - OPC_ADDQ_S_QH =3D (0x0E << 6) | OPC_ADDU_OB_DSP, - OPC_ADDU_OB =3D (0x00 << 6) | OPC_ADDU_OB_DSP, - OPC_ADDU_S_OB =3D (0x04 << 6) | OPC_ADDU_OB_DSP, - OPC_ADDU_QH =3D (0x08 << 6) | OPC_ADDU_OB_DSP, - OPC_ADDU_S_QH =3D (0x0C << 6) | OPC_ADDU_OB_DSP, - OPC_ADDUH_OB =3D (0x18 << 6) | OPC_ADDU_OB_DSP, - OPC_ADDUH_R_OB =3D (0x1A << 6) | OPC_ADDU_OB_DSP, -}; - -#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* DSP Compare-Pick Sub-class */ - OPC_CMP_EQ_PW =3D (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMP_LT_PW =3D (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMP_LE_PW =3D (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMP_EQ_QH =3D (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMP_LT_QH =3D (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMP_LE_QH =3D (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMPGDU_EQ_OB =3D (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMPGDU_LT_OB =3D (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMPGDU_LE_OB =3D (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMPGU_EQ_OB =3D (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMPGU_LT_OB =3D (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMPGU_LE_OB =3D (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMPU_EQ_OB =3D (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMPU_LT_OB =3D (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_CMPU_LE_OB =3D (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PACKRL_PW =3D (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PICK_OB =3D (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PICK_PW =3D (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PICK_QH =3D (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, - /* MIPS DSP Arithmetic Sub-class */ - OPC_PRECR_OB_QH =3D (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PRECR_SRA_QH_PW =3D (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PRECR_SRA_R_QH_PW =3D (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PRECRQ_OB_QH =3D (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PRECRQ_PW_L =3D (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PRECRQ_QH_PW =3D (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PRECRQ_RS_QH_PW =3D (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, - OPC_PRECRQU_S_OB_QH =3D (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, -}; - -#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* DSP Append Sub-class */ - OPC_DAPPEND =3D (0x00 << 6) | OPC_DAPPEND_DSP, - OPC_PREPENDD =3D (0x03 << 6) | OPC_DAPPEND_DSP, - OPC_PREPENDW =3D (0x01 << 6) | OPC_DAPPEND_DSP, - OPC_DBALIGN =3D (0x10 << 6) | OPC_DAPPEND_DSP, -}; - -#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Accumulator and DSPControl Access Sub-class */ - OPC_DMTHLIP =3D (0x1F << 6) | OPC_DEXTR_W_DSP, - OPC_DSHILO =3D (0x1A << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTP =3D (0x02 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTPDP =3D (0x0A << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTPDPV =3D (0x0B << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTPV =3D (0x03 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTR_L =3D (0x10 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTR_R_L =3D (0x14 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTR_RS_L =3D (0x16 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTR_W =3D (0x00 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTR_R_W =3D (0x04 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTR_RS_W =3D (0x06 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTR_S_H =3D (0x0E << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTRV_L =3D (0x11 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTRV_R_L =3D (0x15 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTRV_RS_L =3D (0x17 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTRV_S_H =3D (0x0F << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTRV_W =3D (0x01 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTRV_R_W =3D (0x05 << 6) | OPC_DEXTR_W_DSP, - OPC_DEXTRV_RS_W =3D (0x07 << 6) | OPC_DEXTR_W_DSP, - OPC_DSHILOV =3D (0x1B << 6) | OPC_DEXTR_W_DSP, -}; - -#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* DSP Bit/Manipulation Sub-class */ - OPC_DINSV =3D (0x00 << 6) | OPC_DINSV_DSP, -}; - -#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP Multiply Sub-class insns */ - OPC_DMADD =3D (0x19 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DMADDU =3D (0x1D << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DMSUB =3D (0x1B << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DMSUBU =3D (0x1F << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DPA_W_QH =3D (0x00 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DPAQ_S_W_QH =3D (0x04 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DPAQ_SA_L_PW =3D (0x0C << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DPAU_H_OBL =3D (0x03 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DPAU_H_OBR =3D (0x07 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DPS_W_QH =3D (0x01 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DPSQ_S_W_QH =3D (0x05 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DPSQ_SA_L_PW =3D (0x0D << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DPSU_H_OBL =3D (0x0B << 6) | OPC_DPAQ_W_QH_DSP, - OPC_DPSU_H_OBR =3D (0x0F << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MAQ_S_L_PWL =3D (0x1C << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MAQ_S_L_PWR =3D (0x1E << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MAQ_S_W_QHLL =3D (0x14 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MAQ_SA_W_QHLL =3D (0x10 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MAQ_S_W_QHLR =3D (0x15 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MAQ_SA_W_QHLR =3D (0x11 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MAQ_S_W_QHRL =3D (0x16 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MAQ_SA_W_QHRL =3D (0x12 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MAQ_S_W_QHRR =3D (0x17 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MAQ_SA_W_QHRR =3D (0x13 << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MULSAQ_S_L_PW =3D (0x0E << 6) | OPC_DPAQ_W_QH_DSP, - OPC_MULSAQ_S_W_QH =3D (0x06 << 6) | OPC_DPAQ_W_QH_DSP, -}; - -#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) -enum { - /* MIPS DSP GPR-Based Shift Sub-class */ - OPC_SHLL_PW =3D (0x10 << 6) | OPC_SHLL_OB_DSP, - OPC_SHLL_S_PW =3D (0x14 << 6) | OPC_SHLL_OB_DSP, - OPC_SHLLV_OB =3D (0x02 << 6) | OPC_SHLL_OB_DSP, - OPC_SHLLV_PW =3D (0x12 << 6) | OPC_SHLL_OB_DSP, - OPC_SHLLV_S_PW =3D (0x16 << 6) | OPC_SHLL_OB_DSP, - OPC_SHLLV_QH =3D (0x0A << 6) | OPC_SHLL_OB_DSP, - OPC_SHLLV_S_QH =3D (0x0E << 6) | OPC_SHLL_OB_DSP, - OPC_SHRA_PW =3D (0x11 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRA_R_PW =3D (0x15 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRAV_OB =3D (0x06 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRAV_R_OB =3D (0x07 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRAV_PW =3D (0x13 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRAV_R_PW =3D (0x17 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRAV_QH =3D (0x0B << 6) | OPC_SHLL_OB_DSP, - OPC_SHRAV_R_QH =3D (0x0F << 6) | OPC_SHLL_OB_DSP, - OPC_SHRLV_OB =3D (0x03 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRLV_QH =3D (0x1B << 6) | OPC_SHLL_OB_DSP, - OPC_SHLL_OB =3D (0x00 << 6) | OPC_SHLL_OB_DSP, - OPC_SHLL_QH =3D (0x08 << 6) | OPC_SHLL_OB_DSP, - OPC_SHLL_S_QH =3D (0x0C << 6) | OPC_SHLL_OB_DSP, - OPC_SHRA_OB =3D (0x04 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRA_R_OB =3D (0x05 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRA_QH =3D (0x09 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRA_R_QH =3D (0x0D << 6) | OPC_SHLL_OB_DSP, - OPC_SHRL_OB =3D (0x01 << 6) | OPC_SHLL_OB_DSP, - OPC_SHRL_QH =3D (0x19 << 6) | OPC_SHLL_OB_DSP, -}; - /* Coprocessor 0 (rs field) */ #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21= ))) =20 @@ -2759,42 +2329,9 @@ static inline void check_cp1_registers(DisasContext = *ctx, int regs) } } =20 -/* - * Verify that the processor is running with DSP instructions enabled. - * This is enabled by CP0 Status register MX(24) bit. - */ -static inline void check_dsp(DisasContext *ctx) -{ - if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { - if (ctx->insn_flags & ASE_DSP) { - generate_exception_end(ctx, EXCP_DSPDIS); - } else { - generate_exception_end(ctx, EXCP_RI); - } - } -} - -static inline void check_dsp_r2(DisasContext *ctx) -{ - if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { - if (ctx->insn_flags & ASE_DSP) { - generate_exception_end(ctx, EXCP_DSPDIS); - } else { - generate_exception_end(ctx, EXCP_RI); - } - } -} - -static inline void check_dsp_r3(DisasContext *ctx) -{ - if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { - if (ctx->insn_flags & ASE_DSP) { - generate_exception_end(ctx, EXCP_DSPDIS); - } else { - generate_exception_end(ctx, EXCP_RI); - } - } -} +static inline void check_dsp(DisasContext *ctx); +static inline void check_dsp_r2(DisasContext *ctx); +static inline void check_dsp_r3(DisasContext *ctx); =20 /* * This code generates a "reserved instruction" exception if the @@ -22785,1686 +22322,7 @@ static int decode_nanomips_opc(CPUMIPSState *env= , DisasContext *ctx) =20 #endif =20 -/* MIPSDSP functions. */ -static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc, - int rd, int base, int offset) -{ - TCGv t0; - - check_dsp(ctx); - t0 =3D tcg_temp_new(); - - if (base =3D=3D 0) { - gen_load_gpr(t0, offset); - } else if (offset =3D=3D 0) { - gen_load_gpr(t0, base); - } else { - gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); - } - - switch (opc) { - case OPC_LBUX: - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); - gen_store_gpr(t0, rd); - break; - case OPC_LHX: - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW); - gen_store_gpr(t0, rd); - break; - case OPC_LWX: - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); - gen_store_gpr(t0, rd); - break; -#if defined(TARGET_MIPS64) - case OPC_LDX: - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); - gen_store_gpr(t0, rd); - break; -#endif - } - tcg_temp_free(t0); -} - -static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op= 2, - int ret, int v1, int v2) -{ - TCGv v1_t; - TCGv v2_t; - - if (ret =3D=3D 0) { - /* Treat as NOP. */ - return; - } - - v1_t =3D tcg_temp_new(); - v2_t =3D tcg_temp_new(); - - gen_load_gpr(v1_t, v1); - gen_load_gpr(v2_t, v2); - - switch (op1) { - /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */ - case OPC_MULT_G_2E: - check_dsp_r2(ctx); - switch (op2) { - case OPC_ADDUH_QB: - gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_ADDUH_R_QB: - gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_ADDQH_PH: - gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_ADDQH_R_PH: - gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_ADDQH_W: - gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_ADDQH_R_W: - gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SUBUH_QB: - gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SUBUH_R_QB: - gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SUBQH_PH: - gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SUBQH_R_PH: - gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SUBQH_W: - gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SUBQH_R_W: - gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); - break; - } - break; - case OPC_ABSQ_S_PH_DSP: - switch (op2) { - case OPC_ABSQ_S_QB: - check_dsp_r2(ctx); - gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env); - break; - case OPC_ABSQ_S_PH: - check_dsp(ctx); - gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env); - break; - case OPC_ABSQ_S_W: - check_dsp(ctx); - gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env); - break; - case OPC_PRECEQ_W_PHL: - check_dsp(ctx); - tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); - tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); - break; - case OPC_PRECEQ_W_PHR: - check_dsp(ctx); - tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); - tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); - tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); - break; - case OPC_PRECEQU_PH_QBL: - check_dsp(ctx); - gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEQU_PH_QBR: - check_dsp(ctx); - gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEQU_PH_QBLA: - check_dsp(ctx); - gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEQU_PH_QBRA: - check_dsp(ctx); - gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEU_PH_QBL: - check_dsp(ctx); - gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEU_PH_QBR: - check_dsp(ctx); - gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEU_PH_QBLA: - check_dsp(ctx); - gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEU_PH_QBRA: - check_dsp(ctx); - gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); - break; - } - break; - case OPC_ADDU_QB_DSP: - switch (op2) { - case OPC_ADDQ_PH: - check_dsp(ctx); - gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDQ_S_PH: - check_dsp(ctx); - gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDQ_S_W: - check_dsp(ctx); - gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDU_QB: - check_dsp(ctx); - gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDU_S_QB: - check_dsp(ctx); - gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDU_PH: - check_dsp_r2(ctx); - gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDU_S_PH: - check_dsp_r2(ctx); - gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBQ_PH: - check_dsp(ctx); - gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBQ_S_PH: - check_dsp(ctx); - gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBQ_S_W: - check_dsp(ctx); - gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBU_QB: - check_dsp(ctx); - gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBU_S_QB: - check_dsp(ctx); - gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBU_PH: - check_dsp_r2(ctx); - gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBU_S_PH: - check_dsp_r2(ctx); - gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDSC: - check_dsp(ctx); - gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDWC: - check_dsp(ctx); - gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MODSUB: - check_dsp(ctx); - gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_RADDU_W_QB: - check_dsp(ctx); - gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); - break; - } - break; - case OPC_CMPU_EQ_QB_DSP: - switch (op2) { - case OPC_PRECR_QB_PH: - check_dsp_r2(ctx); - gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_PRECRQ_QB_PH: - check_dsp(ctx); - gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_PRECR_SRA_PH_W: - check_dsp_r2(ctx); - { - TCGv_i32 sa_t =3D tcg_const_i32(v2); - gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, - cpu_gpr[ret]); - tcg_temp_free_i32(sa_t); - break; - } - case OPC_PRECR_SRA_R_PH_W: - check_dsp_r2(ctx); - { - TCGv_i32 sa_t =3D tcg_const_i32(v2); - gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, - cpu_gpr[ret]); - tcg_temp_free_i32(sa_t); - break; - } - case OPC_PRECRQ_PH_W: - check_dsp(ctx); - gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_PRECRQ_RS_PH_W: - check_dsp(ctx); - gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_PRECRQU_S_QB_PH: - check_dsp(ctx); - gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - } - break; -#ifdef TARGET_MIPS64 - case OPC_ABSQ_S_QH_DSP: - switch (op2) { - case OPC_PRECEQ_L_PWL: - check_dsp(ctx); - tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); - break; - case OPC_PRECEQ_L_PWR: - check_dsp(ctx); - tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); - break; - case OPC_PRECEQ_PW_QHL: - check_dsp(ctx); - gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEQ_PW_QHR: - check_dsp(ctx); - gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEQ_PW_QHLA: - check_dsp(ctx); - gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEQ_PW_QHRA: - check_dsp(ctx); - gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEQU_QH_OBL: - check_dsp(ctx); - gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEQU_QH_OBR: - check_dsp(ctx); - gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEQU_QH_OBLA: - check_dsp(ctx); - gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEQU_QH_OBRA: - check_dsp(ctx); - gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEU_QH_OBL: - check_dsp(ctx); - gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEU_QH_OBR: - check_dsp(ctx); - gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEU_QH_OBLA: - check_dsp(ctx); - gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); - break; - case OPC_PRECEU_QH_OBRA: - check_dsp(ctx); - gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); - break; - case OPC_ABSQ_S_OB: - check_dsp_r2(ctx); - gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env); - break; - case OPC_ABSQ_S_PW: - check_dsp(ctx); - gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env); - break; - case OPC_ABSQ_S_QH: - check_dsp(ctx); - gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env); - break; - } - break; - case OPC_ADDU_OB_DSP: - switch (op2) { - case OPC_RADDU_L_OB: - check_dsp(ctx); - gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); - break; - case OPC_SUBQ_PW: - check_dsp(ctx); - gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBQ_S_PW: - check_dsp(ctx); - gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBQ_QH: - check_dsp(ctx); - gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBQ_S_QH: - check_dsp(ctx); - gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBU_OB: - check_dsp(ctx); - gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBU_S_OB: - check_dsp(ctx); - gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBU_QH: - check_dsp_r2(ctx); - gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBU_S_QH: - check_dsp_r2(ctx); - gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SUBUH_OB: - check_dsp_r2(ctx); - gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SUBUH_R_OB: - check_dsp_r2(ctx); - gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_ADDQ_PW: - check_dsp(ctx); - gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDQ_S_PW: - check_dsp(ctx); - gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDQ_QH: - check_dsp(ctx); - gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDQ_S_QH: - check_dsp(ctx); - gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDU_OB: - check_dsp(ctx); - gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDU_S_OB: - check_dsp(ctx); - gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDU_QH: - check_dsp_r2(ctx); - gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDU_S_QH: - check_dsp_r2(ctx); - gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_ADDUH_OB: - check_dsp_r2(ctx); - gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_ADDUH_R_OB: - check_dsp_r2(ctx); - gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); - break; - } - break; - case OPC_CMPU_EQ_OB_DSP: - switch (op2) { - case OPC_PRECR_OB_QH: - check_dsp_r2(ctx); - gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_PRECR_SRA_QH_PW: - check_dsp_r2(ctx); - { - TCGv_i32 ret_t =3D tcg_const_i32(ret); - gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); - tcg_temp_free_i32(ret_t); - break; - } - case OPC_PRECR_SRA_R_QH_PW: - check_dsp_r2(ctx); - { - TCGv_i32 sa_v =3D tcg_const_i32(ret); - gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); - tcg_temp_free_i32(sa_v); - break; - } - case OPC_PRECRQ_OB_QH: - check_dsp(ctx); - gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_PRECRQ_PW_L: - check_dsp(ctx); - gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_PRECRQ_QH_PW: - check_dsp(ctx); - gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_PRECRQ_RS_QH_PW: - check_dsp(ctx); - gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_PRECRQU_S_OB_QH: - check_dsp(ctx); - gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - } - break; -#endif - } - - tcg_temp_free(v1_t); - tcg_temp_free(v2_t); -} - -static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, - int ret, int v1, int v2) -{ - uint32_t op2; - TCGv t0; - TCGv v1_t; - TCGv v2_t; - - if (ret =3D=3D 0) { - /* Treat as NOP. */ - return; - } - - t0 =3D tcg_temp_new(); - v1_t =3D tcg_temp_new(); - v2_t =3D tcg_temp_new(); - - tcg_gen_movi_tl(t0, v1); - gen_load_gpr(v1_t, v1); - gen_load_gpr(v2_t, v2); - - switch (opc) { - case OPC_SHLL_QB_DSP: - { - op2 =3D MASK_SHLL_QB(ctx->opcode); - switch (op2) { - case OPC_SHLL_QB: - check_dsp(ctx); - gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env); - break; - case OPC_SHLLV_QB: - check_dsp(ctx); - gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SHLL_PH: - check_dsp(ctx); - gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env); - break; - case OPC_SHLLV_PH: - check_dsp(ctx); - gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SHLL_S_PH: - check_dsp(ctx); - gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env); - break; - case OPC_SHLLV_S_PH: - check_dsp(ctx); - gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SHLL_S_W: - check_dsp(ctx); - gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env); - break; - case OPC_SHLLV_S_W: - check_dsp(ctx); - gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_SHRL_QB: - check_dsp(ctx); - gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); - break; - case OPC_SHRLV_QB: - check_dsp(ctx); - gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SHRL_PH: - check_dsp_r2(ctx); - gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); - break; - case OPC_SHRLV_PH: - check_dsp_r2(ctx); - gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SHRA_QB: - check_dsp_r2(ctx); - gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); - break; - case OPC_SHRA_R_QB: - check_dsp_r2(ctx); - gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); - break; - case OPC_SHRAV_QB: - check_dsp_r2(ctx); - gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SHRAV_R_QB: - check_dsp_r2(ctx); - gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SHRA_PH: - check_dsp(ctx); - gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); - break; - case OPC_SHRA_R_PH: - check_dsp(ctx); - gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); - break; - case OPC_SHRAV_PH: - check_dsp(ctx); - gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SHRAV_R_PH: - check_dsp(ctx); - gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_SHRA_R_W: - check_dsp(ctx); - gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); - break; - case OPC_SHRAV_R_W: - check_dsp(ctx); - gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); - break; - default: /* Invalid */ - MIPS_INVAL("MASK SHLL.QB"); - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - } -#ifdef TARGET_MIPS64 - case OPC_SHLL_OB_DSP: - op2 =3D MASK_SHLL_OB(ctx->opcode); - switch (op2) { - case OPC_SHLL_PW: - check_dsp(ctx); - gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env); - break; - case OPC_SHLLV_PW: - check_dsp(ctx); - gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); - break; - case OPC_SHLL_S_PW: - check_dsp(ctx); - gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env); - break; - case OPC_SHLLV_S_PW: - check_dsp(ctx); - gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); - break; - case OPC_SHLL_OB: - check_dsp(ctx); - gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env); - break; - case OPC_SHLLV_OB: - check_dsp(ctx); - gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env); - break; - case OPC_SHLL_QH: - check_dsp(ctx); - gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env); - break; - case OPC_SHLLV_QH: - check_dsp(ctx); - gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); - break; - case OPC_SHLL_S_QH: - check_dsp(ctx); - gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env); - break; - case OPC_SHLLV_S_QH: - check_dsp(ctx); - gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); - break; - case OPC_SHRA_OB: - check_dsp_r2(ctx); - gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); - break; - case OPC_SHRAV_OB: - check_dsp_r2(ctx); - gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); - break; - case OPC_SHRA_R_OB: - check_dsp_r2(ctx); - gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); - break; - case OPC_SHRAV_R_OB: - check_dsp_r2(ctx); - gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); - break; - case OPC_SHRA_PW: - check_dsp(ctx); - gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); - break; - case OPC_SHRAV_PW: - check_dsp(ctx); - gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); - break; - case OPC_SHRA_R_PW: - check_dsp(ctx); - gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); - break; - case OPC_SHRAV_R_PW: - check_dsp(ctx); - gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); - break; - case OPC_SHRA_QH: - check_dsp(ctx); - gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); - break; - case OPC_SHRAV_QH: - check_dsp(ctx); - gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); - break; - case OPC_SHRA_R_QH: - check_dsp(ctx); - gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); - break; - case OPC_SHRAV_R_QH: - check_dsp(ctx); - gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); - break; - case OPC_SHRL_OB: - check_dsp(ctx); - gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); - break; - case OPC_SHRLV_OB: - check_dsp(ctx); - gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); - break; - case OPC_SHRL_QH: - check_dsp_r2(ctx); - gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); - break; - case OPC_SHRLV_QH: - check_dsp_r2(ctx); - gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); - break; - default: /* Invalid */ - MIPS_INVAL("MASK SHLL.OB"); - generate_exception_end(ctx, EXCP_RI); - break; - } - break; -#endif - } - - tcg_temp_free(t0); - tcg_temp_free(v1_t); - tcg_temp_free(v2_t); -} - -static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t= op2, - int ret, int v1, int v2, int check_ret) -{ - TCGv_i32 t0; - TCGv v1_t; - TCGv v2_t; - - if ((ret =3D=3D 0) && (check_ret =3D=3D 1)) { - /* Treat as NOP. */ - return; - } - - t0 =3D tcg_temp_new_i32(); - v1_t =3D tcg_temp_new(); - v2_t =3D tcg_temp_new(); - - tcg_gen_movi_i32(t0, ret); - gen_load_gpr(v1_t, v1); - gen_load_gpr(v2_t, v2); - - switch (op1) { - /* - * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have - * the same mask and op1. - */ - case OPC_MULT_G_2E: - check_dsp_r2(ctx); - switch (op2) { - case OPC_MUL_PH: - gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MUL_S_PH: - gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULQ_S_W: - gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULQ_RS_W: - gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - } - break; - case OPC_DPA_W_PH_DSP: - switch (op2) { - case OPC_DPAU_H_QBL: - check_dsp(ctx); - gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPAU_H_QBR: - check_dsp(ctx); - gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPSU_H_QBL: - check_dsp(ctx); - gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPSU_H_QBR: - check_dsp(ctx); - gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPA_W_PH: - check_dsp_r2(ctx); - gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPAX_W_PH: - check_dsp_r2(ctx); - gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPAQ_S_W_PH: - check_dsp(ctx); - gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPAQX_S_W_PH: - check_dsp_r2(ctx); - gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPAQX_SA_W_PH: - check_dsp_r2(ctx); - gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPS_W_PH: - check_dsp_r2(ctx); - gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPSX_W_PH: - check_dsp_r2(ctx); - gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPSQ_S_W_PH: - check_dsp(ctx); - gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPSQX_S_W_PH: - check_dsp_r2(ctx); - gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPSQX_SA_W_PH: - check_dsp_r2(ctx); - gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_MULSAQ_S_W_PH: - check_dsp(ctx); - gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPAQ_SA_L_W: - check_dsp(ctx); - gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env); - break; - case OPC_DPSQ_SA_L_W: - check_dsp(ctx); - gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env); - break; - case OPC_MAQ_S_W_PHL: - check_dsp(ctx); - gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env); - break; - case OPC_MAQ_S_W_PHR: - check_dsp(ctx); - gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env); - break; - case OPC_MAQ_SA_W_PHL: - check_dsp(ctx); - gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env); - break; - case OPC_MAQ_SA_W_PHR: - check_dsp(ctx); - gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env); - break; - case OPC_MULSA_W_PH: - check_dsp_r2(ctx); - gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env); - break; - } - break; -#ifdef TARGET_MIPS64 - case OPC_DPAQ_W_QH_DSP: - { - int ac =3D ret & 0x03; - tcg_gen_movi_i32(t0, ac); - - switch (op2) { - case OPC_DMADD: - check_dsp(ctx); - gen_helper_dmadd(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DMADDU: - check_dsp(ctx); - gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DMSUB: - check_dsp(ctx); - gen_helper_dmsub(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DMSUBU: - check_dsp(ctx); - gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DPA_W_QH: - check_dsp_r2(ctx); - gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DPAQ_S_W_QH: - check_dsp(ctx); - gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DPAQ_SA_L_PW: - check_dsp(ctx); - gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DPAU_H_OBL: - check_dsp(ctx); - gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DPAU_H_OBR: - check_dsp(ctx); - gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DPS_W_QH: - check_dsp_r2(ctx); - gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DPSQ_S_W_QH: - check_dsp(ctx); - gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DPSQ_SA_L_PW: - check_dsp(ctx); - gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DPSU_H_OBL: - check_dsp(ctx); - gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env); - break; - case OPC_DPSU_H_OBR: - check_dsp(ctx); - gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MAQ_S_L_PWL: - check_dsp(ctx); - gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MAQ_S_L_PWR: - check_dsp(ctx); - gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MAQ_S_W_QHLL: - check_dsp(ctx); - gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MAQ_SA_W_QHLL: - check_dsp(ctx); - gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MAQ_S_W_QHLR: - check_dsp(ctx); - gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MAQ_SA_W_QHLR: - check_dsp(ctx); - gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MAQ_S_W_QHRL: - check_dsp(ctx); - gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MAQ_SA_W_QHRL: - check_dsp(ctx); - gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MAQ_S_W_QHRR: - check_dsp(ctx); - gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MAQ_SA_W_QHRR: - check_dsp(ctx); - gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MULSAQ_S_L_PW: - check_dsp(ctx); - gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env); - break; - case OPC_MULSAQ_S_W_QH: - check_dsp(ctx); - gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env); - break; - } - } - break; -#endif - case OPC_ADDU_QB_DSP: - switch (op2) { - case OPC_MULEU_S_PH_QBL: - check_dsp(ctx); - gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULEU_S_PH_QBR: - check_dsp(ctx); - gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULQ_RS_PH: - check_dsp(ctx); - gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULEQ_S_W_PHL: - check_dsp(ctx); - gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULEQ_S_W_PHR: - check_dsp(ctx); - gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULQ_S_PH: - check_dsp_r2(ctx); - gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - } - break; -#ifdef TARGET_MIPS64 - case OPC_ADDU_OB_DSP: - switch (op2) { - case OPC_MULEQ_S_PW_QHL: - check_dsp(ctx); - gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULEQ_S_PW_QHR: - check_dsp(ctx); - gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULEU_S_QH_OBL: - check_dsp(ctx); - gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULEU_S_QH_OBR: - check_dsp(ctx); - gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_MULQ_RS_QH: - check_dsp(ctx); - gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - } - break; -#endif - } - - tcg_temp_free_i32(t0); - tcg_temp_free(v1_t); - tcg_temp_free(v2_t); -} - -static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t = op2, - int ret, int val) -{ - int16_t imm; - TCGv t0; - TCGv val_t; - - if (ret =3D=3D 0) { - /* Treat as NOP. */ - return; - } - - t0 =3D tcg_temp_new(); - val_t =3D tcg_temp_new(); - gen_load_gpr(val_t, val); - - switch (op1) { - case OPC_ABSQ_S_PH_DSP: - switch (op2) { - case OPC_BITREV: - check_dsp(ctx); - gen_helper_bitrev(cpu_gpr[ret], val_t); - break; - case OPC_REPL_QB: - check_dsp(ctx); - { - target_long result; - imm =3D (ctx->opcode >> 16) & 0xFF; - result =3D (uint32_t)imm << 24 | - (uint32_t)imm << 16 | - (uint32_t)imm << 8 | - (uint32_t)imm; - result =3D (int32_t)result; - tcg_gen_movi_tl(cpu_gpr[ret], result); - } - break; - case OPC_REPLV_QB: - check_dsp(ctx); - tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); - tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); - tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); - tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); - tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); - tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); - break; - case OPC_REPL_PH: - check_dsp(ctx); - { - imm =3D (ctx->opcode >> 16) & 0x03FF; - imm =3D (int16_t)(imm << 6) >> 6; - tcg_gen_movi_tl(cpu_gpr[ret], \ - (target_long)((int32_t)imm << 16 | \ - (uint16_t)imm)); - } - break; - case OPC_REPLV_PH: - check_dsp(ctx); - tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); - tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); - tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); - tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); - break; - } - break; -#ifdef TARGET_MIPS64 - case OPC_ABSQ_S_QH_DSP: - switch (op2) { - case OPC_REPL_OB: - check_dsp(ctx); - { - target_long temp; - - imm =3D (ctx->opcode >> 16) & 0xFF; - temp =3D ((uint64_t)imm << 8) | (uint64_t)imm; - temp =3D (temp << 16) | temp; - temp =3D (temp << 32) | temp; - tcg_gen_movi_tl(cpu_gpr[ret], temp); - break; - } - case OPC_REPL_PW: - check_dsp(ctx); - { - target_long temp; - - imm =3D (ctx->opcode >> 16) & 0x03FF; - imm =3D (int16_t)(imm << 6) >> 6; - temp =3D ((target_long)imm << 32) \ - | ((target_long)imm & 0xFFFFFFFF); - tcg_gen_movi_tl(cpu_gpr[ret], temp); - break; - } - case OPC_REPL_QH: - check_dsp(ctx); - { - target_long temp; - - imm =3D (ctx->opcode >> 16) & 0x03FF; - imm =3D (int16_t)(imm << 6) >> 6; - - temp =3D ((uint64_t)(uint16_t)imm << 48) | - ((uint64_t)(uint16_t)imm << 32) | - ((uint64_t)(uint16_t)imm << 16) | - (uint64_t)(uint16_t)imm; - tcg_gen_movi_tl(cpu_gpr[ret], temp); - break; - } - case OPC_REPLV_OB: - check_dsp(ctx); - tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); - tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); - tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); - tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); - tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); - tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); - tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); - break; - case OPC_REPLV_PW: - check_dsp(ctx); - tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); - tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); - tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); - break; - case OPC_REPLV_QH: - check_dsp(ctx); - tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); - tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); - tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); - tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); - tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); - break; - } - break; -#endif - } - tcg_temp_free(t0); - tcg_temp_free(val_t); -} - -static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, - uint32_t op1, uint32_t op2, - int ret, int v1, int v2, int check_re= t) -{ - TCGv t1; - TCGv v1_t; - TCGv v2_t; - - if ((ret =3D=3D 0) && (check_ret =3D=3D 1)) { - /* Treat as NOP. */ - return; - } - - t1 =3D tcg_temp_new(); - v1_t =3D tcg_temp_new(); - v2_t =3D tcg_temp_new(); - - gen_load_gpr(v1_t, v1); - gen_load_gpr(v2_t, v2); - - switch (op1) { - case OPC_CMPU_EQ_QB_DSP: - switch (op2) { - case OPC_CMPU_EQ_QB: - check_dsp(ctx); - gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); - break; - case OPC_CMPU_LT_QB: - check_dsp(ctx); - gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); - break; - case OPC_CMPU_LE_QB: - check_dsp(ctx); - gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); - break; - case OPC_CMPGU_EQ_QB: - check_dsp(ctx); - gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_CMPGU_LT_QB: - check_dsp(ctx); - gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_CMPGU_LE_QB: - check_dsp(ctx); - gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_CMPGDU_EQ_QB: - check_dsp_r2(ctx); - gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); - tcg_gen_mov_tl(cpu_gpr[ret], t1); - tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); - tcg_gen_shli_tl(t1, t1, 24); - tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); - break; - case OPC_CMPGDU_LT_QB: - check_dsp_r2(ctx); - gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); - tcg_gen_mov_tl(cpu_gpr[ret], t1); - tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); - tcg_gen_shli_tl(t1, t1, 24); - tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); - break; - case OPC_CMPGDU_LE_QB: - check_dsp_r2(ctx); - gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); - tcg_gen_mov_tl(cpu_gpr[ret], t1); - tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); - tcg_gen_shli_tl(t1, t1, 24); - tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); - break; - case OPC_CMP_EQ_PH: - check_dsp(ctx); - gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); - break; - case OPC_CMP_LT_PH: - check_dsp(ctx); - gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); - break; - case OPC_CMP_LE_PH: - check_dsp(ctx); - gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); - break; - case OPC_PICK_QB: - check_dsp(ctx); - gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_PICK_PH: - check_dsp(ctx); - gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_PACKRL_PH: - check_dsp(ctx); - gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); - break; - } - break; -#ifdef TARGET_MIPS64 - case OPC_CMPU_EQ_OB_DSP: - switch (op2) { - case OPC_CMP_EQ_PW: - check_dsp(ctx); - gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env); - break; - case OPC_CMP_LT_PW: - check_dsp(ctx); - gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env); - break; - case OPC_CMP_LE_PW: - check_dsp(ctx); - gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env); - break; - case OPC_CMP_EQ_QH: - check_dsp(ctx); - gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env); - break; - case OPC_CMP_LT_QH: - check_dsp(ctx); - gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env); - break; - case OPC_CMP_LE_QH: - check_dsp(ctx); - gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env); - break; - case OPC_CMPGDU_EQ_OB: - check_dsp_r2(ctx); - gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_CMPGDU_LT_OB: - check_dsp_r2(ctx); - gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_CMPGDU_LE_OB: - check_dsp_r2(ctx); - gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_CMPGU_EQ_OB: - check_dsp(ctx); - gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_CMPGU_LT_OB: - check_dsp(ctx); - gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_CMPGU_LE_OB: - check_dsp(ctx); - gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_CMPU_EQ_OB: - check_dsp(ctx); - gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env); - break; - case OPC_CMPU_LT_OB: - check_dsp(ctx); - gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env); - break; - case OPC_CMPU_LE_OB: - check_dsp(ctx); - gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env); - break; - case OPC_PACKRL_PW: - check_dsp(ctx); - gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); - break; - case OPC_PICK_OB: - check_dsp(ctx); - gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_PICK_PW: - check_dsp(ctx); - gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - case OPC_PICK_QH: - check_dsp(ctx); - gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); - break; - } - break; -#endif - } - - tcg_temp_free(t1); - tcg_temp_free(v1_t); - tcg_temp_free(v2_t); -} - -static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, - uint32_t op1, int rt, int rs, int sa) -{ - TCGv t0; - - check_dsp_r2(ctx); - - if (rt =3D=3D 0) { - /* Treat as NOP. */ - return; - } - - t0 =3D tcg_temp_new(); - gen_load_gpr(t0, rs); - - switch (op1) { - case OPC_APPEND_DSP: - switch (MASK_APPEND(ctx->opcode)) { - case OPC_APPEND: - if (sa !=3D 0) { - tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - = sa); - } - tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); - break; - case OPC_PREPEND: - if (sa !=3D 0) { - tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); - tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); - tcg_gen_shli_tl(t0, t0, 32 - sa); - tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); - } - tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); - break; - case OPC_BALIGN: - sa &=3D 3; - if (sa !=3D 0 && sa !=3D 2) { - tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); - tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); - } - tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); - break; - default: /* Invalid */ - MIPS_INVAL("MASK APPEND"); - generate_exception_end(ctx, EXCP_RI); - break; - } - break; -#ifdef TARGET_MIPS64 - case OPC_DAPPEND_DSP: - switch (MASK_DAPPEND(ctx->opcode)) { - case OPC_DAPPEND: - if (sa !=3D 0) { - tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - = sa); - } - break; - case OPC_PREPENDD: - tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); - tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); - tcg_gen_or_tl(cpu_gpr[rt], t0, t0); - break; - case OPC_PREPENDW: - if (sa !=3D 0) { - tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); - tcg_gen_shli_tl(t0, t0, 64 - sa); - tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); - } - break; - case OPC_DBALIGN: - sa &=3D 7; - if (sa !=3D 0 && sa !=3D 2 && sa !=3D 4) { - tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); - tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); - tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); - } - break; - default: /* Invalid */ - MIPS_INVAL("MASK DAPPEND"); - generate_exception_end(ctx, EXCP_RI); - break; - } - break; -#endif - } - tcg_temp_free(t0); -} - -static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t = op2, - int ret, int v1, int v2, int check_ret) - -{ - TCGv t0; - TCGv t1; - TCGv v1_t; - TCGv v2_t; - int16_t imm; - - if ((ret =3D=3D 0) && (check_ret =3D=3D 1)) { - /* Treat as NOP. */ - return; - } - - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - v1_t =3D tcg_temp_new(); - v2_t =3D tcg_temp_new(); - - gen_load_gpr(v1_t, v1); - gen_load_gpr(v2_t, v2); - - switch (op1) { - case OPC_EXTR_W_DSP: - check_dsp(ctx); - switch (op2) { - case OPC_EXTR_W: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_EXTR_R_W: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_EXTR_RS_W: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_EXTR_S_H: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_EXTRV_S_H: - tcg_gen_movi_tl(t0, v2); - gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_EXTRV_W: - tcg_gen_movi_tl(t0, v2); - gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_EXTRV_R_W: - tcg_gen_movi_tl(t0, v2); - gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_EXTRV_RS_W: - tcg_gen_movi_tl(t0, v2); - gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_EXTP: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_EXTPV: - tcg_gen_movi_tl(t0, v2); - gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_EXTPDP: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_EXTPDPV: - tcg_gen_movi_tl(t0, v2); - gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_SHILO: - imm =3D (ctx->opcode >> 20) & 0x3F; - tcg_gen_movi_tl(t0, ret); - tcg_gen_movi_tl(t1, imm); - gen_helper_shilo(t0, t1, cpu_env); - break; - case OPC_SHILOV: - tcg_gen_movi_tl(t0, ret); - gen_helper_shilo(t0, v1_t, cpu_env); - break; - case OPC_MTHLIP: - tcg_gen_movi_tl(t0, ret); - gen_helper_mthlip(t0, v1_t, cpu_env); - break; - case OPC_WRDSP: - imm =3D (ctx->opcode >> 11) & 0x3FF; - tcg_gen_movi_tl(t0, imm); - gen_helper_wrdsp(v1_t, t0, cpu_env); - break; - case OPC_RDDSP: - imm =3D (ctx->opcode >> 16) & 0x03FF; - tcg_gen_movi_tl(t0, imm); - gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env); - break; - } - break; -#ifdef TARGET_MIPS64 - case OPC_DEXTR_W_DSP: - check_dsp(ctx); - switch (op2) { - case OPC_DMTHLIP: - tcg_gen_movi_tl(t0, ret); - gen_helper_dmthlip(v1_t, t0, cpu_env); - break; - case OPC_DSHILO: - { - int shift =3D (ctx->opcode >> 19) & 0x7F; - int ac =3D (ctx->opcode >> 11) & 0x03; - tcg_gen_movi_tl(t0, shift); - tcg_gen_movi_tl(t1, ac); - gen_helper_dshilo(t0, t1, cpu_env); - break; - } - case OPC_DSHILOV: - { - int ac =3D (ctx->opcode >> 11) & 0x03; - tcg_gen_movi_tl(t0, ac); - gen_helper_dshilo(v1_t, t0, cpu_env); - break; - } - case OPC_DEXTP: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - - gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_DEXTPV: - tcg_gen_movi_tl(t0, v2); - gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_DEXTPDP: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_DEXTPDPV: - tcg_gen_movi_tl(t0, v2); - gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_DEXTR_L: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_DEXTR_R_L: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_DEXTR_RS_L: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_DEXTR_W: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_DEXTR_R_W: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_DEXTR_RS_W: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_DEXTR_S_H: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_DEXTRV_S_H: - tcg_gen_movi_tl(t0, v2); - tcg_gen_movi_tl(t1, v1); - gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); - break; - case OPC_DEXTRV_L: - tcg_gen_movi_tl(t0, v2); - gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_DEXTRV_R_L: - tcg_gen_movi_tl(t0, v2); - gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_DEXTRV_RS_L: - tcg_gen_movi_tl(t0, v2); - gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_DEXTRV_W: - tcg_gen_movi_tl(t0, v2); - gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_DEXTRV_R_W: - tcg_gen_movi_tl(t0, v2); - gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - case OPC_DEXTRV_RS_W: - tcg_gen_movi_tl(t0, v2); - gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); - break; - } - break; -#endif - } - - tcg_temp_free(t0); - tcg_temp_free(t1); - tcg_temp_free(v1_t); - tcg_temp_free(v2_t); -} - -/* End MIPSDSP functions. */ +#include "mod-mips-dsp_translate.c.inc" =20 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) { diff --git a/target/mips/mod-mips-dsp_translate.c.inc b/target/mips/mod-mip= s-dsp_translate.c.inc new file mode 100644 index 00000000000..80e3172c0be --- /dev/null +++ b/target/mips/mod-mips-dsp_translate.c.inc @@ -0,0 +1,2158 @@ +/* + * MIPS DSP Architecture Module translation routines + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +enum { + /* MIPS DSP Load */ + OPC_LX_DSP =3D 0x0A | OPC_SPECIAL3, + /* MIPS DSP Arithmetic */ + OPC_ADDU_QB_DSP =3D 0x10 | OPC_SPECIAL3, + OPC_ADDU_OB_DSP =3D 0x14 | OPC_SPECIAL3, + OPC_ABSQ_S_PH_DSP =3D 0x12 | OPC_SPECIAL3, + OPC_ABSQ_S_QH_DSP =3D 0x16 | OPC_SPECIAL3, + /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */ + /* OPC_ADDUH_QB_DSP =3D 0x18 | OPC_SPECIAL3, */ + OPC_CMPU_EQ_QB_DSP =3D 0x11 | OPC_SPECIAL3, + OPC_CMPU_EQ_OB_DSP =3D 0x15 | OPC_SPECIAL3, + /* MIPS DSP GPR-Based Shift Sub-class */ + OPC_SHLL_QB_DSP =3D 0x13 | OPC_SPECIAL3, + OPC_SHLL_OB_DSP =3D 0x17 | OPC_SPECIAL3, + /* MIPS DSP Multiply Sub-class insns */ + /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */ + /* OPC_MUL_PH_DSP =3D 0x18 | OPC_SPECIAL3, */ + OPC_DPA_W_PH_DSP =3D 0x30 | OPC_SPECIAL3, + OPC_DPAQ_W_QH_DSP =3D 0x34 | OPC_SPECIAL3, + /* DSP Bit/Manipulation Sub-class */ + OPC_INSV_DSP =3D 0x0C | OPC_SPECIAL3, + OPC_DINSV_DSP =3D 0x0D | OPC_SPECIAL3, + /* MIPS DSP Append Sub-class */ + OPC_APPEND_DSP =3D 0x31 | OPC_SPECIAL3, + OPC_DAPPEND_DSP =3D 0x35 | OPC_SPECIAL3, + /* MIPS DSP Accumulator and DSPControl Access Sub-class */ + OPC_EXTR_W_DSP =3D 0x38 | OPC_SPECIAL3, + OPC_DEXTR_W_DSP =3D 0x3C | OPC_SPECIAL3, +}; + +#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +/* MIPS DSP Load */ +enum { + OPC_LBUX =3D (0x06 << 6) | OPC_LX_DSP, + OPC_LHX =3D (0x04 << 6) | OPC_LX_DSP, + OPC_LWX =3D (0x00 << 6) | OPC_LX_DSP, + OPC_LDX =3D (0x08 << 6) | OPC_LX_DSP, +}; + +#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Arithmetic Sub-class */ + OPC_ADDQ_PH =3D (0x0A << 6) | OPC_ADDU_QB_DSP, + OPC_ADDQ_S_PH =3D (0x0E << 6) | OPC_ADDU_QB_DSP, + OPC_ADDQ_S_W =3D (0x16 << 6) | OPC_ADDU_QB_DSP, + OPC_ADDU_QB =3D (0x00 << 6) | OPC_ADDU_QB_DSP, + OPC_ADDU_S_QB =3D (0x04 << 6) | OPC_ADDU_QB_DSP, + OPC_ADDU_PH =3D (0x08 << 6) | OPC_ADDU_QB_DSP, + OPC_ADDU_S_PH =3D (0x0C << 6) | OPC_ADDU_QB_DSP, + OPC_SUBQ_PH =3D (0x0B << 6) | OPC_ADDU_QB_DSP, + OPC_SUBQ_S_PH =3D (0x0F << 6) | OPC_ADDU_QB_DSP, + OPC_SUBQ_S_W =3D (0x17 << 6) | OPC_ADDU_QB_DSP, + OPC_SUBU_QB =3D (0x01 << 6) | OPC_ADDU_QB_DSP, + OPC_SUBU_S_QB =3D (0x05 << 6) | OPC_ADDU_QB_DSP, + OPC_SUBU_PH =3D (0x09 << 6) | OPC_ADDU_QB_DSP, + OPC_SUBU_S_PH =3D (0x0D << 6) | OPC_ADDU_QB_DSP, + OPC_ADDSC =3D (0x10 << 6) | OPC_ADDU_QB_DSP, + OPC_ADDWC =3D (0x11 << 6) | OPC_ADDU_QB_DSP, + OPC_MODSUB =3D (0x12 << 6) | OPC_ADDU_QB_DSP, + OPC_RADDU_W_QB =3D (0x14 << 6) | OPC_ADDU_QB_DSP, + /* MIPS DSP Multiply Sub-class insns */ + OPC_MULEU_S_PH_QBL =3D (0x06 << 6) | OPC_ADDU_QB_DSP, + OPC_MULEU_S_PH_QBR =3D (0x07 << 6) | OPC_ADDU_QB_DSP, + OPC_MULQ_RS_PH =3D (0x1F << 6) | OPC_ADDU_QB_DSP, + OPC_MULEQ_S_W_PHL =3D (0x1C << 6) | OPC_ADDU_QB_DSP, + OPC_MULEQ_S_W_PHR =3D (0x1D << 6) | OPC_ADDU_QB_DSP, + OPC_MULQ_S_PH =3D (0x1E << 6) | OPC_ADDU_QB_DSP, +}; + +#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E +#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Arithmetic Sub-class */ + OPC_ADDUH_QB =3D (0x00 << 6) | OPC_ADDUH_QB_DSP, + OPC_ADDUH_R_QB =3D (0x02 << 6) | OPC_ADDUH_QB_DSP, + OPC_ADDQH_PH =3D (0x08 << 6) | OPC_ADDUH_QB_DSP, + OPC_ADDQH_R_PH =3D (0x0A << 6) | OPC_ADDUH_QB_DSP, + OPC_ADDQH_W =3D (0x10 << 6) | OPC_ADDUH_QB_DSP, + OPC_ADDQH_R_W =3D (0x12 << 6) | OPC_ADDUH_QB_DSP, + OPC_SUBUH_QB =3D (0x01 << 6) | OPC_ADDUH_QB_DSP, + OPC_SUBUH_R_QB =3D (0x03 << 6) | OPC_ADDUH_QB_DSP, + OPC_SUBQH_PH =3D (0x09 << 6) | OPC_ADDUH_QB_DSP, + OPC_SUBQH_R_PH =3D (0x0B << 6) | OPC_ADDUH_QB_DSP, + OPC_SUBQH_W =3D (0x11 << 6) | OPC_ADDUH_QB_DSP, + OPC_SUBQH_R_W =3D (0x13 << 6) | OPC_ADDUH_QB_DSP, + /* MIPS DSP Multiply Sub-class insns */ + OPC_MUL_PH =3D (0x0C << 6) | OPC_ADDUH_QB_DSP, + OPC_MUL_S_PH =3D (0x0E << 6) | OPC_ADDUH_QB_DSP, + OPC_MULQ_S_W =3D (0x16 << 6) | OPC_ADDUH_QB_DSP, + OPC_MULQ_RS_W =3D (0x17 << 6) | OPC_ADDUH_QB_DSP, +}; + +#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Arithmetic Sub-class */ + OPC_ABSQ_S_QB =3D (0x01 << 6) | OPC_ABSQ_S_PH_DSP, + OPC_ABSQ_S_PH =3D (0x09 << 6) | OPC_ABSQ_S_PH_DSP, + OPC_ABSQ_S_W =3D (0x11 << 6) | OPC_ABSQ_S_PH_DSP, + OPC_PRECEQ_W_PHL =3D (0x0C << 6) | OPC_ABSQ_S_PH_DSP, + OPC_PRECEQ_W_PHR =3D (0x0D << 6) | OPC_ABSQ_S_PH_DSP, + OPC_PRECEQU_PH_QBL =3D (0x04 << 6) | OPC_ABSQ_S_PH_DSP, + OPC_PRECEQU_PH_QBR =3D (0x05 << 6) | OPC_ABSQ_S_PH_DSP, + OPC_PRECEQU_PH_QBLA =3D (0x06 << 6) | OPC_ABSQ_S_PH_DSP, + OPC_PRECEQU_PH_QBRA =3D (0x07 << 6) | OPC_ABSQ_S_PH_DSP, + OPC_PRECEU_PH_QBL =3D (0x1C << 6) | OPC_ABSQ_S_PH_DSP, + OPC_PRECEU_PH_QBR =3D (0x1D << 6) | OPC_ABSQ_S_PH_DSP, + OPC_PRECEU_PH_QBLA =3D (0x1E << 6) | OPC_ABSQ_S_PH_DSP, + OPC_PRECEU_PH_QBRA =3D (0x1F << 6) | OPC_ABSQ_S_PH_DSP, + /* DSP Bit/Manipulation Sub-class */ + OPC_BITREV =3D (0x1B << 6) | OPC_ABSQ_S_PH_DSP, + OPC_REPL_QB =3D (0x02 << 6) | OPC_ABSQ_S_PH_DSP, + OPC_REPLV_QB =3D (0x03 << 6) | OPC_ABSQ_S_PH_DSP, + OPC_REPL_PH =3D (0x0A << 6) | OPC_ABSQ_S_PH_DSP, + OPC_REPLV_PH =3D (0x0B << 6) | OPC_ABSQ_S_PH_DSP, +}; + +#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Arithmetic Sub-class */ + OPC_PRECR_QB_PH =3D (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PRECRQ_QB_PH =3D (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PRECR_SRA_PH_W =3D (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PRECR_SRA_R_PH_W =3D (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PRECRQ_PH_W =3D (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PRECRQ_RS_PH_W =3D (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PRECRQU_S_QB_PH =3D (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, + /* DSP Compare-Pick Sub-class */ + OPC_CMPU_EQ_QB =3D (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMPU_LT_QB =3D (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMPU_LE_QB =3D (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMPGU_EQ_QB =3D (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMPGU_LT_QB =3D (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMPGU_LE_QB =3D (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMPGDU_EQ_QB =3D (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMPGDU_LT_QB =3D (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMPGDU_LE_QB =3D (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMP_EQ_PH =3D (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMP_LT_PH =3D (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_CMP_LE_PH =3D (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PICK_QB =3D (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PICK_PH =3D (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, + OPC_PACKRL_PH =3D (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, +}; + +#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP GPR-Based Shift Sub-class */ + OPC_SHLL_QB =3D (0x00 << 6) | OPC_SHLL_QB_DSP, + OPC_SHLLV_QB =3D (0x02 << 6) | OPC_SHLL_QB_DSP, + OPC_SHLL_PH =3D (0x08 << 6) | OPC_SHLL_QB_DSP, + OPC_SHLLV_PH =3D (0x0A << 6) | OPC_SHLL_QB_DSP, + OPC_SHLL_S_PH =3D (0x0C << 6) | OPC_SHLL_QB_DSP, + OPC_SHLLV_S_PH =3D (0x0E << 6) | OPC_SHLL_QB_DSP, + OPC_SHLL_S_W =3D (0x14 << 6) | OPC_SHLL_QB_DSP, + OPC_SHLLV_S_W =3D (0x16 << 6) | OPC_SHLL_QB_DSP, + OPC_SHRL_QB =3D (0x01 << 6) | OPC_SHLL_QB_DSP, + OPC_SHRLV_QB =3D (0x03 << 6) | OPC_SHLL_QB_DSP, + OPC_SHRL_PH =3D (0x19 << 6) | OPC_SHLL_QB_DSP, + OPC_SHRLV_PH =3D (0x1B << 6) | OPC_SHLL_QB_DSP, + OPC_SHRA_QB =3D (0x04 << 6) | OPC_SHLL_QB_DSP, + OPC_SHRA_R_QB =3D (0x05 << 6) | OPC_SHLL_QB_DSP, + OPC_SHRAV_QB =3D (0x06 << 6) | OPC_SHLL_QB_DSP, + OPC_SHRAV_R_QB =3D (0x07 << 6) | OPC_SHLL_QB_DSP, + OPC_SHRA_PH =3D (0x09 << 6) | OPC_SHLL_QB_DSP, + OPC_SHRAV_PH =3D (0x0B << 6) | OPC_SHLL_QB_DSP, + OPC_SHRA_R_PH =3D (0x0D << 6) | OPC_SHLL_QB_DSP, + OPC_SHRAV_R_PH =3D (0x0F << 6) | OPC_SHLL_QB_DSP, + OPC_SHRA_R_W =3D (0x15 << 6) | OPC_SHLL_QB_DSP, + OPC_SHRAV_R_W =3D (0x17 << 6) | OPC_SHLL_QB_DSP, +}; + +#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Multiply Sub-class insns */ + OPC_DPAU_H_QBL =3D (0x03 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPAU_H_QBR =3D (0x07 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPSU_H_QBL =3D (0x0B << 6) | OPC_DPA_W_PH_DSP, + OPC_DPSU_H_QBR =3D (0x0F << 6) | OPC_DPA_W_PH_DSP, + OPC_DPA_W_PH =3D (0x00 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPAX_W_PH =3D (0x08 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPAQ_S_W_PH =3D (0x04 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPAQX_S_W_PH =3D (0x18 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPAQX_SA_W_PH =3D (0x1A << 6) | OPC_DPA_W_PH_DSP, + OPC_DPS_W_PH =3D (0x01 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPSX_W_PH =3D (0x09 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPSQ_S_W_PH =3D (0x05 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPSQX_S_W_PH =3D (0x19 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPSQX_SA_W_PH =3D (0x1B << 6) | OPC_DPA_W_PH_DSP, + OPC_MULSAQ_S_W_PH =3D (0x06 << 6) | OPC_DPA_W_PH_DSP, + OPC_DPAQ_SA_L_W =3D (0x0C << 6) | OPC_DPA_W_PH_DSP, + OPC_DPSQ_SA_L_W =3D (0x0D << 6) | OPC_DPA_W_PH_DSP, + OPC_MAQ_S_W_PHL =3D (0x14 << 6) | OPC_DPA_W_PH_DSP, + OPC_MAQ_S_W_PHR =3D (0x16 << 6) | OPC_DPA_W_PH_DSP, + OPC_MAQ_SA_W_PHL =3D (0x10 << 6) | OPC_DPA_W_PH_DSP, + OPC_MAQ_SA_W_PHR =3D (0x12 << 6) | OPC_DPA_W_PH_DSP, + OPC_MULSA_W_PH =3D (0x02 << 6) | OPC_DPA_W_PH_DSP, +}; + +#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* DSP Bit/Manipulation Sub-class */ + OPC_INSV =3D (0x00 << 6) | OPC_INSV_DSP, +}; + +#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Append Sub-class */ + OPC_APPEND =3D (0x00 << 6) | OPC_APPEND_DSP, + OPC_PREPEND =3D (0x01 << 6) | OPC_APPEND_DSP, + OPC_BALIGN =3D (0x10 << 6) | OPC_APPEND_DSP, +}; + +#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Accumulator and DSPControl Access Sub-class */ + OPC_EXTR_W =3D (0x00 << 6) | OPC_EXTR_W_DSP, + OPC_EXTR_R_W =3D (0x04 << 6) | OPC_EXTR_W_DSP, + OPC_EXTR_RS_W =3D (0x06 << 6) | OPC_EXTR_W_DSP, + OPC_EXTR_S_H =3D (0x0E << 6) | OPC_EXTR_W_DSP, + OPC_EXTRV_S_H =3D (0x0F << 6) | OPC_EXTR_W_DSP, + OPC_EXTRV_W =3D (0x01 << 6) | OPC_EXTR_W_DSP, + OPC_EXTRV_R_W =3D (0x05 << 6) | OPC_EXTR_W_DSP, + OPC_EXTRV_RS_W =3D (0x07 << 6) | OPC_EXTR_W_DSP, + OPC_EXTP =3D (0x02 << 6) | OPC_EXTR_W_DSP, + OPC_EXTPV =3D (0x03 << 6) | OPC_EXTR_W_DSP, + OPC_EXTPDP =3D (0x0A << 6) | OPC_EXTR_W_DSP, + OPC_EXTPDPV =3D (0x0B << 6) | OPC_EXTR_W_DSP, + OPC_SHILO =3D (0x1A << 6) | OPC_EXTR_W_DSP, + OPC_SHILOV =3D (0x1B << 6) | OPC_EXTR_W_DSP, + OPC_MTHLIP =3D (0x1F << 6) | OPC_EXTR_W_DSP, + OPC_WRDSP =3D (0x13 << 6) | OPC_EXTR_W_DSP, + OPC_RDDSP =3D (0x12 << 6) | OPC_EXTR_W_DSP, +}; + +#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Arithmetic Sub-class */ + OPC_PRECEQ_L_PWL =3D (0x14 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEQ_L_PWR =3D (0x15 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEQ_PW_QHL =3D (0x0C << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEQ_PW_QHR =3D (0x0D << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEQ_PW_QHLA =3D (0x0E << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEQ_PW_QHRA =3D (0x0F << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEQU_QH_OBL =3D (0x04 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEQU_QH_OBR =3D (0x05 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEQU_QH_OBLA =3D (0x06 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEQU_QH_OBRA =3D (0x07 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEU_QH_OBL =3D (0x1C << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEU_QH_OBR =3D (0x1D << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEU_QH_OBLA =3D (0x1E << 6) | OPC_ABSQ_S_QH_DSP, + OPC_PRECEU_QH_OBRA =3D (0x1F << 6) | OPC_ABSQ_S_QH_DSP, + OPC_ABSQ_S_OB =3D (0x01 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_ABSQ_S_PW =3D (0x11 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_ABSQ_S_QH =3D (0x09 << 6) | OPC_ABSQ_S_QH_DSP, + /* DSP Bit/Manipulation Sub-class */ + OPC_REPL_OB =3D (0x02 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_REPL_PW =3D (0x12 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_REPL_QH =3D (0x0A << 6) | OPC_ABSQ_S_QH_DSP, + OPC_REPLV_OB =3D (0x03 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_REPLV_PW =3D (0x13 << 6) | OPC_ABSQ_S_QH_DSP, + OPC_REPLV_QH =3D (0x0B << 6) | OPC_ABSQ_S_QH_DSP, +}; + +#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Multiply Sub-class insns */ + OPC_MULEQ_S_PW_QHL =3D (0x1C << 6) | OPC_ADDU_OB_DSP, + OPC_MULEQ_S_PW_QHR =3D (0x1D << 6) | OPC_ADDU_OB_DSP, + OPC_MULEU_S_QH_OBL =3D (0x06 << 6) | OPC_ADDU_OB_DSP, + OPC_MULEU_S_QH_OBR =3D (0x07 << 6) | OPC_ADDU_OB_DSP, + OPC_MULQ_RS_QH =3D (0x1F << 6) | OPC_ADDU_OB_DSP, + /* MIPS DSP Arithmetic Sub-class */ + OPC_RADDU_L_OB =3D (0x14 << 6) | OPC_ADDU_OB_DSP, + OPC_SUBQ_PW =3D (0x13 << 6) | OPC_ADDU_OB_DSP, + OPC_SUBQ_S_PW =3D (0x17 << 6) | OPC_ADDU_OB_DSP, + OPC_SUBQ_QH =3D (0x0B << 6) | OPC_ADDU_OB_DSP, + OPC_SUBQ_S_QH =3D (0x0F << 6) | OPC_ADDU_OB_DSP, + OPC_SUBU_OB =3D (0x01 << 6) | OPC_ADDU_OB_DSP, + OPC_SUBU_S_OB =3D (0x05 << 6) | OPC_ADDU_OB_DSP, + OPC_SUBU_QH =3D (0x09 << 6) | OPC_ADDU_OB_DSP, + OPC_SUBU_S_QH =3D (0x0D << 6) | OPC_ADDU_OB_DSP, + OPC_SUBUH_OB =3D (0x19 << 6) | OPC_ADDU_OB_DSP, + OPC_SUBUH_R_OB =3D (0x1B << 6) | OPC_ADDU_OB_DSP, + OPC_ADDQ_PW =3D (0x12 << 6) | OPC_ADDU_OB_DSP, + OPC_ADDQ_S_PW =3D (0x16 << 6) | OPC_ADDU_OB_DSP, + OPC_ADDQ_QH =3D (0x0A << 6) | OPC_ADDU_OB_DSP, + OPC_ADDQ_S_QH =3D (0x0E << 6) | OPC_ADDU_OB_DSP, + OPC_ADDU_OB =3D (0x00 << 6) | OPC_ADDU_OB_DSP, + OPC_ADDU_S_OB =3D (0x04 << 6) | OPC_ADDU_OB_DSP, + OPC_ADDU_QH =3D (0x08 << 6) | OPC_ADDU_OB_DSP, + OPC_ADDU_S_QH =3D (0x0C << 6) | OPC_ADDU_OB_DSP, + OPC_ADDUH_OB =3D (0x18 << 6) | OPC_ADDU_OB_DSP, + OPC_ADDUH_R_OB =3D (0x1A << 6) | OPC_ADDU_OB_DSP, +}; + +#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* DSP Compare-Pick Sub-class */ + OPC_CMP_EQ_PW =3D (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMP_LT_PW =3D (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMP_LE_PW =3D (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMP_EQ_QH =3D (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMP_LT_QH =3D (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMP_LE_QH =3D (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMPGDU_EQ_OB =3D (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMPGDU_LT_OB =3D (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMPGDU_LE_OB =3D (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMPGU_EQ_OB =3D (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMPGU_LT_OB =3D (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMPGU_LE_OB =3D (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMPU_EQ_OB =3D (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMPU_LT_OB =3D (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_CMPU_LE_OB =3D (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PACKRL_PW =3D (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PICK_OB =3D (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PICK_PW =3D (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PICK_QH =3D (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, + /* MIPS DSP Arithmetic Sub-class */ + OPC_PRECR_OB_QH =3D (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PRECR_SRA_QH_PW =3D (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PRECR_SRA_R_QH_PW =3D (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PRECRQ_OB_QH =3D (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PRECRQ_PW_L =3D (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PRECRQ_QH_PW =3D (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PRECRQ_RS_QH_PW =3D (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, + OPC_PRECRQU_S_OB_QH =3D (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, +}; + +#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* DSP Append Sub-class */ + OPC_DAPPEND =3D (0x00 << 6) | OPC_DAPPEND_DSP, + OPC_PREPENDD =3D (0x03 << 6) | OPC_DAPPEND_DSP, + OPC_PREPENDW =3D (0x01 << 6) | OPC_DAPPEND_DSP, + OPC_DBALIGN =3D (0x10 << 6) | OPC_DAPPEND_DSP, +}; + +#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Accumulator and DSPControl Access Sub-class */ + OPC_DMTHLIP =3D (0x1F << 6) | OPC_DEXTR_W_DSP, + OPC_DSHILO =3D (0x1A << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTP =3D (0x02 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTPDP =3D (0x0A << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTPDPV =3D (0x0B << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTPV =3D (0x03 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTR_L =3D (0x10 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTR_R_L =3D (0x14 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTR_RS_L =3D (0x16 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTR_W =3D (0x00 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTR_R_W =3D (0x04 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTR_RS_W =3D (0x06 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTR_S_H =3D (0x0E << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTRV_L =3D (0x11 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTRV_R_L =3D (0x15 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTRV_RS_L =3D (0x17 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTRV_S_H =3D (0x0F << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTRV_W =3D (0x01 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTRV_R_W =3D (0x05 << 6) | OPC_DEXTR_W_DSP, + OPC_DEXTRV_RS_W =3D (0x07 << 6) | OPC_DEXTR_W_DSP, + OPC_DSHILOV =3D (0x1B << 6) | OPC_DEXTR_W_DSP, +}; + +#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* DSP Bit/Manipulation Sub-class */ + OPC_DINSV =3D (0x00 << 6) | OPC_DINSV_DSP, +}; + +#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP Multiply Sub-class insns */ + OPC_DMADD =3D (0x19 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DMADDU =3D (0x1D << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DMSUB =3D (0x1B << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DMSUBU =3D (0x1F << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DPA_W_QH =3D (0x00 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DPAQ_S_W_QH =3D (0x04 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DPAQ_SA_L_PW =3D (0x0C << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DPAU_H_OBL =3D (0x03 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DPAU_H_OBR =3D (0x07 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DPS_W_QH =3D (0x01 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DPSQ_S_W_QH =3D (0x05 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DPSQ_SA_L_PW =3D (0x0D << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DPSU_H_OBL =3D (0x0B << 6) | OPC_DPAQ_W_QH_DSP, + OPC_DPSU_H_OBR =3D (0x0F << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MAQ_S_L_PWL =3D (0x1C << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MAQ_S_L_PWR =3D (0x1E << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MAQ_S_W_QHLL =3D (0x14 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MAQ_SA_W_QHLL =3D (0x10 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MAQ_S_W_QHLR =3D (0x15 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MAQ_SA_W_QHLR =3D (0x11 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MAQ_S_W_QHRL =3D (0x16 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MAQ_SA_W_QHRL =3D (0x12 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MAQ_S_W_QHRR =3D (0x17 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MAQ_SA_W_QHRR =3D (0x13 << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MULSAQ_S_L_PW =3D (0x0E << 6) | OPC_DPAQ_W_QH_DSP, + OPC_MULSAQ_S_W_QH =3D (0x06 << 6) | OPC_DPAQ_W_QH_DSP, +}; + +#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) +enum { + /* MIPS DSP GPR-Based Shift Sub-class */ + OPC_SHLL_PW =3D (0x10 << 6) | OPC_SHLL_OB_DSP, + OPC_SHLL_S_PW =3D (0x14 << 6) | OPC_SHLL_OB_DSP, + OPC_SHLLV_OB =3D (0x02 << 6) | OPC_SHLL_OB_DSP, + OPC_SHLLV_PW =3D (0x12 << 6) | OPC_SHLL_OB_DSP, + OPC_SHLLV_S_PW =3D (0x16 << 6) | OPC_SHLL_OB_DSP, + OPC_SHLLV_QH =3D (0x0A << 6) | OPC_SHLL_OB_DSP, + OPC_SHLLV_S_QH =3D (0x0E << 6) | OPC_SHLL_OB_DSP, + OPC_SHRA_PW =3D (0x11 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRA_R_PW =3D (0x15 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRAV_OB =3D (0x06 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRAV_R_OB =3D (0x07 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRAV_PW =3D (0x13 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRAV_R_PW =3D (0x17 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRAV_QH =3D (0x0B << 6) | OPC_SHLL_OB_DSP, + OPC_SHRAV_R_QH =3D (0x0F << 6) | OPC_SHLL_OB_DSP, + OPC_SHRLV_OB =3D (0x03 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRLV_QH =3D (0x1B << 6) | OPC_SHLL_OB_DSP, + OPC_SHLL_OB =3D (0x00 << 6) | OPC_SHLL_OB_DSP, + OPC_SHLL_QH =3D (0x08 << 6) | OPC_SHLL_OB_DSP, + OPC_SHLL_S_QH =3D (0x0C << 6) | OPC_SHLL_OB_DSP, + OPC_SHRA_OB =3D (0x04 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRA_R_OB =3D (0x05 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRA_QH =3D (0x09 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRA_R_QH =3D (0x0D << 6) | OPC_SHLL_OB_DSP, + OPC_SHRL_OB =3D (0x01 << 6) | OPC_SHLL_OB_DSP, + OPC_SHRL_QH =3D (0x19 << 6) | OPC_SHLL_OB_DSP, +}; + +/* + * Verify that the processor is running with DSP instructions enabled. + * This is enabled by CP0 Status register MX(24) bit. + */ +static inline void check_dsp(DisasContext *ctx) +{ + if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { + if (ctx->insn_flags & ASE_DSP) { + generate_exception_end(ctx, EXCP_DSPDIS); + } else { + generate_exception_end(ctx, EXCP_RI); + } + } +} + +static inline void check_dsp_r2(DisasContext *ctx) +{ + if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { + if (ctx->insn_flags & ASE_DSP) { + generate_exception_end(ctx, EXCP_DSPDIS); + } else { + generate_exception_end(ctx, EXCP_RI); + } + } +} + +static inline void check_dsp_r3(DisasContext *ctx) +{ + if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { + if (ctx->insn_flags & ASE_DSP) { + generate_exception_end(ctx, EXCP_DSPDIS); + } else { + generate_exception_end(ctx, EXCP_RI); + } + } +} + +static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc, + int rd, int base, int offset) +{ + TCGv t0; + + check_dsp(ctx); + t0 =3D tcg_temp_new(); + + if (base =3D=3D 0) { + gen_load_gpr(t0, offset); + } else if (offset =3D=3D 0) { + gen_load_gpr(t0, base); + } else { + gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); + } + + switch (opc) { + case OPC_LBUX: + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); + gen_store_gpr(t0, rd); + break; + case OPC_LHX: + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW); + gen_store_gpr(t0, rd); + break; + case OPC_LWX: + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); + gen_store_gpr(t0, rd); + break; +#if defined(TARGET_MIPS64) + case OPC_LDX: + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); + gen_store_gpr(t0, rd); + break; +#endif + } + tcg_temp_free(t0); +} + +static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op= 2, + int ret, int v1, int v2) +{ + TCGv v1_t; + TCGv v2_t; + + if (ret =3D=3D 0) { + /* Treat as NOP. */ + return; + } + + v1_t =3D tcg_temp_new(); + v2_t =3D tcg_temp_new(); + + gen_load_gpr(v1_t, v1); + gen_load_gpr(v2_t, v2); + + switch (op1) { + /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */ + case OPC_MULT_G_2E: + check_dsp_r2(ctx); + switch (op2) { + case OPC_ADDUH_QB: + gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_ADDUH_R_QB: + gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_ADDQH_PH: + gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_ADDQH_R_PH: + gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_ADDQH_W: + gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_ADDQH_R_W: + gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SUBUH_QB: + gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SUBUH_R_QB: + gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SUBQH_PH: + gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SUBQH_R_PH: + gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SUBQH_W: + gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SUBQH_R_W: + gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); + break; + } + break; + case OPC_ABSQ_S_PH_DSP: + switch (op2) { + case OPC_ABSQ_S_QB: + check_dsp_r2(ctx); + gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env); + break; + case OPC_ABSQ_S_PH: + check_dsp(ctx); + gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env); + break; + case OPC_ABSQ_S_W: + check_dsp(ctx); + gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env); + break; + case OPC_PRECEQ_W_PHL: + check_dsp(ctx); + tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); + tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); + break; + case OPC_PRECEQ_W_PHR: + check_dsp(ctx); + tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); + tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); + tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); + break; + case OPC_PRECEQU_PH_QBL: + check_dsp(ctx); + gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEQU_PH_QBR: + check_dsp(ctx); + gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEQU_PH_QBLA: + check_dsp(ctx); + gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEQU_PH_QBRA: + check_dsp(ctx); + gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEU_PH_QBL: + check_dsp(ctx); + gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEU_PH_QBR: + check_dsp(ctx); + gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEU_PH_QBLA: + check_dsp(ctx); + gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEU_PH_QBRA: + check_dsp(ctx); + gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); + break; + } + break; + case OPC_ADDU_QB_DSP: + switch (op2) { + case OPC_ADDQ_PH: + check_dsp(ctx); + gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDQ_S_PH: + check_dsp(ctx); + gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDQ_S_W: + check_dsp(ctx); + gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDU_QB: + check_dsp(ctx); + gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDU_S_QB: + check_dsp(ctx); + gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDU_PH: + check_dsp_r2(ctx); + gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDU_S_PH: + check_dsp_r2(ctx); + gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBQ_PH: + check_dsp(ctx); + gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBQ_S_PH: + check_dsp(ctx); + gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBQ_S_W: + check_dsp(ctx); + gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBU_QB: + check_dsp(ctx); + gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBU_S_QB: + check_dsp(ctx); + gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBU_PH: + check_dsp_r2(ctx); + gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBU_S_PH: + check_dsp_r2(ctx); + gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDSC: + check_dsp(ctx); + gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDWC: + check_dsp(ctx); + gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MODSUB: + check_dsp(ctx); + gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_RADDU_W_QB: + check_dsp(ctx); + gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); + break; + } + break; + case OPC_CMPU_EQ_QB_DSP: + switch (op2) { + case OPC_PRECR_QB_PH: + check_dsp_r2(ctx); + gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_PRECRQ_QB_PH: + check_dsp(ctx); + gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_PRECR_SRA_PH_W: + check_dsp_r2(ctx); + { + TCGv_i32 sa_t =3D tcg_const_i32(v2); + gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, + cpu_gpr[ret]); + tcg_temp_free_i32(sa_t); + break; + } + case OPC_PRECR_SRA_R_PH_W: + check_dsp_r2(ctx); + { + TCGv_i32 sa_t =3D tcg_const_i32(v2); + gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, + cpu_gpr[ret]); + tcg_temp_free_i32(sa_t); + break; + } + case OPC_PRECRQ_PH_W: + check_dsp(ctx); + gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_PRECRQ_RS_PH_W: + check_dsp(ctx); + gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_PRECRQU_S_QB_PH: + check_dsp(ctx); + gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + } + break; +#ifdef TARGET_MIPS64 + case OPC_ABSQ_S_QH_DSP: + switch (op2) { + case OPC_PRECEQ_L_PWL: + check_dsp(ctx); + tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); + break; + case OPC_PRECEQ_L_PWR: + check_dsp(ctx); + tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); + break; + case OPC_PRECEQ_PW_QHL: + check_dsp(ctx); + gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEQ_PW_QHR: + check_dsp(ctx); + gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEQ_PW_QHLA: + check_dsp(ctx); + gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEQ_PW_QHRA: + check_dsp(ctx); + gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEQU_QH_OBL: + check_dsp(ctx); + gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEQU_QH_OBR: + check_dsp(ctx); + gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEQU_QH_OBLA: + check_dsp(ctx); + gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEQU_QH_OBRA: + check_dsp(ctx); + gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEU_QH_OBL: + check_dsp(ctx); + gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEU_QH_OBR: + check_dsp(ctx); + gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEU_QH_OBLA: + check_dsp(ctx); + gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); + break; + case OPC_PRECEU_QH_OBRA: + check_dsp(ctx); + gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); + break; + case OPC_ABSQ_S_OB: + check_dsp_r2(ctx); + gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env); + break; + case OPC_ABSQ_S_PW: + check_dsp(ctx); + gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env); + break; + case OPC_ABSQ_S_QH: + check_dsp(ctx); + gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env); + break; + } + break; + case OPC_ADDU_OB_DSP: + switch (op2) { + case OPC_RADDU_L_OB: + check_dsp(ctx); + gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); + break; + case OPC_SUBQ_PW: + check_dsp(ctx); + gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBQ_S_PW: + check_dsp(ctx); + gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBQ_QH: + check_dsp(ctx); + gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBQ_S_QH: + check_dsp(ctx); + gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBU_OB: + check_dsp(ctx); + gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBU_S_OB: + check_dsp(ctx); + gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBU_QH: + check_dsp_r2(ctx); + gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBU_S_QH: + check_dsp_r2(ctx); + gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SUBUH_OB: + check_dsp_r2(ctx); + gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SUBUH_R_OB: + check_dsp_r2(ctx); + gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_ADDQ_PW: + check_dsp(ctx); + gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDQ_S_PW: + check_dsp(ctx); + gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDQ_QH: + check_dsp(ctx); + gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDQ_S_QH: + check_dsp(ctx); + gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDU_OB: + check_dsp(ctx); + gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDU_S_OB: + check_dsp(ctx); + gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDU_QH: + check_dsp_r2(ctx); + gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDU_S_QH: + check_dsp_r2(ctx); + gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_ADDUH_OB: + check_dsp_r2(ctx); + gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_ADDUH_R_OB: + check_dsp_r2(ctx); + gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); + break; + } + break; + case OPC_CMPU_EQ_OB_DSP: + switch (op2) { + case OPC_PRECR_OB_QH: + check_dsp_r2(ctx); + gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_PRECR_SRA_QH_PW: + check_dsp_r2(ctx); + { + TCGv_i32 ret_t =3D tcg_const_i32(ret); + gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); + tcg_temp_free_i32(ret_t); + break; + } + case OPC_PRECR_SRA_R_QH_PW: + check_dsp_r2(ctx); + { + TCGv_i32 sa_v =3D tcg_const_i32(ret); + gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); + tcg_temp_free_i32(sa_v); + break; + } + case OPC_PRECRQ_OB_QH: + check_dsp(ctx); + gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_PRECRQ_PW_L: + check_dsp(ctx); + gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_PRECRQ_QH_PW: + check_dsp(ctx); + gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_PRECRQ_RS_QH_PW: + check_dsp(ctx); + gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_PRECRQU_S_OB_QH: + check_dsp(ctx); + gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + } + break; +#endif + } + + tcg_temp_free(v1_t); + tcg_temp_free(v2_t); +} + +static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, + int ret, int v1, int v2) +{ + uint32_t op2; + TCGv t0; + TCGv v1_t; + TCGv v2_t; + + if (ret =3D=3D 0) { + /* Treat as NOP. */ + return; + } + + t0 =3D tcg_temp_new(); + v1_t =3D tcg_temp_new(); + v2_t =3D tcg_temp_new(); + + tcg_gen_movi_tl(t0, v1); + gen_load_gpr(v1_t, v1); + gen_load_gpr(v2_t, v2); + + switch (opc) { + case OPC_SHLL_QB_DSP: + { + op2 =3D MASK_SHLL_QB(ctx->opcode); + switch (op2) { + case OPC_SHLL_QB: + check_dsp(ctx); + gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env); + break; + case OPC_SHLLV_QB: + check_dsp(ctx); + gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SHLL_PH: + check_dsp(ctx); + gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env); + break; + case OPC_SHLLV_PH: + check_dsp(ctx); + gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SHLL_S_PH: + check_dsp(ctx); + gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env); + break; + case OPC_SHLLV_S_PH: + check_dsp(ctx); + gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SHLL_S_W: + check_dsp(ctx); + gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env); + break; + case OPC_SHLLV_S_W: + check_dsp(ctx); + gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_SHRL_QB: + check_dsp(ctx); + gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); + break; + case OPC_SHRLV_QB: + check_dsp(ctx); + gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SHRL_PH: + check_dsp_r2(ctx); + gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); + break; + case OPC_SHRLV_PH: + check_dsp_r2(ctx); + gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SHRA_QB: + check_dsp_r2(ctx); + gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); + break; + case OPC_SHRA_R_QB: + check_dsp_r2(ctx); + gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); + break; + case OPC_SHRAV_QB: + check_dsp_r2(ctx); + gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SHRAV_R_QB: + check_dsp_r2(ctx); + gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SHRA_PH: + check_dsp(ctx); + gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); + break; + case OPC_SHRA_R_PH: + check_dsp(ctx); + gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); + break; + case OPC_SHRAV_PH: + check_dsp(ctx); + gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SHRAV_R_PH: + check_dsp(ctx); + gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_SHRA_R_W: + check_dsp(ctx); + gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); + break; + case OPC_SHRAV_R_W: + check_dsp(ctx); + gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); + break; + default: /* Invalid */ + MIPS_INVAL("MASK SHLL.QB"); + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + } +#ifdef TARGET_MIPS64 + case OPC_SHLL_OB_DSP: + op2 =3D MASK_SHLL_OB(ctx->opcode); + switch (op2) { + case OPC_SHLL_PW: + check_dsp(ctx); + gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env); + break; + case OPC_SHLLV_PW: + check_dsp(ctx); + gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); + break; + case OPC_SHLL_S_PW: + check_dsp(ctx); + gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env); + break; + case OPC_SHLLV_S_PW: + check_dsp(ctx); + gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); + break; + case OPC_SHLL_OB: + check_dsp(ctx); + gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env); + break; + case OPC_SHLLV_OB: + check_dsp(ctx); + gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env); + break; + case OPC_SHLL_QH: + check_dsp(ctx); + gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env); + break; + case OPC_SHLLV_QH: + check_dsp(ctx); + gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); + break; + case OPC_SHLL_S_QH: + check_dsp(ctx); + gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env); + break; + case OPC_SHLLV_S_QH: + check_dsp(ctx); + gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); + break; + case OPC_SHRA_OB: + check_dsp_r2(ctx); + gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); + break; + case OPC_SHRAV_OB: + check_dsp_r2(ctx); + gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); + break; + case OPC_SHRA_R_OB: + check_dsp_r2(ctx); + gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); + break; + case OPC_SHRAV_R_OB: + check_dsp_r2(ctx); + gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); + break; + case OPC_SHRA_PW: + check_dsp(ctx); + gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); + break; + case OPC_SHRAV_PW: + check_dsp(ctx); + gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); + break; + case OPC_SHRA_R_PW: + check_dsp(ctx); + gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); + break; + case OPC_SHRAV_R_PW: + check_dsp(ctx); + gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); + break; + case OPC_SHRA_QH: + check_dsp(ctx); + gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); + break; + case OPC_SHRAV_QH: + check_dsp(ctx); + gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); + break; + case OPC_SHRA_R_QH: + check_dsp(ctx); + gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); + break; + case OPC_SHRAV_R_QH: + check_dsp(ctx); + gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); + break; + case OPC_SHRL_OB: + check_dsp(ctx); + gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); + break; + case OPC_SHRLV_OB: + check_dsp(ctx); + gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); + break; + case OPC_SHRL_QH: + check_dsp_r2(ctx); + gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); + break; + case OPC_SHRLV_QH: + check_dsp_r2(ctx); + gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); + break; + default: /* Invalid */ + MIPS_INVAL("MASK SHLL.OB"); + generate_exception_end(ctx, EXCP_RI); + break; + } + break; +#endif + } + + tcg_temp_free(t0); + tcg_temp_free(v1_t); + tcg_temp_free(v2_t); +} + +static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t= op2, + int ret, int v1, int v2, int check_ret) +{ + TCGv_i32 t0; + TCGv v1_t; + TCGv v2_t; + + if ((ret =3D=3D 0) && (check_ret =3D=3D 1)) { + /* Treat as NOP. */ + return; + } + + t0 =3D tcg_temp_new_i32(); + v1_t =3D tcg_temp_new(); + v2_t =3D tcg_temp_new(); + + tcg_gen_movi_i32(t0, ret); + gen_load_gpr(v1_t, v1); + gen_load_gpr(v2_t, v2); + + switch (op1) { + /* + * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have + * the same mask and op1. + */ + case OPC_MULT_G_2E: + check_dsp_r2(ctx); + switch (op2) { + case OPC_MUL_PH: + gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MUL_S_PH: + gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULQ_S_W: + gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULQ_RS_W: + gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + } + break; + case OPC_DPA_W_PH_DSP: + switch (op2) { + case OPC_DPAU_H_QBL: + check_dsp(ctx); + gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPAU_H_QBR: + check_dsp(ctx); + gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPSU_H_QBL: + check_dsp(ctx); + gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPSU_H_QBR: + check_dsp(ctx); + gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPA_W_PH: + check_dsp_r2(ctx); + gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPAX_W_PH: + check_dsp_r2(ctx); + gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPAQ_S_W_PH: + check_dsp(ctx); + gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPAQX_S_W_PH: + check_dsp_r2(ctx); + gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPAQX_SA_W_PH: + check_dsp_r2(ctx); + gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPS_W_PH: + check_dsp_r2(ctx); + gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPSX_W_PH: + check_dsp_r2(ctx); + gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPSQ_S_W_PH: + check_dsp(ctx); + gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPSQX_S_W_PH: + check_dsp_r2(ctx); + gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPSQX_SA_W_PH: + check_dsp_r2(ctx); + gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_MULSAQ_S_W_PH: + check_dsp(ctx); + gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPAQ_SA_L_W: + check_dsp(ctx); + gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env); + break; + case OPC_DPSQ_SA_L_W: + check_dsp(ctx); + gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env); + break; + case OPC_MAQ_S_W_PHL: + check_dsp(ctx); + gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env); + break; + case OPC_MAQ_S_W_PHR: + check_dsp(ctx); + gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env); + break; + case OPC_MAQ_SA_W_PHL: + check_dsp(ctx); + gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env); + break; + case OPC_MAQ_SA_W_PHR: + check_dsp(ctx); + gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env); + break; + case OPC_MULSA_W_PH: + check_dsp_r2(ctx); + gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env); + break; + } + break; +#ifdef TARGET_MIPS64 + case OPC_DPAQ_W_QH_DSP: + { + int ac =3D ret & 0x03; + tcg_gen_movi_i32(t0, ac); + + switch (op2) { + case OPC_DMADD: + check_dsp(ctx); + gen_helper_dmadd(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DMADDU: + check_dsp(ctx); + gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DMSUB: + check_dsp(ctx); + gen_helper_dmsub(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DMSUBU: + check_dsp(ctx); + gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DPA_W_QH: + check_dsp_r2(ctx); + gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DPAQ_S_W_QH: + check_dsp(ctx); + gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DPAQ_SA_L_PW: + check_dsp(ctx); + gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DPAU_H_OBL: + check_dsp(ctx); + gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DPAU_H_OBR: + check_dsp(ctx); + gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DPS_W_QH: + check_dsp_r2(ctx); + gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DPSQ_S_W_QH: + check_dsp(ctx); + gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DPSQ_SA_L_PW: + check_dsp(ctx); + gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DPSU_H_OBL: + check_dsp(ctx); + gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env); + break; + case OPC_DPSU_H_OBR: + check_dsp(ctx); + gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MAQ_S_L_PWL: + check_dsp(ctx); + gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MAQ_S_L_PWR: + check_dsp(ctx); + gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MAQ_S_W_QHLL: + check_dsp(ctx); + gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MAQ_SA_W_QHLL: + check_dsp(ctx); + gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MAQ_S_W_QHLR: + check_dsp(ctx); + gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MAQ_SA_W_QHLR: + check_dsp(ctx); + gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MAQ_S_W_QHRL: + check_dsp(ctx); + gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MAQ_SA_W_QHRL: + check_dsp(ctx); + gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MAQ_S_W_QHRR: + check_dsp(ctx); + gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MAQ_SA_W_QHRR: + check_dsp(ctx); + gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MULSAQ_S_L_PW: + check_dsp(ctx); + gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env); + break; + case OPC_MULSAQ_S_W_QH: + check_dsp(ctx); + gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env); + break; + } + } + break; +#endif + case OPC_ADDU_QB_DSP: + switch (op2) { + case OPC_MULEU_S_PH_QBL: + check_dsp(ctx); + gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULEU_S_PH_QBR: + check_dsp(ctx); + gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULQ_RS_PH: + check_dsp(ctx); + gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULEQ_S_W_PHL: + check_dsp(ctx); + gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULEQ_S_W_PHR: + check_dsp(ctx); + gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULQ_S_PH: + check_dsp_r2(ctx); + gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + } + break; +#ifdef TARGET_MIPS64 + case OPC_ADDU_OB_DSP: + switch (op2) { + case OPC_MULEQ_S_PW_QHL: + check_dsp(ctx); + gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULEQ_S_PW_QHR: + check_dsp(ctx); + gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULEU_S_QH_OBL: + check_dsp(ctx); + gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULEU_S_QH_OBR: + check_dsp(ctx); + gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_MULQ_RS_QH: + check_dsp(ctx); + gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + } + break; +#endif + } + + tcg_temp_free_i32(t0); + tcg_temp_free(v1_t); + tcg_temp_free(v2_t); +} + +static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t = op2, + int ret, int val) +{ + int16_t imm; + TCGv t0; + TCGv val_t; + + if (ret =3D=3D 0) { + /* Treat as NOP. */ + return; + } + + t0 =3D tcg_temp_new(); + val_t =3D tcg_temp_new(); + gen_load_gpr(val_t, val); + + switch (op1) { + case OPC_ABSQ_S_PH_DSP: + switch (op2) { + case OPC_BITREV: + check_dsp(ctx); + gen_helper_bitrev(cpu_gpr[ret], val_t); + break; + case OPC_REPL_QB: + check_dsp(ctx); + { + target_long result; + imm =3D (ctx->opcode >> 16) & 0xFF; + result =3D (uint32_t)imm << 24 | + (uint32_t)imm << 16 | + (uint32_t)imm << 8 | + (uint32_t)imm; + result =3D (int32_t)result; + tcg_gen_movi_tl(cpu_gpr[ret], result); + } + break; + case OPC_REPLV_QB: + check_dsp(ctx); + tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); + tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); + tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); + tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); + tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); + tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); + break; + case OPC_REPL_PH: + check_dsp(ctx); + { + imm =3D (ctx->opcode >> 16) & 0x03FF; + imm =3D (int16_t)(imm << 6) >> 6; + tcg_gen_movi_tl(cpu_gpr[ret], \ + (target_long)((int32_t)imm << 16 | \ + (uint16_t)imm)); + } + break; + case OPC_REPLV_PH: + check_dsp(ctx); + tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); + tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); + tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); + tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); + break; + } + break; +#ifdef TARGET_MIPS64 + case OPC_ABSQ_S_QH_DSP: + switch (op2) { + case OPC_REPL_OB: + check_dsp(ctx); + { + target_long temp; + + imm =3D (ctx->opcode >> 16) & 0xFF; + temp =3D ((uint64_t)imm << 8) | (uint64_t)imm; + temp =3D (temp << 16) | temp; + temp =3D (temp << 32) | temp; + tcg_gen_movi_tl(cpu_gpr[ret], temp); + break; + } + case OPC_REPL_PW: + check_dsp(ctx); + { + target_long temp; + + imm =3D (ctx->opcode >> 16) & 0x03FF; + imm =3D (int16_t)(imm << 6) >> 6; + temp =3D ((target_long)imm << 32) \ + | ((target_long)imm & 0xFFFFFFFF); + tcg_gen_movi_tl(cpu_gpr[ret], temp); + break; + } + case OPC_REPL_QH: + check_dsp(ctx); + { + target_long temp; + + imm =3D (ctx->opcode >> 16) & 0x03FF; + imm =3D (int16_t)(imm << 6) >> 6; + + temp =3D ((uint64_t)(uint16_t)imm << 48) | + ((uint64_t)(uint16_t)imm << 32) | + ((uint64_t)(uint16_t)imm << 16) | + (uint64_t)(uint16_t)imm; + tcg_gen_movi_tl(cpu_gpr[ret], temp); + break; + } + case OPC_REPLV_OB: + check_dsp(ctx); + tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); + tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); + tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); + tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); + tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); + tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); + tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); + break; + case OPC_REPLV_PW: + check_dsp(ctx); + tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); + tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); + tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); + break; + case OPC_REPLV_QH: + check_dsp(ctx); + tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); + tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); + tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); + tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); + tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); + break; + } + break; +#endif + } + tcg_temp_free(t0); + tcg_temp_free(val_t); +} + +static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, + uint32_t op1, uint32_t op2, + int ret, int v1, int v2, int check_re= t) +{ + TCGv t1; + TCGv v1_t; + TCGv v2_t; + + if ((ret =3D=3D 0) && (check_ret =3D=3D 1)) { + /* Treat as NOP. */ + return; + } + + t1 =3D tcg_temp_new(); + v1_t =3D tcg_temp_new(); + v2_t =3D tcg_temp_new(); + + gen_load_gpr(v1_t, v1); + gen_load_gpr(v2_t, v2); + + switch (op1) { + case OPC_CMPU_EQ_QB_DSP: + switch (op2) { + case OPC_CMPU_EQ_QB: + check_dsp(ctx); + gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); + break; + case OPC_CMPU_LT_QB: + check_dsp(ctx); + gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); + break; + case OPC_CMPU_LE_QB: + check_dsp(ctx); + gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); + break; + case OPC_CMPGU_EQ_QB: + check_dsp(ctx); + gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_CMPGU_LT_QB: + check_dsp(ctx); + gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_CMPGU_LE_QB: + check_dsp(ctx); + gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_CMPGDU_EQ_QB: + check_dsp_r2(ctx); + gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); + tcg_gen_mov_tl(cpu_gpr[ret], t1); + tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); + tcg_gen_shli_tl(t1, t1, 24); + tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); + break; + case OPC_CMPGDU_LT_QB: + check_dsp_r2(ctx); + gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); + tcg_gen_mov_tl(cpu_gpr[ret], t1); + tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); + tcg_gen_shli_tl(t1, t1, 24); + tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); + break; + case OPC_CMPGDU_LE_QB: + check_dsp_r2(ctx); + gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); + tcg_gen_mov_tl(cpu_gpr[ret], t1); + tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); + tcg_gen_shli_tl(t1, t1, 24); + tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); + break; + case OPC_CMP_EQ_PH: + check_dsp(ctx); + gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); + break; + case OPC_CMP_LT_PH: + check_dsp(ctx); + gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); + break; + case OPC_CMP_LE_PH: + check_dsp(ctx); + gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); + break; + case OPC_PICK_QB: + check_dsp(ctx); + gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_PICK_PH: + check_dsp(ctx); + gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_PACKRL_PH: + check_dsp(ctx); + gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); + break; + } + break; +#ifdef TARGET_MIPS64 + case OPC_CMPU_EQ_OB_DSP: + switch (op2) { + case OPC_CMP_EQ_PW: + check_dsp(ctx); + gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env); + break; + case OPC_CMP_LT_PW: + check_dsp(ctx); + gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env); + break; + case OPC_CMP_LE_PW: + check_dsp(ctx); + gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env); + break; + case OPC_CMP_EQ_QH: + check_dsp(ctx); + gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env); + break; + case OPC_CMP_LT_QH: + check_dsp(ctx); + gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env); + break; + case OPC_CMP_LE_QH: + check_dsp(ctx); + gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env); + break; + case OPC_CMPGDU_EQ_OB: + check_dsp_r2(ctx); + gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_CMPGDU_LT_OB: + check_dsp_r2(ctx); + gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_CMPGDU_LE_OB: + check_dsp_r2(ctx); + gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_CMPGU_EQ_OB: + check_dsp(ctx); + gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_CMPGU_LT_OB: + check_dsp(ctx); + gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_CMPGU_LE_OB: + check_dsp(ctx); + gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_CMPU_EQ_OB: + check_dsp(ctx); + gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env); + break; + case OPC_CMPU_LT_OB: + check_dsp(ctx); + gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env); + break; + case OPC_CMPU_LE_OB: + check_dsp(ctx); + gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env); + break; + case OPC_PACKRL_PW: + check_dsp(ctx); + gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); + break; + case OPC_PICK_OB: + check_dsp(ctx); + gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_PICK_PW: + check_dsp(ctx); + gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + case OPC_PICK_QH: + check_dsp(ctx); + gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); + break; + } + break; +#endif + } + + tcg_temp_free(t1); + tcg_temp_free(v1_t); + tcg_temp_free(v2_t); +} + +static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, + uint32_t op1, int rt, int rs, int sa) +{ + TCGv t0; + + check_dsp_r2(ctx); + + if (rt =3D=3D 0) { + /* Treat as NOP. */ + return; + } + + t0 =3D tcg_temp_new(); + gen_load_gpr(t0, rs); + + switch (op1) { + case OPC_APPEND_DSP: + switch (MASK_APPEND(ctx->opcode)) { + case OPC_APPEND: + if (sa !=3D 0) { + tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - = sa); + } + tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); + break; + case OPC_PREPEND: + if (sa !=3D 0) { + tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); + tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); + tcg_gen_shli_tl(t0, t0, 32 - sa); + tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); + } + tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); + break; + case OPC_BALIGN: + sa &=3D 3; + if (sa !=3D 0 && sa !=3D 2) { + tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); + tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); + } + tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); + break; + default: /* Invalid */ + MIPS_INVAL("MASK APPEND"); + generate_exception_end(ctx, EXCP_RI); + break; + } + break; +#ifdef TARGET_MIPS64 + case OPC_DAPPEND_DSP: + switch (MASK_DAPPEND(ctx->opcode)) { + case OPC_DAPPEND: + if (sa !=3D 0) { + tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - = sa); + } + break; + case OPC_PREPENDD: + tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); + tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); + tcg_gen_or_tl(cpu_gpr[rt], t0, t0); + break; + case OPC_PREPENDW: + if (sa !=3D 0) { + tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); + tcg_gen_shli_tl(t0, t0, 64 - sa); + tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); + } + break; + case OPC_DBALIGN: + sa &=3D 7; + if (sa !=3D 0 && sa !=3D 2 && sa !=3D 4) { + tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); + tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); + tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); + } + break; + default: /* Invalid */ + MIPS_INVAL("MASK DAPPEND"); + generate_exception_end(ctx, EXCP_RI); + break; + } + break; +#endif + } + tcg_temp_free(t0); +} + +static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t = op2, + int ret, int v1, int v2, int check_ret) + +{ + TCGv t0; + TCGv t1; + TCGv v1_t; + TCGv v2_t; + int16_t imm; + + if ((ret =3D=3D 0) && (check_ret =3D=3D 1)) { + /* Treat as NOP. */ + return; + } + + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + v1_t =3D tcg_temp_new(); + v2_t =3D tcg_temp_new(); + + gen_load_gpr(v1_t, v1); + gen_load_gpr(v2_t, v2); + + switch (op1) { + case OPC_EXTR_W_DSP: + check_dsp(ctx); + switch (op2) { + case OPC_EXTR_W: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_EXTR_R_W: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_EXTR_RS_W: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_EXTR_S_H: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_EXTRV_S_H: + tcg_gen_movi_tl(t0, v2); + gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_EXTRV_W: + tcg_gen_movi_tl(t0, v2); + gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_EXTRV_R_W: + tcg_gen_movi_tl(t0, v2); + gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_EXTRV_RS_W: + tcg_gen_movi_tl(t0, v2); + gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_EXTP: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_EXTPV: + tcg_gen_movi_tl(t0, v2); + gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_EXTPDP: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_EXTPDPV: + tcg_gen_movi_tl(t0, v2); + gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_SHILO: + imm =3D (ctx->opcode >> 20) & 0x3F; + tcg_gen_movi_tl(t0, ret); + tcg_gen_movi_tl(t1, imm); + gen_helper_shilo(t0, t1, cpu_env); + break; + case OPC_SHILOV: + tcg_gen_movi_tl(t0, ret); + gen_helper_shilo(t0, v1_t, cpu_env); + break; + case OPC_MTHLIP: + tcg_gen_movi_tl(t0, ret); + gen_helper_mthlip(t0, v1_t, cpu_env); + break; + case OPC_WRDSP: + imm =3D (ctx->opcode >> 11) & 0x3FF; + tcg_gen_movi_tl(t0, imm); + gen_helper_wrdsp(v1_t, t0, cpu_env); + break; + case OPC_RDDSP: + imm =3D (ctx->opcode >> 16) & 0x03FF; + tcg_gen_movi_tl(t0, imm); + gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env); + break; + } + break; +#ifdef TARGET_MIPS64 + case OPC_DEXTR_W_DSP: + check_dsp(ctx); + switch (op2) { + case OPC_DMTHLIP: + tcg_gen_movi_tl(t0, ret); + gen_helper_dmthlip(v1_t, t0, cpu_env); + break; + case OPC_DSHILO: + { + int shift =3D (ctx->opcode >> 19) & 0x7F; + int ac =3D (ctx->opcode >> 11) & 0x03; + tcg_gen_movi_tl(t0, shift); + tcg_gen_movi_tl(t1, ac); + gen_helper_dshilo(t0, t1, cpu_env); + break; + } + case OPC_DSHILOV: + { + int ac =3D (ctx->opcode >> 11) & 0x03; + tcg_gen_movi_tl(t0, ac); + gen_helper_dshilo(v1_t, t0, cpu_env); + break; + } + case OPC_DEXTP: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + + gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_DEXTPV: + tcg_gen_movi_tl(t0, v2); + gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_DEXTPDP: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_DEXTPDPV: + tcg_gen_movi_tl(t0, v2); + gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_DEXTR_L: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_DEXTR_R_L: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_DEXTR_RS_L: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_DEXTR_W: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_DEXTR_R_W: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_DEXTR_RS_W: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_DEXTR_S_H: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_DEXTRV_S_H: + tcg_gen_movi_tl(t0, v2); + tcg_gen_movi_tl(t1, v1); + gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); + break; + case OPC_DEXTRV_L: + tcg_gen_movi_tl(t0, v2); + gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_DEXTRV_R_L: + tcg_gen_movi_tl(t0, v2); + gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_DEXTRV_RS_L: + tcg_gen_movi_tl(t0, v2); + gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_DEXTRV_W: + tcg_gen_movi_tl(t0, v2); + gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_DEXTRV_R_W: + tcg_gen_movi_tl(t0, v2); + gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + case OPC_DEXTRV_RS_W: + tcg_gen_movi_tl(t0, v2); + gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); + break; + } + break; +#endif + } + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(v1_t); + tcg_temp_free(v2_t); +} --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.66 as permitted sender) client-ip=209.85.128.66; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f66.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.66 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906571; cv=none; d=zohomail.com; s=zohoarc; b=SPFnMx3QCmrFS08bJqa4PMMqmQpBdqgZl94JD9xlw4SKyVB68s1g3Kb55C/ISPGgblvTUYdaMdgRyBprn5kIuoQJrpW2PMa4q5ixMh3EjiJTBR4OofNSiBAErS2ca7BZEnIHY9ej/tvUFmhW3QpMp6SaXSZkmahPOJcnReAhyXg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906571; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=y6PVLgrWI9U5avOLga7o8h5cNRHQNNP+gsHWE0oqgdU=; b=blu6dKtzfPPGrY+2SB/X31R9YdcMG87PFmGt+1tmbd2xFZn6A8rcvOw7mdvEAKOrPvgwx7EuafjReyHCZVdBUm4PrpE+FEOlkxSTCPAcp2z6Iz/2j+BNdx1O52+p8Rli5clovrQxvvFNgCQCdaRoGRY6eDfZzKfw83fUBOaQ/7s= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.66 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by mx.zohomail.com with SMTPS id 1605906571069637.5003477893415; Fri, 20 Nov 2020 13:09:31 -0800 (PST) Received: by mail-wm1-f66.google.com with SMTP id a3so11241006wmb.5 for ; Fri, 20 Nov 2020 13:09:30 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id 60sm6144403wrs.69.2020.11.20.13.09.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=y6PVLgrWI9U5avOLga7o8h5cNRHQNNP+gsHWE0oqgdU=; b=M9MHZFjuIT/OicHfAKQzkdF/xuGEoOW03jasoyee94WayFuKqe/e5CtLKNuW5vGmyh yvdmn38rK4Q3FDNJw4wQUiEYO/rwDT3ILeZVXEbyP9cGUL75TeBC5Kw6jsr4MUbLlG0u XpuU2sPLzFaGtmypTzxRpDafFPzrFJgZekjLkHbOdFdzFEUJchhNPoQDjigErgWASOGz 6Fd4ewUaOMyBfK3eIw6APzQxH7A4MMNOZMlPFSZACpMj5QOtd7TANUc7pMpjBVVD63qi L/Y0d1FhOG5BFisNYX6ecszEfm4mdE20ZtLzqdtQCuRG6hN7B2qNon4cx6J1k9vOr4IG 80pg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=y6PVLgrWI9U5avOLga7o8h5cNRHQNNP+gsHWE0oqgdU=; b=KXCq4AlMC0uYWyI5EoqaMj6dAwcQIzPC8YCGvyJTHGa6hwgM4TOCnQUCwAslr47EXM RiqfcdHe6yP12A+/Do2/4C2m6gfoc2KgDEEB1TWQ+NjLv4nhy9TiJHuqAA/PikS4liDn IDnYpAKNquYm08GmBB6JABXD3aiX3mm3OUvTlVRXDAaZNmOC+o9ao3TE5HgBfBSV2WuP 1dUJAyeGrz9j3hCIoyzKbIuG7rfIW3QmggTWRCRKOGmlOa3ioc7UdmtqfKglHQiQ7Fv6 YuZMMb5JBmb25q1GERO+aF5Fyaz+Xrv6lVtElbUrWz+DuPz+g6CcBdYaMPNsKQgcEHcF 3UCA== X-Gm-Message-State: AOAM532jygoE/mOtdbXCe2t7hw17KUxnHC7tX/3vIj8JW2geGXH2aXPm uu8fO821eWczjGzQ6aHoPHg= X-Google-Smtp-Source: ABdhPJxT0FE6nsn2TrUHEzv2uJYg/JskkUyZag3J9dRd6iGlFuuQtyHP7i65E5WedmJPL17L+qJwtQ== X-Received: by 2002:a1c:2b03:: with SMTP id r3mr11306852wmr.184.1605906569285; Fri, 20 Nov 2020 13:09:29 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 08/26] target/mips: Extract Multi-Threading helper definitions Date: Fri, 20 Nov 2020 22:08:26 +0100 Message-Id: <20201120210844.2625602-9-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) 'MIPS MT' is defined as a Module by MIPS. Extract the helper definitions to 'mod-mips-mt_helper.h.inc'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/helper.h | 24 +------------------ target/mips/mod-mips-mt_helper.h.inc | 36 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 target/mips/mod-mips-mt_helper.h.inc diff --git a/target/mips/helper.h b/target/mips/helper.h index bce869f3718..c15caed9fca 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -179,25 +179,6 @@ DEF_HELPER_2(dmtc0_entrylo0, void, env, i64) DEF_HELPER_2(dmtc0_entrylo1, void, env, i64) #endif =20 -/* MIPS MT functions */ -DEF_HELPER_2(mftgpr, tl, env, i32) -DEF_HELPER_2(mftlo, tl, env, i32) -DEF_HELPER_2(mfthi, tl, env, i32) -DEF_HELPER_2(mftacx, tl, env, i32) -DEF_HELPER_1(mftdsp, tl, env) -DEF_HELPER_3(mttgpr, void, env, tl, i32) -DEF_HELPER_3(mttlo, void, env, tl, i32) -DEF_HELPER_3(mtthi, void, env, tl, i32) -DEF_HELPER_3(mttacx, void, env, tl, i32) -DEF_HELPER_2(mttdsp, void, env, tl) -DEF_HELPER_0(dmt, tl) -DEF_HELPER_0(emt, tl) -DEF_HELPER_1(dvpe, tl, env) -DEF_HELPER_1(evpe, tl, env) - -/* R6 Multi-threading */ -DEF_HELPER_1(dvp, tl, env) -DEF_HELPER_1(evp, tl, env) #endif /* !CONFIG_USER_ONLY */ =20 /* microMIPS functions */ @@ -208,9 +189,6 @@ DEF_HELPER_4(ldm, void, env, tl, tl, i32) DEF_HELPER_4(sdm, void, env, tl, tl, i32) #endif =20 -DEF_HELPER_2(fork, void, tl, tl) -DEF_HELPER_2(yield, tl, env, tl) - /* CP1 functions */ DEF_HELPER_2(cfc1, tl, env, i32) DEF_HELPER_4(ctc1, void, env, tl, i32, i32) @@ -451,4 +429,4 @@ DEF_HELPER_3(cache, void, env, tl, i32) =20 #include "mod-mips-dsp_helper.h.inc" #include "mod-mips-msa_helper.h.inc" - +#include "mod-mips-mt_helper.h.inc" diff --git a/target/mips/mod-mips-mt_helper.h.inc b/target/mips/mod-mips-mt= _helper.h.inc new file mode 100644 index 00000000000..0db58e2a780 --- /dev/null +++ b/target/mips/mod-mips-mt_helper.h.inc @@ -0,0 +1,36 @@ +/* + * MIPS Multi-Threading helpers for QEMU. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef CONFIG_USER_ONLY +DEF_HELPER_2(mftgpr, tl, env, i32) +DEF_HELPER_2(mftlo, tl, env, i32) +DEF_HELPER_2(mfthi, tl, env, i32) +DEF_HELPER_2(mftacx, tl, env, i32) +DEF_HELPER_1(mftdsp, tl, env) +DEF_HELPER_3(mttgpr, void, env, tl, i32) +DEF_HELPER_3(mttlo, void, env, tl, i32) +DEF_HELPER_3(mtthi, void, env, tl, i32) +DEF_HELPER_3(mttacx, void, env, tl, i32) +DEF_HELPER_2(mttdsp, void, env, tl) + +DEF_HELPER_0(dmt, tl) +DEF_HELPER_0(emt, tl) + +DEF_HELPER_1(dvpe, tl, env) +DEF_HELPER_1(evpe, tl, env) + +/* R6 Multi-threading */ +DEF_HELPER_1(dvp, tl, env) +DEF_HELPER_1(evp, tl, env) +#endif /* !CONFIG_USER_ONLY */ + +DEF_HELPER_2(fork, void, tl, tl) +DEF_HELPER_2(yield, tl, env, tl) --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.43 as permitted sender) client-ip=209.85.221.43; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f43.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.43 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906577; cv=none; d=zohomail.com; s=zohoarc; b=BpM6E9+Fu3iwF7lyS5lrm0NSYU0sRFDAXGK9wBmR74DIcZ3ZeBHH+4PPxGFdgz1JAwTKB6eBCT0tHEayRHIQGCa4TUtSXPCUDtzeai573Q37o8/TktqjlnSm3m3xX7/eY+Q/IN/gmHoIOhUE5y/l0GsZ7bJlCAJPAk55Zz3wh1E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906577; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=g0Mk9GDnqB4MQPo0pWHhvafWi3BgfMYyKp5lBRD8ev4=; b=BFwhJ5CkwFWUX3SVDK+mL9FCw7rjygrsmC2nOADm/zvIPildDhkuBi745SYk1o6eL1+Xq63mRZUvNH8HyCtHzlKujNpQNKm9VfPS0v5E96OIiY3lOOusAFDPm+1DxcQIdTbKlpKnMNOUi1mFm49MLz2Nnin/Nzq0s1qyBODfFZU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.43 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) by mx.zohomail.com with SMTPS id 1605906577103480.33644882441615; Fri, 20 Nov 2020 13:09:37 -0800 (PST) Received: by mail-wr1-f43.google.com with SMTP id u12so11755540wrt.0 for ; Fri, 20 Nov 2020 13:09:36 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id g11sm6711182wrq.7.2020.11.20.13.09.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=g0Mk9GDnqB4MQPo0pWHhvafWi3BgfMYyKp5lBRD8ev4=; b=Id9jlWxRLVeXqBSwvFRuP3XPqMf6/+F2ww35+mxXl6KE9DjjaTMudJE954j242gZ24 5i3So7iMzwWGsmXfFR6vbPBravttqHJ8AsipTYOP/ZlVJnW7B8ivQ6g+gAMX/xaC3Z+o idXvBjyoI9PcIEyG9EEwqV3r3yvCPOudtqUbMsIfBKeIw+8Hvs5SHN62ysqZ9w+D1jnd A0Udss5Ky+vfikbfr0wphf1tvNw1H1hItXhG5cLJNZ/vvIdNjs+SsrLr/DAHHZiCKnbv hZ9AmxnEuGPAJ3lm2Q7I5pDYnA6AufyzleCzg8B9eyBaUzCJhmHDD0zo2NYE6pHBll36 vrbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=g0Mk9GDnqB4MQPo0pWHhvafWi3BgfMYyKp5lBRD8ev4=; b=OvK/NMZ1aUZlNEE9ZKabbq43YQIwXwGSetdyTpV90qsVfTjt5Y67sKJbbrPpJulExS TnKutDYy7BjJYStcoCBnQn9pkA2ntVVmPHCJY+tZ0pQIykIdnshhnwlLtq+oFEAc2LVu cVasysZrB2RoVRdfcHs85LPIG5Qkl68g7WCYcsBMVuEF7IBBAjGs6br6u73t6sT9rbJY dvUA0bSrZ4wWxJnfX2WNIKxvS25qK8glldbGP240aXEuXuyGljp1t68u7HwVSgotNwze 5hABP8R8ekt0Hena0iR3VFzR89pRZE29gYTwV/sZd62lHmOC8I9XhFtIIk0HemKcr4el wK7Q== X-Gm-Message-State: AOAM530SvuUEkJtJdCcQ1VsbMq7YBu7dIWR1U943dh45FkuMB7GWsiAO GCS8C+4U2Zu5jgH3F2rKOGY= X-Google-Smtp-Source: ABdhPJy4ID263CqFTt2GtP75onMmhDiHd3GglcVbuo2sLYDFYTWrH+JHC9CVy9ZTb/ac7OEg0wk4nw== X-Received: by 2002:a5d:44c1:: with SMTP id z1mr17724161wrr.375.1605906574558; Fri, 20 Nov 2020 13:09:34 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 09/26] target/mips: Extract Code Compaction ASE translation routines Date: Fri, 20 Nov 2020 22:08:27 +0100 Message-Id: <20201120210844.2625602-10-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract 1200 lines from the huge translate.c to a new file, 'ase-mips16e_translate.c.inc'. As there are too many inter- dependencies we don't compile it as another object, but keep including it in the big translate.o. We gain in code maintainability. Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/translate.c | 1161 +--------------------- target/mips/ase-mips16e_translate.c.inc | 1170 +++++++++++++++++++++++ 2 files changed, 1171 insertions(+), 1160 deletions(-) create mode 100644 target/mips/ase-mips16e_translate.c.inc diff --git a/target/mips/translate.c b/target/mips/translate.c index bc581a7a7a7..bae2064e7fa 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -13131,1167 +13131,8 @@ out: } =20 /* ISA extensions (ASEs) */ -/* MIPS16 extension to MIPS32 */ =20 -/* MIPS16 major opcodes */ -enum { - M16_OPC_ADDIUSP =3D 0x00, - M16_OPC_ADDIUPC =3D 0x01, - M16_OPC_B =3D 0x02, - M16_OPC_JAL =3D 0x03, - M16_OPC_BEQZ =3D 0x04, - M16_OPC_BNEQZ =3D 0x05, - M16_OPC_SHIFT =3D 0x06, - M16_OPC_LD =3D 0x07, - M16_OPC_RRIA =3D 0x08, - M16_OPC_ADDIU8 =3D 0x09, - M16_OPC_SLTI =3D 0x0a, - M16_OPC_SLTIU =3D 0x0b, - M16_OPC_I8 =3D 0x0c, - M16_OPC_LI =3D 0x0d, - M16_OPC_CMPI =3D 0x0e, - M16_OPC_SD =3D 0x0f, - M16_OPC_LB =3D 0x10, - M16_OPC_LH =3D 0x11, - M16_OPC_LWSP =3D 0x12, - M16_OPC_LW =3D 0x13, - M16_OPC_LBU =3D 0x14, - M16_OPC_LHU =3D 0x15, - M16_OPC_LWPC =3D 0x16, - M16_OPC_LWU =3D 0x17, - M16_OPC_SB =3D 0x18, - M16_OPC_SH =3D 0x19, - M16_OPC_SWSP =3D 0x1a, - M16_OPC_SW =3D 0x1b, - M16_OPC_RRR =3D 0x1c, - M16_OPC_RR =3D 0x1d, - M16_OPC_EXTEND =3D 0x1e, - M16_OPC_I64 =3D 0x1f -}; - -/* I8 funct field */ -enum { - I8_BTEQZ =3D 0x0, - I8_BTNEZ =3D 0x1, - I8_SWRASP =3D 0x2, - I8_ADJSP =3D 0x3, - I8_SVRS =3D 0x4, - I8_MOV32R =3D 0x5, - I8_MOVR32 =3D 0x7 -}; - -/* RRR f field */ -enum { - RRR_DADDU =3D 0x0, - RRR_ADDU =3D 0x1, - RRR_DSUBU =3D 0x2, - RRR_SUBU =3D 0x3 -}; - -/* RR funct field */ -enum { - RR_JR =3D 0x00, - RR_SDBBP =3D 0x01, - RR_SLT =3D 0x02, - RR_SLTU =3D 0x03, - RR_SLLV =3D 0x04, - RR_BREAK =3D 0x05, - RR_SRLV =3D 0x06, - RR_SRAV =3D 0x07, - RR_DSRL =3D 0x08, - RR_CMP =3D 0x0a, - RR_NEG =3D 0x0b, - RR_AND =3D 0x0c, - RR_OR =3D 0x0d, - RR_XOR =3D 0x0e, - RR_NOT =3D 0x0f, - RR_MFHI =3D 0x10, - RR_CNVT =3D 0x11, - RR_MFLO =3D 0x12, - RR_DSRA =3D 0x13, - RR_DSLLV =3D 0x14, - RR_DSRLV =3D 0x16, - RR_DSRAV =3D 0x17, - RR_MULT =3D 0x18, - RR_MULTU =3D 0x19, - RR_DIV =3D 0x1a, - RR_DIVU =3D 0x1b, - RR_DMULT =3D 0x1c, - RR_DMULTU =3D 0x1d, - RR_DDIV =3D 0x1e, - RR_DDIVU =3D 0x1f -}; - -/* I64 funct field */ -enum { - I64_LDSP =3D 0x0, - I64_SDSP =3D 0x1, - I64_SDRASP =3D 0x2, - I64_DADJSP =3D 0x3, - I64_LDPC =3D 0x4, - I64_DADDIU5 =3D 0x5, - I64_DADDIUPC =3D 0x6, - I64_DADDIUSP =3D 0x7 -}; - -/* RR ry field for CNVT */ -enum { - RR_RY_CNVT_ZEB =3D 0x0, - RR_RY_CNVT_ZEH =3D 0x1, - RR_RY_CNVT_ZEW =3D 0x2, - RR_RY_CNVT_SEB =3D 0x4, - RR_RY_CNVT_SEH =3D 0x5, - RR_RY_CNVT_SEW =3D 0x6, -}; - -static int xlat(int r) -{ - static int map[] =3D { 16, 17, 2, 3, 4, 5, 6, 7 }; - - return map[r]; -} - -static void gen_mips16_save(DisasContext *ctx, - int xsregs, int aregs, - int do_ra, int do_s0, int do_s1, - int framesize) -{ - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - TCGv t2 =3D tcg_temp_new(); - int args, astatic; - - switch (aregs) { - case 0: - case 1: - case 2: - case 3: - case 11: - args =3D 0; - break; - case 4: - case 5: - case 6: - case 7: - args =3D 1; - break; - case 8: - case 9: - case 10: - args =3D 2; - break; - case 12: - case 13: - args =3D 3; - break; - case 14: - args =3D 4; - break; - default: - generate_exception_end(ctx, EXCP_RI); - return; - } - - switch (args) { - case 4: - gen_base_offset_addr(ctx, t0, 29, 12); - gen_load_gpr(t1, 7); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); - /* Fall through */ - case 3: - gen_base_offset_addr(ctx, t0, 29, 8); - gen_load_gpr(t1, 6); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); - /* Fall through */ - case 2: - gen_base_offset_addr(ctx, t0, 29, 4); - gen_load_gpr(t1, 5); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); - /* Fall through */ - case 1: - gen_base_offset_addr(ctx, t0, 29, 0); - gen_load_gpr(t1, 4); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); - } - - gen_load_gpr(t0, 29); - -#define DECR_AND_STORE(reg) do { \ - tcg_gen_movi_tl(t2, -4); \ - gen_op_addr_add(ctx, t0, t0, t2); \ - gen_load_gpr(t1, reg); \ - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \ - } while (0) - - if (do_ra) { - DECR_AND_STORE(31); - } - - switch (xsregs) { - case 7: - DECR_AND_STORE(30); - /* Fall through */ - case 6: - DECR_AND_STORE(23); - /* Fall through */ - case 5: - DECR_AND_STORE(22); - /* Fall through */ - case 4: - DECR_AND_STORE(21); - /* Fall through */ - case 3: - DECR_AND_STORE(20); - /* Fall through */ - case 2: - DECR_AND_STORE(19); - /* Fall through */ - case 1: - DECR_AND_STORE(18); - } - - if (do_s1) { - DECR_AND_STORE(17); - } - if (do_s0) { - DECR_AND_STORE(16); - } - - switch (aregs) { - case 0: - case 4: - case 8: - case 12: - case 14: - astatic =3D 0; - break; - case 1: - case 5: - case 9: - case 13: - astatic =3D 1; - break; - case 2: - case 6: - case 10: - astatic =3D 2; - break; - case 3: - case 7: - astatic =3D 3; - break; - case 11: - astatic =3D 4; - break; - default: - generate_exception_end(ctx, EXCP_RI); - return; - } - - if (astatic > 0) { - DECR_AND_STORE(7); - if (astatic > 1) { - DECR_AND_STORE(6); - if (astatic > 2) { - DECR_AND_STORE(5); - if (astatic > 3) { - DECR_AND_STORE(4); - } - } - } - } -#undef DECR_AND_STORE - - tcg_gen_movi_tl(t2, -framesize); - gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2); - tcg_temp_free(t0); - tcg_temp_free(t1); - tcg_temp_free(t2); -} - -static void gen_mips16_restore(DisasContext *ctx, - int xsregs, int aregs, - int do_ra, int do_s0, int do_s1, - int framesize) -{ - int astatic; - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - TCGv t2 =3D tcg_temp_new(); - - tcg_gen_movi_tl(t2, framesize); - gen_op_addr_add(ctx, t0, cpu_gpr[29], t2); - -#define DECR_AND_LOAD(reg) do { \ - tcg_gen_movi_tl(t2, -4); \ - gen_op_addr_add(ctx, t0, t0, t2); \ - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \ - gen_store_gpr(t1, reg); \ - } while (0) - - if (do_ra) { - DECR_AND_LOAD(31); - } - - switch (xsregs) { - case 7: - DECR_AND_LOAD(30); - /* Fall through */ - case 6: - DECR_AND_LOAD(23); - /* Fall through */ - case 5: - DECR_AND_LOAD(22); - /* Fall through */ - case 4: - DECR_AND_LOAD(21); - /* Fall through */ - case 3: - DECR_AND_LOAD(20); - /* Fall through */ - case 2: - DECR_AND_LOAD(19); - /* Fall through */ - case 1: - DECR_AND_LOAD(18); - } - - if (do_s1) { - DECR_AND_LOAD(17); - } - if (do_s0) { - DECR_AND_LOAD(16); - } - - switch (aregs) { - case 0: - case 4: - case 8: - case 12: - case 14: - astatic =3D 0; - break; - case 1: - case 5: - case 9: - case 13: - astatic =3D 1; - break; - case 2: - case 6: - case 10: - astatic =3D 2; - break; - case 3: - case 7: - astatic =3D 3; - break; - case 11: - astatic =3D 4; - break; - default: - generate_exception_end(ctx, EXCP_RI); - return; - } - - if (astatic > 0) { - DECR_AND_LOAD(7); - if (astatic > 1) { - DECR_AND_LOAD(6); - if (astatic > 2) { - DECR_AND_LOAD(5); - if (astatic > 3) { - DECR_AND_LOAD(4); - } - } - } - } -#undef DECR_AND_LOAD - - tcg_gen_movi_tl(t2, framesize); - gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2); - tcg_temp_free(t0); - tcg_temp_free(t1); - tcg_temp_free(t2); -} - -static void gen_addiupc(DisasContext *ctx, int rx, int imm, - int is_64_bit, int extended) -{ - TCGv t0; - - if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { - generate_exception_end(ctx, EXCP_RI); - return; - } - - t0 =3D tcg_temp_new(); - - tcg_gen_movi_tl(t0, pc_relative_pc(ctx)); - tcg_gen_addi_tl(cpu_gpr[rx], t0, imm); - if (!is_64_bit) { - tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); - } - - tcg_temp_free(t0); -} - -static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, - int16_t offset) -{ - TCGv_i32 t0 =3D tcg_const_i32(op); - TCGv t1 =3D tcg_temp_new(); - gen_base_offset_addr(ctx, t1, base, offset); - gen_helper_cache(cpu_env, t1, t0); -} - -#if defined(TARGET_MIPS64) -static void decode_i64_mips16(DisasContext *ctx, - int ry, int funct, int16_t offset, - int extended) -{ - switch (funct) { - case I64_LDSP: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - offset =3D extended ? offset : offset << 3; - gen_ld(ctx, OPC_LD, ry, 29, offset); - break; - case I64_SDSP: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - offset =3D extended ? offset : offset << 3; - gen_st(ctx, OPC_SD, ry, 29, offset); - break; - case I64_SDRASP: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - offset =3D extended ? offset : (ctx->opcode & 0xff) << 3; - gen_st(ctx, OPC_SD, 31, 29, offset); - break; - case I64_DADJSP: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - offset =3D extended ? offset : ((int8_t)ctx->opcode) << 3; - gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset); - break; - case I64_LDPC: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { - generate_exception_end(ctx, EXCP_RI); - } else { - offset =3D extended ? offset : offset << 3; - gen_ld(ctx, OPC_LDPC, ry, 0, offset); - } - break; - case I64_DADDIU5: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - offset =3D extended ? offset : ((int8_t)(offset << 3)) >> 3; - gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset); - break; - case I64_DADDIUPC: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - offset =3D extended ? offset : offset << 2; - gen_addiupc(ctx, ry, offset, 1, extended); - break; - case I64_DADDIUSP: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - offset =3D extended ? offset : offset << 2; - gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset); - break; - } -} -#endif - -static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx) -{ - int extend =3D cpu_lduw_code(env, ctx->base.pc_next + 2); - int op, rx, ry, funct, sa; - int16_t imm, offset; - - ctx->opcode =3D (ctx->opcode << 16) | extend; - op =3D (ctx->opcode >> 11) & 0x1f; - sa =3D (ctx->opcode >> 22) & 0x1f; - funct =3D (ctx->opcode >> 8) & 0x7; - rx =3D xlat((ctx->opcode >> 8) & 0x7); - ry =3D xlat((ctx->opcode >> 5) & 0x7); - offset =3D imm =3D (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11 - | ((ctx->opcode >> 21) & 0x3f) << 5 - | (ctx->opcode & 0x1f)); - - /* - * The extended opcodes cleverly reuse the opcodes from their 16-bit - * counterparts. - */ - switch (op) { - case M16_OPC_ADDIUSP: - gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm); - break; - case M16_OPC_ADDIUPC: - gen_addiupc(ctx, rx, imm, 0, 1); - break; - case M16_OPC_B: - gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0); - /* No delay slot, so just process as a normal instruction */ - break; - case M16_OPC_BEQZ: - gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0); - /* No delay slot, so just process as a normal instruction */ - break; - case M16_OPC_BNEQZ: - gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0); - /* No delay slot, so just process as a normal instruction */ - break; - case M16_OPC_SHIFT: - switch (ctx->opcode & 0x3) { - case 0x0: - gen_shift_imm(ctx, OPC_SLL, rx, ry, sa); - break; - case 0x1: -#if defined(TARGET_MIPS64) - check_mips_64(ctx); - gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa); -#else - generate_exception_end(ctx, EXCP_RI); -#endif - break; - case 0x2: - gen_shift_imm(ctx, OPC_SRL, rx, ry, sa); - break; - case 0x3: - gen_shift_imm(ctx, OPC_SRA, rx, ry, sa); - break; - } - break; -#if defined(TARGET_MIPS64) - case M16_OPC_LD: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_ld(ctx, OPC_LD, ry, rx, offset); - break; -#endif - case M16_OPC_RRIA: - imm =3D ctx->opcode & 0xf; - imm =3D imm | ((ctx->opcode >> 20) & 0x7f) << 4; - imm =3D imm | ((ctx->opcode >> 16) & 0xf) << 11; - imm =3D (int16_t) (imm << 1) >> 1; - if ((ctx->opcode >> 4) & 0x1) { -#if defined(TARGET_MIPS64) - check_mips_64(ctx); - gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm); -#else - generate_exception_end(ctx, EXCP_RI); -#endif - } else { - gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm); - } - break; - case M16_OPC_ADDIU8: - gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm); - break; - case M16_OPC_SLTI: - gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm); - break; - case M16_OPC_SLTIU: - gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm); - break; - case M16_OPC_I8: - switch (funct) { - case I8_BTEQZ: - gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0); - break; - case I8_BTNEZ: - gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0); - break; - case I8_SWRASP: - gen_st(ctx, OPC_SW, 31, 29, imm); - break; - case I8_ADJSP: - gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm); - break; - case I8_SVRS: - check_insn(ctx, ISA_MIPS32); - { - int xsregs =3D (ctx->opcode >> 24) & 0x7; - int aregs =3D (ctx->opcode >> 16) & 0xf; - int do_ra =3D (ctx->opcode >> 6) & 0x1; - int do_s0 =3D (ctx->opcode >> 5) & 0x1; - int do_s1 =3D (ctx->opcode >> 4) & 0x1; - int framesize =3D (((ctx->opcode >> 20) & 0xf) << 4 - | (ctx->opcode & 0xf)) << 3; - - if (ctx->opcode & (1 << 7)) { - gen_mips16_save(ctx, xsregs, aregs, - do_ra, do_s0, do_s1, - framesize); - } else { - gen_mips16_restore(ctx, xsregs, aregs, - do_ra, do_s0, do_s1, - framesize); - } - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case M16_OPC_LI: - tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm); - break; - case M16_OPC_CMPI: - tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm); - break; -#if defined(TARGET_MIPS64) - case M16_OPC_SD: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_st(ctx, OPC_SD, ry, rx, offset); - break; -#endif - case M16_OPC_LB: - gen_ld(ctx, OPC_LB, ry, rx, offset); - break; - case M16_OPC_LH: - gen_ld(ctx, OPC_LH, ry, rx, offset); - break; - case M16_OPC_LWSP: - gen_ld(ctx, OPC_LW, rx, 29, offset); - break; - case M16_OPC_LW: - gen_ld(ctx, OPC_LW, ry, rx, offset); - break; - case M16_OPC_LBU: - gen_ld(ctx, OPC_LBU, ry, rx, offset); - break; - case M16_OPC_LHU: - gen_ld(ctx, OPC_LHU, ry, rx, offset); - break; - case M16_OPC_LWPC: - gen_ld(ctx, OPC_LWPC, rx, 0, offset); - break; -#if defined(TARGET_MIPS64) - case M16_OPC_LWU: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_ld(ctx, OPC_LWU, ry, rx, offset); - break; -#endif - case M16_OPC_SB: - gen_st(ctx, OPC_SB, ry, rx, offset); - break; - case M16_OPC_SH: - gen_st(ctx, OPC_SH, ry, rx, offset); - break; - case M16_OPC_SWSP: - gen_st(ctx, OPC_SW, rx, 29, offset); - break; - case M16_OPC_SW: - gen_st(ctx, OPC_SW, ry, rx, offset); - break; -#if defined(TARGET_MIPS64) - case M16_OPC_I64: - decode_i64_mips16(ctx, ry, funct, offset, 1); - break; -#endif - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - - return 4; -} - -static inline bool is_uhi(int sdbbp_code) -{ -#ifdef CONFIG_USER_ONLY - return false; -#else - return semihosting_enabled() && sdbbp_code =3D=3D 1; -#endif -} - -#ifdef CONFIG_USER_ONLY -/* The above should dead-code away any calls to this..*/ -static inline void gen_helper_do_semihosting(void *env) -{ - g_assert_not_reached(); -} -#endif - -static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) -{ - int rx, ry; - int sa; - int op, cnvt_op, op1, offset; - int funct; - int n_bytes; - - op =3D (ctx->opcode >> 11) & 0x1f; - sa =3D (ctx->opcode >> 2) & 0x7; - sa =3D sa =3D=3D 0 ? 8 : sa; - rx =3D xlat((ctx->opcode >> 8) & 0x7); - cnvt_op =3D (ctx->opcode >> 5) & 0x7; - ry =3D xlat((ctx->opcode >> 5) & 0x7); - op1 =3D offset =3D ctx->opcode & 0x1f; - - n_bytes =3D 2; - - switch (op) { - case M16_OPC_ADDIUSP: - { - int16_t imm =3D ((uint8_t) ctx->opcode) << 2; - - gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm); - } - break; - case M16_OPC_ADDIUPC: - gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0); - break; - case M16_OPC_B: - offset =3D (ctx->opcode & 0x7ff) << 1; - offset =3D (int16_t)(offset << 4) >> 4; - gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0); - /* No delay slot, so just process as a normal instruction */ - break; - case M16_OPC_JAL: - offset =3D cpu_lduw_code(env, ctx->base.pc_next + 2); - offset =3D (((ctx->opcode & 0x1f) << 21) - | ((ctx->opcode >> 5) & 0x1f) << 16 - | offset) << 2; - op =3D ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL; - gen_compute_branch(ctx, op, 4, rx, ry, offset, 2); - n_bytes =3D 4; - break; - case M16_OPC_BEQZ: - gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, - ((int8_t)ctx->opcode) << 1, 0); - /* No delay slot, so just process as a normal instruction */ - break; - case M16_OPC_BNEQZ: - gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, - ((int8_t)ctx->opcode) << 1, 0); - /* No delay slot, so just process as a normal instruction */ - break; - case M16_OPC_SHIFT: - switch (ctx->opcode & 0x3) { - case 0x0: - gen_shift_imm(ctx, OPC_SLL, rx, ry, sa); - break; - case 0x1: -#if defined(TARGET_MIPS64) - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa); -#else - generate_exception_end(ctx, EXCP_RI); -#endif - break; - case 0x2: - gen_shift_imm(ctx, OPC_SRL, rx, ry, sa); - break; - case 0x3: - gen_shift_imm(ctx, OPC_SRA, rx, ry, sa); - break; - } - break; -#if defined(TARGET_MIPS64) - case M16_OPC_LD: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_ld(ctx, OPC_LD, ry, rx, offset << 3); - break; -#endif - case M16_OPC_RRIA: - { - int16_t imm =3D (int8_t)((ctx->opcode & 0xf) << 4) >> 4; - - if ((ctx->opcode >> 4) & 1) { -#if defined(TARGET_MIPS64) - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm); -#else - generate_exception_end(ctx, EXCP_RI); -#endif - } else { - gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm); - } - } - break; - case M16_OPC_ADDIU8: - { - int16_t imm =3D (int8_t) ctx->opcode; - - gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm); - } - break; - case M16_OPC_SLTI: - { - int16_t imm =3D (uint8_t) ctx->opcode; - gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm); - } - break; - case M16_OPC_SLTIU: - { - int16_t imm =3D (uint8_t) ctx->opcode; - gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm); - } - break; - case M16_OPC_I8: - { - int reg32; - - funct =3D (ctx->opcode >> 8) & 0x7; - switch (funct) { - case I8_BTEQZ: - gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0, - ((int8_t)ctx->opcode) << 1, 0); - break; - case I8_BTNEZ: - gen_compute_branch(ctx, OPC_BNE, 2, 24, 0, - ((int8_t)ctx->opcode) << 1, 0); - break; - case I8_SWRASP: - gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2); - break; - case I8_ADJSP: - gen_arith_imm(ctx, OPC_ADDIU, 29, 29, - ((int8_t)ctx->opcode) << 3); - break; - case I8_SVRS: - check_insn(ctx, ISA_MIPS32); - { - int do_ra =3D ctx->opcode & (1 << 6); - int do_s0 =3D ctx->opcode & (1 << 5); - int do_s1 =3D ctx->opcode & (1 << 4); - int framesize =3D ctx->opcode & 0xf; - - if (framesize =3D=3D 0) { - framesize =3D 128; - } else { - framesize =3D framesize << 3; - } - - if (ctx->opcode & (1 << 7)) { - gen_mips16_save(ctx, 0, 0, - do_ra, do_s0, do_s1, framesize); - } else { - gen_mips16_restore(ctx, 0, 0, - do_ra, do_s0, do_s1, framesize); - } - } - break; - case I8_MOV32R: - { - int rz =3D xlat(ctx->opcode & 0x7); - - reg32 =3D (((ctx->opcode >> 3) & 0x3) << 3) | - ((ctx->opcode >> 5) & 0x7); - gen_arith(ctx, OPC_ADDU, reg32, rz, 0); - } - break; - case I8_MOVR32: - reg32 =3D ctx->opcode & 0x1f; - gen_arith(ctx, OPC_ADDU, ry, reg32, 0); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - } - break; - case M16_OPC_LI: - { - int16_t imm =3D (uint8_t) ctx->opcode; - - gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm); - } - break; - case M16_OPC_CMPI: - { - int16_t imm =3D (uint8_t) ctx->opcode; - gen_logic_imm(ctx, OPC_XORI, 24, rx, imm); - } - break; -#if defined(TARGET_MIPS64) - case M16_OPC_SD: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_st(ctx, OPC_SD, ry, rx, offset << 3); - break; -#endif - case M16_OPC_LB: - gen_ld(ctx, OPC_LB, ry, rx, offset); - break; - case M16_OPC_LH: - gen_ld(ctx, OPC_LH, ry, rx, offset << 1); - break; - case M16_OPC_LWSP: - gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2); - break; - case M16_OPC_LW: - gen_ld(ctx, OPC_LW, ry, rx, offset << 2); - break; - case M16_OPC_LBU: - gen_ld(ctx, OPC_LBU, ry, rx, offset); - break; - case M16_OPC_LHU: - gen_ld(ctx, OPC_LHU, ry, rx, offset << 1); - break; - case M16_OPC_LWPC: - gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2); - break; -#if defined(TARGET_MIPS64) - case M16_OPC_LWU: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_ld(ctx, OPC_LWU, ry, rx, offset << 2); - break; -#endif - case M16_OPC_SB: - gen_st(ctx, OPC_SB, ry, rx, offset); - break; - case M16_OPC_SH: - gen_st(ctx, OPC_SH, ry, rx, offset << 1); - break; - case M16_OPC_SWSP: - gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2); - break; - case M16_OPC_SW: - gen_st(ctx, OPC_SW, ry, rx, offset << 2); - break; - case M16_OPC_RRR: - { - int rz =3D xlat((ctx->opcode >> 2) & 0x7); - int mips32_op; - - switch (ctx->opcode & 0x3) { - case RRR_ADDU: - mips32_op =3D OPC_ADDU; - break; - case RRR_SUBU: - mips32_op =3D OPC_SUBU; - break; -#if defined(TARGET_MIPS64) - case RRR_DADDU: - mips32_op =3D OPC_DADDU; - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - break; - case RRR_DSUBU: - mips32_op =3D OPC_DSUBU; - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - break; -#endif - default: - generate_exception_end(ctx, EXCP_RI); - goto done; - } - - gen_arith(ctx, mips32_op, rz, rx, ry); - done: - ; - } - break; - case M16_OPC_RR: - switch (op1) { - case RR_JR: - { - int nd =3D (ctx->opcode >> 7) & 0x1; - int link =3D (ctx->opcode >> 6) & 0x1; - int ra =3D (ctx->opcode >> 5) & 0x1; - - if (nd) { - check_insn(ctx, ISA_MIPS32); - } - - if (link) { - op =3D OPC_JALR; - } else { - op =3D OPC_JR; - } - - gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0, - (nd ? 0 : 2)); - } - break; - case RR_SDBBP: - if (is_uhi(extract32(ctx->opcode, 5, 6))) { - gen_helper_do_semihosting(cpu_env); - } else { - /* - * XXX: not clear which exception should be raised - * when in debug mode... - */ - check_insn(ctx, ISA_MIPS32); - generate_exception_end(ctx, EXCP_DBp); - } - break; - case RR_SLT: - gen_slt(ctx, OPC_SLT, 24, rx, ry); - break; - case RR_SLTU: - gen_slt(ctx, OPC_SLTU, 24, rx, ry); - break; - case RR_BREAK: - generate_exception_end(ctx, EXCP_BREAK); - break; - case RR_SLLV: - gen_shift(ctx, OPC_SLLV, ry, rx, ry); - break; - case RR_SRLV: - gen_shift(ctx, OPC_SRLV, ry, rx, ry); - break; - case RR_SRAV: - gen_shift(ctx, OPC_SRAV, ry, rx, ry); - break; -#if defined(TARGET_MIPS64) - case RR_DSRL: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa); - break; -#endif - case RR_CMP: - gen_logic(ctx, OPC_XOR, 24, rx, ry); - break; - case RR_NEG: - gen_arith(ctx, OPC_SUBU, rx, 0, ry); - break; - case RR_AND: - gen_logic(ctx, OPC_AND, rx, rx, ry); - break; - case RR_OR: - gen_logic(ctx, OPC_OR, rx, rx, ry); - break; - case RR_XOR: - gen_logic(ctx, OPC_XOR, rx, rx, ry); - break; - case RR_NOT: - gen_logic(ctx, OPC_NOR, rx, ry, 0); - break; - case RR_MFHI: - gen_HILO(ctx, OPC_MFHI, 0, rx); - break; - case RR_CNVT: - check_insn(ctx, ISA_MIPS32); - switch (cnvt_op) { - case RR_RY_CNVT_ZEB: - tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]); - break; - case RR_RY_CNVT_ZEH: - tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]); - break; - case RR_RY_CNVT_SEB: - tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]); - break; - case RR_RY_CNVT_SEH: - tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]); - break; -#if defined(TARGET_MIPS64) - case RR_RY_CNVT_ZEW: - check_insn(ctx, ISA_MIPS64); - check_mips_64(ctx); - tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]); - break; - case RR_RY_CNVT_SEW: - check_insn(ctx, ISA_MIPS64); - check_mips_64(ctx); - tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); - break; -#endif - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case RR_MFLO: - gen_HILO(ctx, OPC_MFLO, 0, rx); - break; -#if defined(TARGET_MIPS64) - case RR_DSRA: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa); - break; - case RR_DSLLV: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_shift(ctx, OPC_DSLLV, ry, rx, ry); - break; - case RR_DSRLV: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_shift(ctx, OPC_DSRLV, ry, rx, ry); - break; - case RR_DSRAV: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_shift(ctx, OPC_DSRAV, ry, rx, ry); - break; -#endif - case RR_MULT: - gen_muldiv(ctx, OPC_MULT, 0, rx, ry); - break; - case RR_MULTU: - gen_muldiv(ctx, OPC_MULTU, 0, rx, ry); - break; - case RR_DIV: - gen_muldiv(ctx, OPC_DIV, 0, rx, ry); - break; - case RR_DIVU: - gen_muldiv(ctx, OPC_DIVU, 0, rx, ry); - break; -#if defined(TARGET_MIPS64) - case RR_DMULT: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_muldiv(ctx, OPC_DMULT, 0, rx, ry); - break; - case RR_DMULTU: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry); - break; - case RR_DDIV: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_muldiv(ctx, OPC_DDIV, 0, rx, ry); - break; - case RR_DDIVU: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry); - break; -#endif - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case M16_OPC_EXTEND: - decode_extended_mips16_opc(env, ctx); - n_bytes =3D 4; - break; -#if defined(TARGET_MIPS64) - case M16_OPC_I64: - funct =3D (ctx->opcode >> 8) & 0x7; - decode_i64_mips16(ctx, ry, funct, offset, 0); - break; -#endif - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - - return n_bytes; -} +#include "ase-mips16e_translate.c.inc" =20 /* microMIPS extension to MIPS32/MIPS64 */ =20 diff --git a/target/mips/ase-mips16e_translate.c.inc b/target/mips/ase-mips= 16e_translate.c.inc new file mode 100644 index 00000000000..11010a30bce --- /dev/null +++ b/target/mips/ase-mips16e_translate.c.inc @@ -0,0 +1,1170 @@ +/* + * MIPS16 extension (Code Compaction) ASE translation routines + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +/* MIPS16 major opcodes */ +enum { + M16_OPC_ADDIUSP =3D 0x00, + M16_OPC_ADDIUPC =3D 0x01, + M16_OPC_B =3D 0x02, + M16_OPC_JAL =3D 0x03, + M16_OPC_BEQZ =3D 0x04, + M16_OPC_BNEQZ =3D 0x05, + M16_OPC_SHIFT =3D 0x06, + M16_OPC_LD =3D 0x07, + M16_OPC_RRIA =3D 0x08, + M16_OPC_ADDIU8 =3D 0x09, + M16_OPC_SLTI =3D 0x0a, + M16_OPC_SLTIU =3D 0x0b, + M16_OPC_I8 =3D 0x0c, + M16_OPC_LI =3D 0x0d, + M16_OPC_CMPI =3D 0x0e, + M16_OPC_SD =3D 0x0f, + M16_OPC_LB =3D 0x10, + M16_OPC_LH =3D 0x11, + M16_OPC_LWSP =3D 0x12, + M16_OPC_LW =3D 0x13, + M16_OPC_LBU =3D 0x14, + M16_OPC_LHU =3D 0x15, + M16_OPC_LWPC =3D 0x16, + M16_OPC_LWU =3D 0x17, + M16_OPC_SB =3D 0x18, + M16_OPC_SH =3D 0x19, + M16_OPC_SWSP =3D 0x1a, + M16_OPC_SW =3D 0x1b, + M16_OPC_RRR =3D 0x1c, + M16_OPC_RR =3D 0x1d, + M16_OPC_EXTEND =3D 0x1e, + M16_OPC_I64 =3D 0x1f +}; + +/* I8 funct field */ +enum { + I8_BTEQZ =3D 0x0, + I8_BTNEZ =3D 0x1, + I8_SWRASP =3D 0x2, + I8_ADJSP =3D 0x3, + I8_SVRS =3D 0x4, + I8_MOV32R =3D 0x5, + I8_MOVR32 =3D 0x7 +}; + +/* RRR f field */ +enum { + RRR_DADDU =3D 0x0, + RRR_ADDU =3D 0x1, + RRR_DSUBU =3D 0x2, + RRR_SUBU =3D 0x3 +}; + +/* RR funct field */ +enum { + RR_JR =3D 0x00, + RR_SDBBP =3D 0x01, + RR_SLT =3D 0x02, + RR_SLTU =3D 0x03, + RR_SLLV =3D 0x04, + RR_BREAK =3D 0x05, + RR_SRLV =3D 0x06, + RR_SRAV =3D 0x07, + RR_DSRL =3D 0x08, + RR_CMP =3D 0x0a, + RR_NEG =3D 0x0b, + RR_AND =3D 0x0c, + RR_OR =3D 0x0d, + RR_XOR =3D 0x0e, + RR_NOT =3D 0x0f, + RR_MFHI =3D 0x10, + RR_CNVT =3D 0x11, + RR_MFLO =3D 0x12, + RR_DSRA =3D 0x13, + RR_DSLLV =3D 0x14, + RR_DSRLV =3D 0x16, + RR_DSRAV =3D 0x17, + RR_MULT =3D 0x18, + RR_MULTU =3D 0x19, + RR_DIV =3D 0x1a, + RR_DIVU =3D 0x1b, + RR_DMULT =3D 0x1c, + RR_DMULTU =3D 0x1d, + RR_DDIV =3D 0x1e, + RR_DDIVU =3D 0x1f +}; + +/* I64 funct field */ +enum { + I64_LDSP =3D 0x0, + I64_SDSP =3D 0x1, + I64_SDRASP =3D 0x2, + I64_DADJSP =3D 0x3, + I64_LDPC =3D 0x4, + I64_DADDIU5 =3D 0x5, + I64_DADDIUPC =3D 0x6, + I64_DADDIUSP =3D 0x7 +}; + +/* RR ry field for CNVT */ +enum { + RR_RY_CNVT_ZEB =3D 0x0, + RR_RY_CNVT_ZEH =3D 0x1, + RR_RY_CNVT_ZEW =3D 0x2, + RR_RY_CNVT_SEB =3D 0x4, + RR_RY_CNVT_SEH =3D 0x5, + RR_RY_CNVT_SEW =3D 0x6, +}; + +static int xlat(int r) +{ + static int map[] =3D { 16, 17, 2, 3, 4, 5, 6, 7 }; + + return map[r]; +} + +static void gen_mips16_save(DisasContext *ctx, + int xsregs, int aregs, + int do_ra, int do_s0, int do_s1, + int framesize) +{ + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + TCGv t2 =3D tcg_temp_new(); + int args, astatic; + + switch (aregs) { + case 0: + case 1: + case 2: + case 3: + case 11: + args =3D 0; + break; + case 4: + case 5: + case 6: + case 7: + args =3D 1; + break; + case 8: + case 9: + case 10: + args =3D 2; + break; + case 12: + case 13: + args =3D 3; + break; + case 14: + args =3D 4; + break; + default: + generate_exception_end(ctx, EXCP_RI); + return; + } + + switch (args) { + case 4: + gen_base_offset_addr(ctx, t0, 29, 12); + gen_load_gpr(t1, 7); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); + /* Fall through */ + case 3: + gen_base_offset_addr(ctx, t0, 29, 8); + gen_load_gpr(t1, 6); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); + /* Fall through */ + case 2: + gen_base_offset_addr(ctx, t0, 29, 4); + gen_load_gpr(t1, 5); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); + /* Fall through */ + case 1: + gen_base_offset_addr(ctx, t0, 29, 0); + gen_load_gpr(t1, 4); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); + } + + gen_load_gpr(t0, 29); + +#define DECR_AND_STORE(reg) do { \ + tcg_gen_movi_tl(t2, -4); \ + gen_op_addr_add(ctx, t0, t0, t2); \ + gen_load_gpr(t1, reg); \ + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \ + } while (0) + + if (do_ra) { + DECR_AND_STORE(31); + } + + switch (xsregs) { + case 7: + DECR_AND_STORE(30); + /* Fall through */ + case 6: + DECR_AND_STORE(23); + /* Fall through */ + case 5: + DECR_AND_STORE(22); + /* Fall through */ + case 4: + DECR_AND_STORE(21); + /* Fall through */ + case 3: + DECR_AND_STORE(20); + /* Fall through */ + case 2: + DECR_AND_STORE(19); + /* Fall through */ + case 1: + DECR_AND_STORE(18); + } + + if (do_s1) { + DECR_AND_STORE(17); + } + if (do_s0) { + DECR_AND_STORE(16); + } + + switch (aregs) { + case 0: + case 4: + case 8: + case 12: + case 14: + astatic =3D 0; + break; + case 1: + case 5: + case 9: + case 13: + astatic =3D 1; + break; + case 2: + case 6: + case 10: + astatic =3D 2; + break; + case 3: + case 7: + astatic =3D 3; + break; + case 11: + astatic =3D 4; + break; + default: + generate_exception_end(ctx, EXCP_RI); + return; + } + + if (astatic > 0) { + DECR_AND_STORE(7); + if (astatic > 1) { + DECR_AND_STORE(6); + if (astatic > 2) { + DECR_AND_STORE(5); + if (astatic > 3) { + DECR_AND_STORE(4); + } + } + } + } +#undef DECR_AND_STORE + + tcg_gen_movi_tl(t2, -framesize); + gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2); + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); +} + +static void gen_mips16_restore(DisasContext *ctx, + int xsregs, int aregs, + int do_ra, int do_s0, int do_s1, + int framesize) +{ + int astatic; + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + TCGv t2 =3D tcg_temp_new(); + + tcg_gen_movi_tl(t2, framesize); + gen_op_addr_add(ctx, t0, cpu_gpr[29], t2); + +#define DECR_AND_LOAD(reg) do { \ + tcg_gen_movi_tl(t2, -4); \ + gen_op_addr_add(ctx, t0, t0, t2); \ + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \ + gen_store_gpr(t1, reg); \ + } while (0) + + if (do_ra) { + DECR_AND_LOAD(31); + } + + switch (xsregs) { + case 7: + DECR_AND_LOAD(30); + /* Fall through */ + case 6: + DECR_AND_LOAD(23); + /* Fall through */ + case 5: + DECR_AND_LOAD(22); + /* Fall through */ + case 4: + DECR_AND_LOAD(21); + /* Fall through */ + case 3: + DECR_AND_LOAD(20); + /* Fall through */ + case 2: + DECR_AND_LOAD(19); + /* Fall through */ + case 1: + DECR_AND_LOAD(18); + } + + if (do_s1) { + DECR_AND_LOAD(17); + } + if (do_s0) { + DECR_AND_LOAD(16); + } + + switch (aregs) { + case 0: + case 4: + case 8: + case 12: + case 14: + astatic =3D 0; + break; + case 1: + case 5: + case 9: + case 13: + astatic =3D 1; + break; + case 2: + case 6: + case 10: + astatic =3D 2; + break; + case 3: + case 7: + astatic =3D 3; + break; + case 11: + astatic =3D 4; + break; + default: + generate_exception_end(ctx, EXCP_RI); + return; + } + + if (astatic > 0) { + DECR_AND_LOAD(7); + if (astatic > 1) { + DECR_AND_LOAD(6); + if (astatic > 2) { + DECR_AND_LOAD(5); + if (astatic > 3) { + DECR_AND_LOAD(4); + } + } + } + } +#undef DECR_AND_LOAD + + tcg_gen_movi_tl(t2, framesize); + gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2); + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); +} + +static void gen_addiupc(DisasContext *ctx, int rx, int imm, + int is_64_bit, int extended) +{ + TCGv t0; + + if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { + generate_exception_end(ctx, EXCP_RI); + return; + } + + t0 =3D tcg_temp_new(); + + tcg_gen_movi_tl(t0, pc_relative_pc(ctx)); + tcg_gen_addi_tl(cpu_gpr[rx], t0, imm); + if (!is_64_bit) { + tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); + } + + tcg_temp_free(t0); +} + +static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, + int16_t offset) +{ + TCGv_i32 t0 =3D tcg_const_i32(op); + TCGv t1 =3D tcg_temp_new(); + gen_base_offset_addr(ctx, t1, base, offset); + gen_helper_cache(cpu_env, t1, t0); +} + +#if defined(TARGET_MIPS64) +static void decode_i64_mips16(DisasContext *ctx, + int ry, int funct, int16_t offset, + int extended) +{ + switch (funct) { + case I64_LDSP: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + offset =3D extended ? offset : offset << 3; + gen_ld(ctx, OPC_LD, ry, 29, offset); + break; + case I64_SDSP: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + offset =3D extended ? offset : offset << 3; + gen_st(ctx, OPC_SD, ry, 29, offset); + break; + case I64_SDRASP: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + offset =3D extended ? offset : (ctx->opcode & 0xff) << 3; + gen_st(ctx, OPC_SD, 31, 29, offset); + break; + case I64_DADJSP: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + offset =3D extended ? offset : ((int8_t)ctx->opcode) << 3; + gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset); + break; + case I64_LDPC: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { + generate_exception_end(ctx, EXCP_RI); + } else { + offset =3D extended ? offset : offset << 3; + gen_ld(ctx, OPC_LDPC, ry, 0, offset); + } + break; + case I64_DADDIU5: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + offset =3D extended ? offset : ((int8_t)(offset << 3)) >> 3; + gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset); + break; + case I64_DADDIUPC: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + offset =3D extended ? offset : offset << 2; + gen_addiupc(ctx, ry, offset, 1, extended); + break; + case I64_DADDIUSP: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + offset =3D extended ? offset : offset << 2; + gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset); + break; + } +} +#endif + +static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx) +{ + int extend =3D cpu_lduw_code(env, ctx->base.pc_next + 2); + int op, rx, ry, funct, sa; + int16_t imm, offset; + + ctx->opcode =3D (ctx->opcode << 16) | extend; + op =3D (ctx->opcode >> 11) & 0x1f; + sa =3D (ctx->opcode >> 22) & 0x1f; + funct =3D (ctx->opcode >> 8) & 0x7; + rx =3D xlat((ctx->opcode >> 8) & 0x7); + ry =3D xlat((ctx->opcode >> 5) & 0x7); + offset =3D imm =3D (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11 + | ((ctx->opcode >> 21) & 0x3f) << 5 + | (ctx->opcode & 0x1f)); + + /* + * The extended opcodes cleverly reuse the opcodes from their 16-bit + * counterparts. + */ + switch (op) { + case M16_OPC_ADDIUSP: + gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm); + break; + case M16_OPC_ADDIUPC: + gen_addiupc(ctx, rx, imm, 0, 1); + break; + case M16_OPC_B: + gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0); + /* No delay slot, so just process as a normal instruction */ + break; + case M16_OPC_BEQZ: + gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0); + /* No delay slot, so just process as a normal instruction */ + break; + case M16_OPC_BNEQZ: + gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0); + /* No delay slot, so just process as a normal instruction */ + break; + case M16_OPC_SHIFT: + switch (ctx->opcode & 0x3) { + case 0x0: + gen_shift_imm(ctx, OPC_SLL, rx, ry, sa); + break; + case 0x1: +#if defined(TARGET_MIPS64) + check_mips_64(ctx); + gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa); +#else + generate_exception_end(ctx, EXCP_RI); +#endif + break; + case 0x2: + gen_shift_imm(ctx, OPC_SRL, rx, ry, sa); + break; + case 0x3: + gen_shift_imm(ctx, OPC_SRA, rx, ry, sa); + break; + } + break; +#if defined(TARGET_MIPS64) + case M16_OPC_LD: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_ld(ctx, OPC_LD, ry, rx, offset); + break; +#endif + case M16_OPC_RRIA: + imm =3D ctx->opcode & 0xf; + imm =3D imm | ((ctx->opcode >> 20) & 0x7f) << 4; + imm =3D imm | ((ctx->opcode >> 16) & 0xf) << 11; + imm =3D (int16_t) (imm << 1) >> 1; + if ((ctx->opcode >> 4) & 0x1) { +#if defined(TARGET_MIPS64) + check_mips_64(ctx); + gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm); +#else + generate_exception_end(ctx, EXCP_RI); +#endif + } else { + gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm); + } + break; + case M16_OPC_ADDIU8: + gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm); + break; + case M16_OPC_SLTI: + gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm); + break; + case M16_OPC_SLTIU: + gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm); + break; + case M16_OPC_I8: + switch (funct) { + case I8_BTEQZ: + gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0); + break; + case I8_BTNEZ: + gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0); + break; + case I8_SWRASP: + gen_st(ctx, OPC_SW, 31, 29, imm); + break; + case I8_ADJSP: + gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm); + break; + case I8_SVRS: + check_insn(ctx, ISA_MIPS32); + { + int xsregs =3D (ctx->opcode >> 24) & 0x7; + int aregs =3D (ctx->opcode >> 16) & 0xf; + int do_ra =3D (ctx->opcode >> 6) & 0x1; + int do_s0 =3D (ctx->opcode >> 5) & 0x1; + int do_s1 =3D (ctx->opcode >> 4) & 0x1; + int framesize =3D (((ctx->opcode >> 20) & 0xf) << 4 + | (ctx->opcode & 0xf)) << 3; + + if (ctx->opcode & (1 << 7)) { + gen_mips16_save(ctx, xsregs, aregs, + do_ra, do_s0, do_s1, + framesize); + } else { + gen_mips16_restore(ctx, xsregs, aregs, + do_ra, do_s0, do_s1, + framesize); + } + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case M16_OPC_LI: + tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm); + break; + case M16_OPC_CMPI: + tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm); + break; +#if defined(TARGET_MIPS64) + case M16_OPC_SD: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_st(ctx, OPC_SD, ry, rx, offset); + break; +#endif + case M16_OPC_LB: + gen_ld(ctx, OPC_LB, ry, rx, offset); + break; + case M16_OPC_LH: + gen_ld(ctx, OPC_LH, ry, rx, offset); + break; + case M16_OPC_LWSP: + gen_ld(ctx, OPC_LW, rx, 29, offset); + break; + case M16_OPC_LW: + gen_ld(ctx, OPC_LW, ry, rx, offset); + break; + case M16_OPC_LBU: + gen_ld(ctx, OPC_LBU, ry, rx, offset); + break; + case M16_OPC_LHU: + gen_ld(ctx, OPC_LHU, ry, rx, offset); + break; + case M16_OPC_LWPC: + gen_ld(ctx, OPC_LWPC, rx, 0, offset); + break; +#if defined(TARGET_MIPS64) + case M16_OPC_LWU: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_ld(ctx, OPC_LWU, ry, rx, offset); + break; +#endif + case M16_OPC_SB: + gen_st(ctx, OPC_SB, ry, rx, offset); + break; + case M16_OPC_SH: + gen_st(ctx, OPC_SH, ry, rx, offset); + break; + case M16_OPC_SWSP: + gen_st(ctx, OPC_SW, rx, 29, offset); + break; + case M16_OPC_SW: + gen_st(ctx, OPC_SW, ry, rx, offset); + break; +#if defined(TARGET_MIPS64) + case M16_OPC_I64: + decode_i64_mips16(ctx, ry, funct, offset, 1); + break; +#endif + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + + return 4; +} + +static inline bool is_uhi(int sdbbp_code) +{ +#ifdef CONFIG_USER_ONLY + return false; +#else + return semihosting_enabled() && sdbbp_code =3D=3D 1; +#endif +} + +#ifdef CONFIG_USER_ONLY +/* The above should dead-code away any calls to this..*/ +static inline void gen_helper_do_semihosting(void *env) +{ + g_assert_not_reached(); +} +#endif + +static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) +{ + int rx, ry; + int sa; + int op, cnvt_op, op1, offset; + int funct; + int n_bytes; + + op =3D (ctx->opcode >> 11) & 0x1f; + sa =3D (ctx->opcode >> 2) & 0x7; + sa =3D sa =3D=3D 0 ? 8 : sa; + rx =3D xlat((ctx->opcode >> 8) & 0x7); + cnvt_op =3D (ctx->opcode >> 5) & 0x7; + ry =3D xlat((ctx->opcode >> 5) & 0x7); + op1 =3D offset =3D ctx->opcode & 0x1f; + + n_bytes =3D 2; + + switch (op) { + case M16_OPC_ADDIUSP: + { + int16_t imm =3D ((uint8_t) ctx->opcode) << 2; + + gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm); + } + break; + case M16_OPC_ADDIUPC: + gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0); + break; + case M16_OPC_B: + offset =3D (ctx->opcode & 0x7ff) << 1; + offset =3D (int16_t)(offset << 4) >> 4; + gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0); + /* No delay slot, so just process as a normal instruction */ + break; + case M16_OPC_JAL: + offset =3D cpu_lduw_code(env, ctx->base.pc_next + 2); + offset =3D (((ctx->opcode & 0x1f) << 21) + | ((ctx->opcode >> 5) & 0x1f) << 16 + | offset) << 2; + op =3D ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL; + gen_compute_branch(ctx, op, 4, rx, ry, offset, 2); + n_bytes =3D 4; + break; + case M16_OPC_BEQZ: + gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, + ((int8_t)ctx->opcode) << 1, 0); + /* No delay slot, so just process as a normal instruction */ + break; + case M16_OPC_BNEQZ: + gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, + ((int8_t)ctx->opcode) << 1, 0); + /* No delay slot, so just process as a normal instruction */ + break; + case M16_OPC_SHIFT: + switch (ctx->opcode & 0x3) { + case 0x0: + gen_shift_imm(ctx, OPC_SLL, rx, ry, sa); + break; + case 0x1: +#if defined(TARGET_MIPS64) + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa); +#else + generate_exception_end(ctx, EXCP_RI); +#endif + break; + case 0x2: + gen_shift_imm(ctx, OPC_SRL, rx, ry, sa); + break; + case 0x3: + gen_shift_imm(ctx, OPC_SRA, rx, ry, sa); + break; + } + break; +#if defined(TARGET_MIPS64) + case M16_OPC_LD: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_ld(ctx, OPC_LD, ry, rx, offset << 3); + break; +#endif + case M16_OPC_RRIA: + { + int16_t imm =3D (int8_t)((ctx->opcode & 0xf) << 4) >> 4; + + if ((ctx->opcode >> 4) & 1) { +#if defined(TARGET_MIPS64) + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm); +#else + generate_exception_end(ctx, EXCP_RI); +#endif + } else { + gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm); + } + } + break; + case M16_OPC_ADDIU8: + { + int16_t imm =3D (int8_t) ctx->opcode; + + gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm); + } + break; + case M16_OPC_SLTI: + { + int16_t imm =3D (uint8_t) ctx->opcode; + gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm); + } + break; + case M16_OPC_SLTIU: + { + int16_t imm =3D (uint8_t) ctx->opcode; + gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm); + } + break; + case M16_OPC_I8: + { + int reg32; + + funct =3D (ctx->opcode >> 8) & 0x7; + switch (funct) { + case I8_BTEQZ: + gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0, + ((int8_t)ctx->opcode) << 1, 0); + break; + case I8_BTNEZ: + gen_compute_branch(ctx, OPC_BNE, 2, 24, 0, + ((int8_t)ctx->opcode) << 1, 0); + break; + case I8_SWRASP: + gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2); + break; + case I8_ADJSP: + gen_arith_imm(ctx, OPC_ADDIU, 29, 29, + ((int8_t)ctx->opcode) << 3); + break; + case I8_SVRS: + check_insn(ctx, ISA_MIPS32); + { + int do_ra =3D ctx->opcode & (1 << 6); + int do_s0 =3D ctx->opcode & (1 << 5); + int do_s1 =3D ctx->opcode & (1 << 4); + int framesize =3D ctx->opcode & 0xf; + + if (framesize =3D=3D 0) { + framesize =3D 128; + } else { + framesize =3D framesize << 3; + } + + if (ctx->opcode & (1 << 7)) { + gen_mips16_save(ctx, 0, 0, + do_ra, do_s0, do_s1, framesize); + } else { + gen_mips16_restore(ctx, 0, 0, + do_ra, do_s0, do_s1, framesize); + } + } + break; + case I8_MOV32R: + { + int rz =3D xlat(ctx->opcode & 0x7); + + reg32 =3D (((ctx->opcode >> 3) & 0x3) << 3) | + ((ctx->opcode >> 5) & 0x7); + gen_arith(ctx, OPC_ADDU, reg32, rz, 0); + } + break; + case I8_MOVR32: + reg32 =3D ctx->opcode & 0x1f; + gen_arith(ctx, OPC_ADDU, ry, reg32, 0); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + } + break; + case M16_OPC_LI: + { + int16_t imm =3D (uint8_t) ctx->opcode; + + gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm); + } + break; + case M16_OPC_CMPI: + { + int16_t imm =3D (uint8_t) ctx->opcode; + gen_logic_imm(ctx, OPC_XORI, 24, rx, imm); + } + break; +#if defined(TARGET_MIPS64) + case M16_OPC_SD: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_st(ctx, OPC_SD, ry, rx, offset << 3); + break; +#endif + case M16_OPC_LB: + gen_ld(ctx, OPC_LB, ry, rx, offset); + break; + case M16_OPC_LH: + gen_ld(ctx, OPC_LH, ry, rx, offset << 1); + break; + case M16_OPC_LWSP: + gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2); + break; + case M16_OPC_LW: + gen_ld(ctx, OPC_LW, ry, rx, offset << 2); + break; + case M16_OPC_LBU: + gen_ld(ctx, OPC_LBU, ry, rx, offset); + break; + case M16_OPC_LHU: + gen_ld(ctx, OPC_LHU, ry, rx, offset << 1); + break; + case M16_OPC_LWPC: + gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2); + break; +#if defined(TARGET_MIPS64) + case M16_OPC_LWU: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_ld(ctx, OPC_LWU, ry, rx, offset << 2); + break; +#endif + case M16_OPC_SB: + gen_st(ctx, OPC_SB, ry, rx, offset); + break; + case M16_OPC_SH: + gen_st(ctx, OPC_SH, ry, rx, offset << 1); + break; + case M16_OPC_SWSP: + gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2); + break; + case M16_OPC_SW: + gen_st(ctx, OPC_SW, ry, rx, offset << 2); + break; + case M16_OPC_RRR: + { + int rz =3D xlat((ctx->opcode >> 2) & 0x7); + int mips32_op; + + switch (ctx->opcode & 0x3) { + case RRR_ADDU: + mips32_op =3D OPC_ADDU; + break; + case RRR_SUBU: + mips32_op =3D OPC_SUBU; + break; +#if defined(TARGET_MIPS64) + case RRR_DADDU: + mips32_op =3D OPC_DADDU; + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + break; + case RRR_DSUBU: + mips32_op =3D OPC_DSUBU; + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + break; +#endif + default: + generate_exception_end(ctx, EXCP_RI); + goto done; + } + + gen_arith(ctx, mips32_op, rz, rx, ry); + done: + ; + } + break; + case M16_OPC_RR: + switch (op1) { + case RR_JR: + { + int nd =3D (ctx->opcode >> 7) & 0x1; + int link =3D (ctx->opcode >> 6) & 0x1; + int ra =3D (ctx->opcode >> 5) & 0x1; + + if (nd) { + check_insn(ctx, ISA_MIPS32); + } + + if (link) { + op =3D OPC_JALR; + } else { + op =3D OPC_JR; + } + + gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0, + (nd ? 0 : 2)); + } + break; + case RR_SDBBP: + if (is_uhi(extract32(ctx->opcode, 5, 6))) { + gen_helper_do_semihosting(cpu_env); + } else { + /* + * XXX: not clear which exception should be raised + * when in debug mode... + */ + check_insn(ctx, ISA_MIPS32); + generate_exception_end(ctx, EXCP_DBp); + } + break; + case RR_SLT: + gen_slt(ctx, OPC_SLT, 24, rx, ry); + break; + case RR_SLTU: + gen_slt(ctx, OPC_SLTU, 24, rx, ry); + break; + case RR_BREAK: + generate_exception_end(ctx, EXCP_BREAK); + break; + case RR_SLLV: + gen_shift(ctx, OPC_SLLV, ry, rx, ry); + break; + case RR_SRLV: + gen_shift(ctx, OPC_SRLV, ry, rx, ry); + break; + case RR_SRAV: + gen_shift(ctx, OPC_SRAV, ry, rx, ry); + break; +#if defined(TARGET_MIPS64) + case RR_DSRL: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa); + break; +#endif + case RR_CMP: + gen_logic(ctx, OPC_XOR, 24, rx, ry); + break; + case RR_NEG: + gen_arith(ctx, OPC_SUBU, rx, 0, ry); + break; + case RR_AND: + gen_logic(ctx, OPC_AND, rx, rx, ry); + break; + case RR_OR: + gen_logic(ctx, OPC_OR, rx, rx, ry); + break; + case RR_XOR: + gen_logic(ctx, OPC_XOR, rx, rx, ry); + break; + case RR_NOT: + gen_logic(ctx, OPC_NOR, rx, ry, 0); + break; + case RR_MFHI: + gen_HILO(ctx, OPC_MFHI, 0, rx); + break; + case RR_CNVT: + check_insn(ctx, ISA_MIPS32); + switch (cnvt_op) { + case RR_RY_CNVT_ZEB: + tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]); + break; + case RR_RY_CNVT_ZEH: + tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]); + break; + case RR_RY_CNVT_SEB: + tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]); + break; + case RR_RY_CNVT_SEH: + tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]); + break; +#if defined(TARGET_MIPS64) + case RR_RY_CNVT_ZEW: + check_insn(ctx, ISA_MIPS64); + check_mips_64(ctx); + tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]); + break; + case RR_RY_CNVT_SEW: + check_insn(ctx, ISA_MIPS64); + check_mips_64(ctx); + tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); + break; +#endif + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case RR_MFLO: + gen_HILO(ctx, OPC_MFLO, 0, rx); + break; +#if defined(TARGET_MIPS64) + case RR_DSRA: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa); + break; + case RR_DSLLV: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_shift(ctx, OPC_DSLLV, ry, rx, ry); + break; + case RR_DSRLV: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_shift(ctx, OPC_DSRLV, ry, rx, ry); + break; + case RR_DSRAV: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_shift(ctx, OPC_DSRAV, ry, rx, ry); + break; +#endif + case RR_MULT: + gen_muldiv(ctx, OPC_MULT, 0, rx, ry); + break; + case RR_MULTU: + gen_muldiv(ctx, OPC_MULTU, 0, rx, ry); + break; + case RR_DIV: + gen_muldiv(ctx, OPC_DIV, 0, rx, ry); + break; + case RR_DIVU: + gen_muldiv(ctx, OPC_DIVU, 0, rx, ry); + break; +#if defined(TARGET_MIPS64) + case RR_DMULT: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_muldiv(ctx, OPC_DMULT, 0, rx, ry); + break; + case RR_DMULTU: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry); + break; + case RR_DDIV: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_muldiv(ctx, OPC_DDIV, 0, rx, ry); + break; + case RR_DDIVU: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry); + break; +#endif + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case M16_OPC_EXTEND: + decode_extended_mips16_opc(env, ctx); + n_bytes =3D 4; + break; +#if defined(TARGET_MIPS64) + case M16_OPC_I64: + funct =3D (ctx->opcode >> 8) & 0x7; + decode_i64_mips16(ctx, ry, funct, offset, 0); + break; +#endif + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + + return n_bytes; +} --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.65 as permitted sender) client-ip=209.85.128.65; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f65.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.65 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906581; cv=none; d=zohomail.com; s=zohoarc; b=mTGL1VZO1BiXwK9lNpSH+2yG2FtYq3Bns51NaVpf7qPZIyXdyzcZ0EvIoUpuG3uB0kg7vnXCGUbhnJqUet5103/DJMEqWw2xIv9+NcyJInCeKSbzUeoJY2uztogVvYrV/G8XStBFGh6nXR7ksfy10n5ML1otprxGL4Rii+x4+Vg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906581; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=8GcA1tmgbgHsjhyS0X00aq1DHnZJQwU28jq75V9oiA8=; b=nj6LQed2B/kWzdqJPbJngPONDD7VrIl+N/E0iJuf7hOHAbK02dC6XF9DOFP5p9X4kAI6FYG6ar7wVTouFUM+fwcapgML45EckzM+dQfQ88SF3rrN0S1KDUkonVQclNPfRGfK5+7jmh1PYK0DQ1EOZ2IAVAXISGAvgwc0ESKuhuE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.65 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f65.google.com (mail-wm1-f65.google.com [209.85.128.65]) by mx.zohomail.com with SMTPS id 1605906581461428.57353429743966; Fri, 20 Nov 2020 13:09:41 -0800 (PST) Received: by mail-wm1-f65.google.com with SMTP id h21so11246355wmb.2 for ; Fri, 20 Nov 2020 13:09:40 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id s8sm6627126wrn.33.2020.11.20.13.09.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8GcA1tmgbgHsjhyS0X00aq1DHnZJQwU28jq75V9oiA8=; b=De0yqsrKx5tBwZsUF7B7lrVLtX8ukJw13uC6J1CK7ebKO+RXM8gdxxKG2Wzp27QDrw mddDUVSWAyvQQOtaNk2rXwtVZcQF2H18RBzvtSpTbMHqpXMGmkBp8HneMwk7x+BPt1Jv xJyCpRtSABeAp+WYqCF7MMerkSN69pW09H8q1d72sM4I1liBmqpB/M2DrvRrGqpNxB0H Urhn6Qb7FqrHvmZEFybrmw7xt0SRX1yM37T2AoIh0dCDAUXgEles4zkPNrSiS9RBoKVb vajRfhs9+fT0V1qMihciC0aJDR6zMTQ8FtpaW1QEm9vFBUn5iJ0If11C6fAbw69gQK0a ROCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=8GcA1tmgbgHsjhyS0X00aq1DHnZJQwU28jq75V9oiA8=; b=rHHBoi2N4FIVqZGDsuJgW557zv2Hhzx7OcrANXz3KVq4QAsAiTTzFWNFS9LaXHXC14 jx3aQ6/9XpwDtEreubgOffo0nlq/ZNbHUVw3fJPKl8kDiAM0J4C6wifPVFMGVUie6B72 CQP8mMyrPiUm5Lw52rtU66qx7LARQzxP62PbuvAov8C2dfkANrxVPJVs5uKEKhsdiiOU ziu5GPOsub6G6kSS7Cy7kHaE4q/RISfp/tcxd38zjk5puCqz+JaqH3j8MA2x13FXoOsQ UvpC88hSrozLXBpa345lkPMlirg4EdDxWITllGK5krmQBZ5w4NQDRJOBgc8aBgAeyLFi x3gQ== X-Gm-Message-State: AOAM530r6U8Ra4+yPS9ZyWYD/SJO+J+89nbV2Fhs32pAJYZKHjslqtd5 4ZpOD5bnW3xBwzV58rgR35rTYOuK3DY= X-Google-Smtp-Source: ABdhPJyQk/7+Y2GUgg/1Pn1CwN4xY7tKMkwp2jN7qYHaiaTqJ74iKppDWWUVDFofRRssc26OpW+wNg== X-Received: by 2002:a1c:ddd7:: with SMTP id u206mr11758386wmg.27.1605906579667; Fri, 20 Nov 2020 13:09:39 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 10/26] target/mips: Extract the microMIPS ISA helper definitions Date: Fri, 20 Nov 2020 22:08:28 +0100 Message-Id: <20201120210844.2625602-11-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract the microMIPS ISA helper definitions to 'isa-micromips_helper.h.inc'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/helper.h | 10 ++-------- target/mips/isa-micromips_helper.h.inc | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 target/mips/isa-micromips_helper.h.inc diff --git a/target/mips/helper.h b/target/mips/helper.h index c15caed9fca..ee93c2de836 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -181,14 +181,6 @@ DEF_HELPER_2(dmtc0_entrylo1, void, env, i64) =20 #endif /* !CONFIG_USER_ONLY */ =20 -/* microMIPS functions */ -DEF_HELPER_4(lwm, void, env, tl, tl, i32) -DEF_HELPER_4(swm, void, env, tl, tl, i32) -#ifdef TARGET_MIPS64 -DEF_HELPER_4(ldm, void, env, tl, tl, i32) -DEF_HELPER_4(sdm, void, env, tl, tl, i32) -#endif - /* CP1 functions */ DEF_HELPER_2(cfc1, tl, env, i32) DEF_HELPER_4(ctc1, void, env, tl, i32, i32) @@ -427,6 +419,8 @@ DEF_HELPER_FLAGS_1(pmovmskb, TCG_CALL_NO_RWG_SE, i64, i= 64) =20 DEF_HELPER_3(cache, void, env, tl, i32) =20 +#include "isa-micromips_helper.h.inc" + #include "mod-mips-dsp_helper.h.inc" #include "mod-mips-msa_helper.h.inc" #include "mod-mips-mt_helper.h.inc" diff --git a/target/mips/isa-micromips_helper.h.inc b/target/mips/isa-micro= mips_helper.h.inc new file mode 100644 index 00000000000..66a764c4aac --- /dev/null +++ b/target/mips/isa-micromips_helper.h.inc @@ -0,0 +1,17 @@ +/* + * microMIPS instruction emulation helpers for QEMU. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +DEF_HELPER_4(lwm, void, env, tl, tl, i32) +DEF_HELPER_4(swm, void, env, tl, tl, i32) +#ifdef TARGET_MIPS64 +DEF_HELPER_4(ldm, void, env, tl, tl, i32) +DEF_HELPER_4(sdm, void, env, tl, tl, i32) +#endif --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.47 as permitted sender) client-ip=209.85.221.47; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f47.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.47 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906588; cv=none; d=zohomail.com; s=zohoarc; b=FRxfvS81WMpbZVKdlda+U+bepEq7gF7DchmzXIG7eCoJHY0LQ0cqXXRBoCCcuJzVOw9+Z6NpcK6ncxjMDczk1N/C37QhPr5mqnXpkhD+fHvAbYAeahzN2J+xgfSaB1q5FhRhy2fzhJFxAYtvuUNR39UKDEGL2CUcMr40JyI7/iY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906588; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=px1ZCn0NlxZ7ZDcTjTqKASNwb3J6qR82Wpq2iR/mowE=; b=UGkO96vhFjOefYuRM5hri9OgHEqLSjmZU9gRcH5vxMSizqZxdNgMpd3ggS4GKAu35xLS0pEqwWJWIy8ulYygN/65QN2xZpEPUlux6GoFlupoYhQIZm5oeBxPvDB+Rhq5XHbDIgBaXK8uZ9OeqpLVexzphnyoQuJ4ndsyZzrsdvE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.47 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wr1-f47.google.com (mail-wr1-f47.google.com [209.85.221.47]) by mx.zohomail.com with SMTPS id 1605906588383682.1004622336264; Fri, 20 Nov 2020 13:09:48 -0800 (PST) Received: by mail-wr1-f47.google.com with SMTP id u12so11757372wrt.0 for ; Fri, 20 Nov 2020 13:09:47 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id b17sm6550652wru.12.2020.11.20.13.09.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=px1ZCn0NlxZ7ZDcTjTqKASNwb3J6qR82Wpq2iR/mowE=; b=UfYnt0+UOgvdRo/S6wPJiq5Cs6J+05RtpxUMOHsiTOmhWzL2pWm5rUxRaWYAvod2SS qY0J4hwszH4iOIOOPZieNuDzxEPyLlDMp/0I8GRSqCVhxWkffmm9XwP98rKj5jzqhg0B 9p+XTFTLtrVoOTGNPjfLcueBe+t39/T5sRqQO6b8+2jVlJ8ZtaMMCcs/n9ui12Ek8//E 1i6AnMIRGBjbn2yqfnbb+TKBcgZSBmAJgWAbrUf1hBDHFlU5c/XWiaIAfG6g4iD4xqkP XncGITvGDp8p6BvrFUhcMuqhCnD+LgcvpWvLnoCBUfsQXOCnWSvaplAfDDxnIAaery9c YwyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=px1ZCn0NlxZ7ZDcTjTqKASNwb3J6qR82Wpq2iR/mowE=; b=TS/Ok/q46cezGTWQOAsk9LiWdvuS9Ft4gBdp5HDXrTiV2Udxx4i82dCtz8K5fpG7au nyZ0PpZui1uTw/I+aY+q0VlJQHkFCDoKHrrHTRySTw4QcR97gi8gOdBPc+bi6bJ/Pqn6 vQryMjFdbG3BLcMUCOeFWUnccK92rNx6W33zuA3jaY5rs7JMbxwPluXOjBO8abEDje6B 17+T1cIkx08XBPsmlCTFmtgl4k6VNXbfYEl3XTeTegWlham8H9a3S13eV5BaGf8ot2YZ Uy5XrdV3vRX2RLjYSkfLDq16ERP17+VUgxrcLJk4Ly0ohMxrgKi/VAJH4M0SzijizcLx ucqA== X-Gm-Message-State: AOAM530NyjZL6MCXf2NLJbnCbavHGO+jWwS5xmDjAZrf3rClIg9N6QLa cjPvRnP8FlxK/oOH6RMmj38= X-Google-Smtp-Source: ABdhPJyGImzQMPrxWxQIr8VxPLrjsbv7uAJCz7Mg88i397dMr/nkKxujdiTLp7XxB0fm/901oNR+qg== X-Received: by 2002:a5d:4e4c:: with SMTP id r12mr18127603wrt.348.1605906585260; Fri, 20 Nov 2020 13:09:45 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 11/26] target/mips: Extract the microMIPS ISA translation routines Date: Fri, 20 Nov 2020 22:08:29 +0100 Message-Id: <20201120210844.2625602-12-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract 3300 lines from the huge translate.c to a new file, 'isa-micromips_translate.c.inc'. As there are too many inter- dependencies we don't compile it as another object, but keep including it in the big translate.o. We gain in code maintainability. Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/translate.c | 3309 +------------------- target/mips/isa-micromips_translate.c.inc | 3316 +++++++++++++++++++++ 2 files changed, 3317 insertions(+), 3308 deletions(-) create mode 100644 target/mips/isa-micromips_translate.c.inc diff --git a/target/mips/translate.c b/target/mips/translate.c index bae2064e7fa..17dfee12b7d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -13133,3314 +13133,7 @@ out: /* ISA extensions (ASEs) */ =20 #include "ase-mips16e_translate.c.inc" - -/* microMIPS extension to MIPS32/MIPS64 */ - -/* - * microMIPS32/microMIPS64 major opcodes - * - * 1. MIPS Architecture for Programmers Volume II-B: - * The microMIPS32 Instruction Set (Revision 3.05) - * - * Table 6.2 microMIPS32 Encoding of Major Opcode Field - * - * 2. MIPS Architecture For Programmers Volume II-A: - * The MIPS64 Instruction Set (Revision 3.51) - */ - -enum { - POOL32A =3D 0x00, - POOL16A =3D 0x01, - LBU16 =3D 0x02, - MOVE16 =3D 0x03, - ADDI32 =3D 0x04, - R6_LUI =3D 0x04, - AUI =3D 0x04, - LBU32 =3D 0x05, - SB32 =3D 0x06, - LB32 =3D 0x07, - - POOL32B =3D 0x08, - POOL16B =3D 0x09, - LHU16 =3D 0x0a, - ANDI16 =3D 0x0b, - ADDIU32 =3D 0x0c, - LHU32 =3D 0x0d, - SH32 =3D 0x0e, - LH32 =3D 0x0f, - - POOL32I =3D 0x10, - POOL16C =3D 0x11, - LWSP16 =3D 0x12, - POOL16D =3D 0x13, - ORI32 =3D 0x14, - POOL32F =3D 0x15, - POOL32S =3D 0x16, /* MIPS64 */ - DADDIU32 =3D 0x17, /* MIPS64 */ - - POOL32C =3D 0x18, - LWGP16 =3D 0x19, - LW16 =3D 0x1a, - POOL16E =3D 0x1b, - XORI32 =3D 0x1c, - JALS32 =3D 0x1d, - BOVC =3D 0x1d, - BEQC =3D 0x1d, - BEQZALC =3D 0x1d, - ADDIUPC =3D 0x1e, - PCREL =3D 0x1e, - BNVC =3D 0x1f, - BNEC =3D 0x1f, - BNEZALC =3D 0x1f, - - R6_BEQZC =3D 0x20, - JIC =3D 0x20, - POOL16F =3D 0x21, - SB16 =3D 0x22, - BEQZ16 =3D 0x23, - BEQZC16 =3D 0x23, - SLTI32 =3D 0x24, - BEQ32 =3D 0x25, - BC =3D 0x25, - SWC132 =3D 0x26, - LWC132 =3D 0x27, - - /* 0x29 is reserved */ - RES_29 =3D 0x29, - R6_BNEZC =3D 0x28, - JIALC =3D 0x28, - SH16 =3D 0x2a, - BNEZ16 =3D 0x2b, - BNEZC16 =3D 0x2b, - SLTIU32 =3D 0x2c, - BNE32 =3D 0x2d, - BALC =3D 0x2d, - SDC132 =3D 0x2e, - LDC132 =3D 0x2f, - - /* 0x31 is reserved */ - RES_31 =3D 0x31, - BLEZALC =3D 0x30, - BGEZALC =3D 0x30, - BGEUC =3D 0x30, - SWSP16 =3D 0x32, - B16 =3D 0x33, - BC16 =3D 0x33, - ANDI32 =3D 0x34, - J32 =3D 0x35, - BGTZC =3D 0x35, - BLTZC =3D 0x35, - BLTC =3D 0x35, - SD32 =3D 0x36, /* MIPS64 */ - LD32 =3D 0x37, /* MIPS64 */ - - /* 0x39 is reserved */ - RES_39 =3D 0x39, - BGTZALC =3D 0x38, - BLTZALC =3D 0x38, - BLTUC =3D 0x38, - SW16 =3D 0x3a, - LI16 =3D 0x3b, - JALX32 =3D 0x3c, - JAL32 =3D 0x3d, - BLEZC =3D 0x3d, - BGEZC =3D 0x3d, - BGEC =3D 0x3d, - SW32 =3D 0x3e, - LW32 =3D 0x3f -}; - -/* PCREL Instructions perform PC-Relative address calculation. bits 20..16= */ -enum { - ADDIUPC_00 =3D 0x00, - ADDIUPC_01 =3D 0x01, - ADDIUPC_02 =3D 0x02, - ADDIUPC_03 =3D 0x03, - ADDIUPC_04 =3D 0x04, - ADDIUPC_05 =3D 0x05, - ADDIUPC_06 =3D 0x06, - ADDIUPC_07 =3D 0x07, - AUIPC =3D 0x1e, - ALUIPC =3D 0x1f, - LWPC_08 =3D 0x08, - LWPC_09 =3D 0x09, - LWPC_0A =3D 0x0A, - LWPC_0B =3D 0x0B, - LWPC_0C =3D 0x0C, - LWPC_0D =3D 0x0D, - LWPC_0E =3D 0x0E, - LWPC_0F =3D 0x0F, -}; - -/* POOL32A encoding of minor opcode field */ - -enum { - /* - * These opcodes are distinguished only by bits 9..6; those bits are - * what are recorded below. - */ - SLL32 =3D 0x0, - SRL32 =3D 0x1, - SRA =3D 0x2, - ROTR =3D 0x3, - SELEQZ =3D 0x5, - SELNEZ =3D 0x6, - R6_RDHWR =3D 0x7, - - SLLV =3D 0x0, - SRLV =3D 0x1, - SRAV =3D 0x2, - ROTRV =3D 0x3, - ADD =3D 0x4, - ADDU32 =3D 0x5, - SUB =3D 0x6, - SUBU32 =3D 0x7, - MUL =3D 0x8, - AND =3D 0x9, - OR32 =3D 0xa, - NOR =3D 0xb, - XOR32 =3D 0xc, - SLT =3D 0xd, - SLTU =3D 0xe, - - MOVN =3D 0x0, - R6_MUL =3D 0x0, - MOVZ =3D 0x1, - MUH =3D 0x1, - MULU =3D 0x2, - MUHU =3D 0x3, - LWXS =3D 0x4, - R6_DIV =3D 0x4, - MOD =3D 0x5, - R6_DIVU =3D 0x6, - MODU =3D 0x7, - - /* The following can be distinguished by their lower 6 bits. */ - BREAK32 =3D 0x07, - INS =3D 0x0c, - LSA =3D 0x0f, - ALIGN =3D 0x1f, - EXT =3D 0x2c, - POOL32AXF =3D 0x3c, - SIGRIE =3D 0x3f -}; - -/* POOL32AXF encoding of minor opcode field extension */ - -/* - * 1. MIPS Architecture for Programmers Volume II-B: - * The microMIPS32 Instruction Set (Revision 3.05) - * - * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field - * - * 2. MIPS Architecture for Programmers VolumeIV-e: - * The MIPS DSP Application-Specific Extension - * to the microMIPS32 Architecture (Revision 2.34) - * - * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field - */ - -enum { - /* bits 11..6 */ - TEQ =3D 0x00, - TGE =3D 0x08, - TGEU =3D 0x10, - TLT =3D 0x20, - TLTU =3D 0x28, - TNE =3D 0x30, - - MFC0 =3D 0x03, - MTC0 =3D 0x0b, - - /* begin of microMIPS32 DSP */ - - /* bits 13..12 for 0x01 */ - MFHI_ACC =3D 0x0, - MFLO_ACC =3D 0x1, - MTHI_ACC =3D 0x2, - MTLO_ACC =3D 0x3, - - /* bits 13..12 for 0x2a */ - MADD_ACC =3D 0x0, - MADDU_ACC =3D 0x1, - MSUB_ACC =3D 0x2, - MSUBU_ACC =3D 0x3, - - /* bits 13..12 for 0x32 */ - MULT_ACC =3D 0x0, - MULTU_ACC =3D 0x1, - - /* end of microMIPS32 DSP */ - - /* bits 15..12 for 0x2c */ - BITSWAP =3D 0x0, - SEB =3D 0x2, - SEH =3D 0x3, - CLO =3D 0x4, - CLZ =3D 0x5, - RDHWR =3D 0x6, - WSBH =3D 0x7, - MULT =3D 0x8, - MULTU =3D 0x9, - DIV =3D 0xa, - DIVU =3D 0xb, - MADD =3D 0xc, - MADDU =3D 0xd, - MSUB =3D 0xe, - MSUBU =3D 0xf, - - /* bits 15..12 for 0x34 */ - MFC2 =3D 0x4, - MTC2 =3D 0x5, - MFHC2 =3D 0x8, - MTHC2 =3D 0x9, - CFC2 =3D 0xc, - CTC2 =3D 0xd, - - /* bits 15..12 for 0x3c */ - JALR =3D 0x0, - JR =3D 0x0, /* alias */ - JALRC =3D 0x0, - JRC =3D 0x0, - JALR_HB =3D 0x1, - JALRC_HB =3D 0x1, - JALRS =3D 0x4, - JALRS_HB =3D 0x5, - - /* bits 15..12 for 0x05 */ - RDPGPR =3D 0xe, - WRPGPR =3D 0xf, - - /* bits 15..12 for 0x0d */ - TLBP =3D 0x0, - TLBR =3D 0x1, - TLBWI =3D 0x2, - TLBWR =3D 0x3, - TLBINV =3D 0x4, - TLBINVF =3D 0x5, - WAIT =3D 0x9, - IRET =3D 0xd, - DERET =3D 0xe, - ERET =3D 0xf, - - /* bits 15..12 for 0x15 */ - DMT =3D 0x0, - DVPE =3D 0x1, - EMT =3D 0x2, - EVPE =3D 0x3, - - /* bits 15..12 for 0x1d */ - DI =3D 0x4, - EI =3D 0x5, - - /* bits 15..12 for 0x2d */ - SYNC =3D 0x6, - SYSCALL =3D 0x8, - SDBBP =3D 0xd, - - /* bits 15..12 for 0x35 */ - MFHI32 =3D 0x0, - MFLO32 =3D 0x1, - MTHI32 =3D 0x2, - MTLO32 =3D 0x3, -}; - -/* POOL32B encoding of minor opcode field (bits 15..12) */ - -enum { - LWC2 =3D 0x0, - LWP =3D 0x1, - LDP =3D 0x4, - LWM32 =3D 0x5, - CACHE =3D 0x6, - LDM =3D 0x7, - SWC2 =3D 0x8, - SWP =3D 0x9, - SDP =3D 0xc, - SWM32 =3D 0xd, - SDM =3D 0xf -}; - -/* POOL32C encoding of minor opcode field (bits 15..12) */ - -enum { - LWL =3D 0x0, - SWL =3D 0x8, - LWR =3D 0x1, - SWR =3D 0x9, - PREF =3D 0x2, - ST_EVA =3D 0xa, - LL =3D 0x3, - SC =3D 0xb, - LDL =3D 0x4, - SDL =3D 0xc, - LDR =3D 0x5, - SDR =3D 0xd, - LD_EVA =3D 0x6, - LWU =3D 0xe, - LLD =3D 0x7, - SCD =3D 0xf -}; - -/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */ - -enum { - LBUE =3D 0x0, - LHUE =3D 0x1, - LWLE =3D 0x2, - LWRE =3D 0x3, - LBE =3D 0x4, - LHE =3D 0x5, - LLE =3D 0x6, - LWE =3D 0x7, -}; - -/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */ - -enum { - SWLE =3D 0x0, - SWRE =3D 0x1, - PREFE =3D 0x2, - CACHEE =3D 0x3, - SBE =3D 0x4, - SHE =3D 0x5, - SCE =3D 0x6, - SWE =3D 0x7, -}; - -/* POOL32F encoding of minor opcode field (bits 5..0) */ - -enum { - /* These are the bit 7..6 values */ - ADD_FMT =3D 0x0, - - SUB_FMT =3D 0x1, - - MUL_FMT =3D 0x2, - - DIV_FMT =3D 0x3, - - /* These are the bit 8..6 values */ - MOVN_FMT =3D 0x0, - RSQRT2_FMT =3D 0x0, - MOVF_FMT =3D 0x0, - RINT_FMT =3D 0x0, - SELNEZ_FMT =3D 0x0, - - MOVZ_FMT =3D 0x1, - LWXC1 =3D 0x1, - MOVT_FMT =3D 0x1, - CLASS_FMT =3D 0x1, - SELEQZ_FMT =3D 0x1, - - PLL_PS =3D 0x2, - SWXC1 =3D 0x2, - SEL_FMT =3D 0x2, - - PLU_PS =3D 0x3, - LDXC1 =3D 0x3, - - MOVN_FMT_04 =3D 0x4, - PUL_PS =3D 0x4, - SDXC1 =3D 0x4, - RECIP2_FMT =3D 0x4, - - MOVZ_FMT_05 =3D 0x05, - PUU_PS =3D 0x5, - LUXC1 =3D 0x5, - - CVT_PS_S =3D 0x6, - SUXC1 =3D 0x6, - ADDR_PS =3D 0x6, - PREFX =3D 0x6, - MADDF_FMT =3D 0x6, - - MULR_PS =3D 0x7, - MSUBF_FMT =3D 0x7, - - MADD_S =3D 0x01, - MADD_D =3D 0x09, - MADD_PS =3D 0x11, - ALNV_PS =3D 0x19, - MSUB_S =3D 0x21, - MSUB_D =3D 0x29, - MSUB_PS =3D 0x31, - - NMADD_S =3D 0x02, - NMADD_D =3D 0x0a, - NMADD_PS =3D 0x12, - NMSUB_S =3D 0x22, - NMSUB_D =3D 0x2a, - NMSUB_PS =3D 0x32, - - MIN_FMT =3D 0x3, - MAX_FMT =3D 0xb, - MINA_FMT =3D 0x23, - MAXA_FMT =3D 0x2b, - POOL32FXF =3D 0x3b, - - CABS_COND_FMT =3D 0x1c, /* MIPS3D */ - C_COND_FMT =3D 0x3c, - - CMP_CONDN_S =3D 0x5, - CMP_CONDN_D =3D 0x15 -}; - -/* POOL32Fxf encoding of minor opcode extension field */ - -enum { - CVT_L =3D 0x04, - RSQRT_FMT =3D 0x08, - FLOOR_L =3D 0x0c, - CVT_PW_PS =3D 0x1c, - CVT_W =3D 0x24, - SQRT_FMT =3D 0x28, - FLOOR_W =3D 0x2c, - CVT_PS_PW =3D 0x3c, - CFC1 =3D 0x40, - RECIP_FMT =3D 0x48, - CEIL_L =3D 0x4c, - CTC1 =3D 0x60, - CEIL_W =3D 0x6c, - MFC1 =3D 0x80, - CVT_S_PL =3D 0x84, - TRUNC_L =3D 0x8c, - MTC1 =3D 0xa0, - CVT_S_PU =3D 0xa4, - TRUNC_W =3D 0xac, - MFHC1 =3D 0xc0, - ROUND_L =3D 0xcc, - MTHC1 =3D 0xe0, - ROUND_W =3D 0xec, - - MOV_FMT =3D 0x01, - MOVF =3D 0x05, - ABS_FMT =3D 0x0d, - RSQRT1_FMT =3D 0x1d, - MOVT =3D 0x25, - NEG_FMT =3D 0x2d, - CVT_D =3D 0x4d, - RECIP1_FMT =3D 0x5d, - CVT_S =3D 0x6d -}; - -/* POOL32I encoding of minor opcode field (bits 25..21) */ - -enum { - BLTZ =3D 0x00, - BLTZAL =3D 0x01, - BGEZ =3D 0x02, - BGEZAL =3D 0x03, - BLEZ =3D 0x04, - BNEZC =3D 0x05, - BGTZ =3D 0x06, - BEQZC =3D 0x07, - TLTI =3D 0x08, - BC1EQZC =3D 0x08, - TGEI =3D 0x09, - BC1NEZC =3D 0x09, - TLTIU =3D 0x0a, - BC2EQZC =3D 0x0a, - TGEIU =3D 0x0b, - BC2NEZC =3D 0x0a, - TNEI =3D 0x0c, - R6_SYNCI =3D 0x0c, - LUI =3D 0x0d, - TEQI =3D 0x0e, - SYNCI =3D 0x10, - BLTZALS =3D 0x11, - BGEZALS =3D 0x13, - BC2F =3D 0x14, - BC2T =3D 0x15, - BPOSGE64 =3D 0x1a, - BPOSGE32 =3D 0x1b, - /* These overlap and are distinguished by bit16 of the instruction */ - BC1F =3D 0x1c, - BC1T =3D 0x1d, - BC1ANY2F =3D 0x1c, - BC1ANY2T =3D 0x1d, - BC1ANY4F =3D 0x1e, - BC1ANY4T =3D 0x1f -}; - -/* POOL16A encoding of minor opcode field */ - -enum { - ADDU16 =3D 0x0, - SUBU16 =3D 0x1 -}; - -/* POOL16B encoding of minor opcode field */ - -enum { - SLL16 =3D 0x0, - SRL16 =3D 0x1 -}; - -/* POOL16C encoding of minor opcode field */ - -enum { - NOT16 =3D 0x00, - XOR16 =3D 0x04, - AND16 =3D 0x08, - OR16 =3D 0x0c, - LWM16 =3D 0x10, - SWM16 =3D 0x14, - JR16 =3D 0x18, - JRC16 =3D 0x1a, - JALR16 =3D 0x1c, - JALR16S =3D 0x1e, - MFHI16 =3D 0x20, - MFLO16 =3D 0x24, - BREAK16 =3D 0x28, - SDBBP16 =3D 0x2c, - JRADDIUSP =3D 0x30 -}; - -/* R6 POOL16C encoding of minor opcode field (bits 0..5) */ - -enum { - R6_NOT16 =3D 0x00, - R6_AND16 =3D 0x01, - R6_LWM16 =3D 0x02, - R6_JRC16 =3D 0x03, - MOVEP =3D 0x04, - MOVEP_05 =3D 0x05, - MOVEP_06 =3D 0x06, - MOVEP_07 =3D 0x07, - R6_XOR16 =3D 0x08, - R6_OR16 =3D 0x09, - R6_SWM16 =3D 0x0a, - JALRC16 =3D 0x0b, - MOVEP_0C =3D 0x0c, - MOVEP_0D =3D 0x0d, - MOVEP_0E =3D 0x0e, - MOVEP_0F =3D 0x0f, - JRCADDIUSP =3D 0x13, - R6_BREAK16 =3D 0x1b, - R6_SDBBP16 =3D 0x3b -}; - -/* POOL16D encoding of minor opcode field */ - -enum { - ADDIUS5 =3D 0x0, - ADDIUSP =3D 0x1 -}; - -/* POOL16E encoding of minor opcode field */ - -enum { - ADDIUR2 =3D 0x0, - ADDIUR1SP =3D 0x1 -}; - -static int mmreg(int r) -{ - static const int map[] =3D { 16, 17, 2, 3, 4, 5, 6, 7 }; - - return map[r]; -} - -/* Used for 16-bit store instructions. */ -static int mmreg2(int r) -{ - static const int map[] =3D { 0, 17, 2, 3, 4, 5, 6, 7 }; - - return map[r]; -} - -#define uMIPS_RD(op) ((op >> 7) & 0x7) -#define uMIPS_RS(op) ((op >> 4) & 0x7) -#define uMIPS_RS2(op) uMIPS_RS(op) -#define uMIPS_RS1(op) ((op >> 1) & 0x7) -#define uMIPS_RD5(op) ((op >> 5) & 0x1f) -#define uMIPS_RS5(op) (op & 0x1f) - -/* Signed immediate */ -#define SIMM(op, start, width) \ - ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \ - << (32 - width)) \ - >> (32 - width)) -/* Zero-extended immediate */ -#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width))) - -static void gen_addiur1sp(DisasContext *ctx) -{ - int rd =3D mmreg(uMIPS_RD(ctx->opcode)); - - gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2= ); -} - -static void gen_addiur2(DisasContext *ctx) -{ - static const int decoded_imm[] =3D { 1, 4, 8, 12, 16, 20, 24, -1 }; - int rd =3D mmreg(uMIPS_RD(ctx->opcode)); - int rs =3D mmreg(uMIPS_RS(ctx->opcode)); - - gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1,= 3)]); -} - -static void gen_addiusp(DisasContext *ctx) -{ - int encoded =3D ZIMM(ctx->opcode, 1, 9); - int decoded; - - if (encoded <=3D 1) { - decoded =3D 256 + encoded; - } else if (encoded <=3D 255) { - decoded =3D encoded; - } else if (encoded <=3D 509) { - decoded =3D encoded - 512; - } else { - decoded =3D encoded - 768; - } - - gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2); -} - -static void gen_addius5(DisasContext *ctx) -{ - int imm =3D SIMM(ctx->opcode, 1, 4); - int rd =3D (ctx->opcode >> 5) & 0x1f; - - gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm); -} - -static void gen_andi16(DisasContext *ctx) -{ - static const int decoded_imm[] =3D { 128, 1, 2, 3, 4, 7, 8, 15, 16, - 31, 32, 63, 64, 255, 32768, 65535 }; - int rd =3D mmreg(uMIPS_RD(ctx->opcode)); - int rs =3D mmreg(uMIPS_RS(ctx->opcode)); - int encoded =3D ZIMM(ctx->opcode, 0, 4); - - gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]); -} - -static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist, - int base, int16_t offset) -{ - TCGv t0, t1; - TCGv_i32 t2; - - if (ctx->hflags & MIPS_HFLAG_BMASK) { - generate_exception_end(ctx, EXCP_RI); - return; - } - - t0 =3D tcg_temp_new(); - - gen_base_offset_addr(ctx, t0, base, offset); - - t1 =3D tcg_const_tl(reglist); - t2 =3D tcg_const_i32(ctx->mem_idx); - - save_cpu_state(ctx, 1); - switch (opc) { - case LWM32: - gen_helper_lwm(cpu_env, t0, t1, t2); - break; - case SWM32: - gen_helper_swm(cpu_env, t0, t1, t2); - break; -#ifdef TARGET_MIPS64 - case LDM: - gen_helper_ldm(cpu_env, t0, t1, t2); - break; - case SDM: - gen_helper_sdm(cpu_env, t0, t1, t2); - break; -#endif - } - tcg_temp_free(t0); - tcg_temp_free(t1); - tcg_temp_free_i32(t2); -} - - -static void gen_pool16c_insn(DisasContext *ctx) -{ - int rd =3D mmreg((ctx->opcode >> 3) & 0x7); - int rs =3D mmreg(ctx->opcode & 0x7); - - switch (((ctx->opcode) >> 4) & 0x3f) { - case NOT16 + 0: - case NOT16 + 1: - case NOT16 + 2: - case NOT16 + 3: - gen_logic(ctx, OPC_NOR, rd, rs, 0); - break; - case XOR16 + 0: - case XOR16 + 1: - case XOR16 + 2: - case XOR16 + 3: - gen_logic(ctx, OPC_XOR, rd, rd, rs); - break; - case AND16 + 0: - case AND16 + 1: - case AND16 + 2: - case AND16 + 3: - gen_logic(ctx, OPC_AND, rd, rd, rs); - break; - case OR16 + 0: - case OR16 + 1: - case OR16 + 2: - case OR16 + 3: - gen_logic(ctx, OPC_OR, rd, rd, rs); - break; - case LWM16 + 0: - case LWM16 + 1: - case LWM16 + 2: - case LWM16 + 3: - { - static const int lwm_convert[] =3D { 0x11, 0x12, 0x13, 0x14 }; - int offset =3D ZIMM(ctx->opcode, 0, 4); - - gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) &= 0x3], - 29, offset << 2); - } - break; - case SWM16 + 0: - case SWM16 + 1: - case SWM16 + 2: - case SWM16 + 3: - { - static const int swm_convert[] =3D { 0x11, 0x12, 0x13, 0x14 }; - int offset =3D ZIMM(ctx->opcode, 0, 4); - - gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) &= 0x3], - 29, offset << 2); - } - break; - case JR16 + 0: - case JR16 + 1: - { - int reg =3D ctx->opcode & 0x1f; - - gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4); - } - break; - case JRC16 + 0: - case JRC16 + 1: - { - int reg =3D ctx->opcode & 0x1f; - gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0); - /* - * Let normal delay slot handling in our caller take us - * to the branch target. - */ - } - break; - case JALR16 + 0: - case JALR16 + 1: - gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - break; - case JALR16S + 0: - case JALR16S + 1: - gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - break; - case MFHI16 + 0: - case MFHI16 + 1: - gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode)); - break; - case MFLO16 + 0: - case MFLO16 + 1: - gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode)); - break; - case BREAK16: - generate_exception_end(ctx, EXCP_BREAK); - break; - case SDBBP16: - if (is_uhi(extract32(ctx->opcode, 0, 4))) { - gen_helper_do_semihosting(cpu_env); - } else { - /* - * XXX: not clear which exception should be raised - * when in debug mode... - */ - check_insn(ctx, ISA_MIPS32); - generate_exception_end(ctx, EXCP_DBp); - } - break; - case JRADDIUSP + 0: - case JRADDIUSP + 1: - { - int imm =3D ZIMM(ctx->opcode, 0, 5); - gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0); - gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2); - /* - * Let normal delay slot handling in our caller take us - * to the branch target. - */ - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt, - int enc_rs) -{ - int rd, rs, re, rt; - static const int rd_enc[] =3D { 5, 5, 6, 4, 4, 4, 4, 4 }; - static const int re_enc[] =3D { 6, 7, 7, 21, 22, 5, 6, 7 }; - static const int rs_rt_enc[] =3D { 0, 17, 2, 3, 16, 18, 19, 20 }; - rd =3D rd_enc[enc_dest]; - re =3D re_enc[enc_dest]; - rs =3D rs_rt_enc[enc_rs]; - rt =3D rs_rt_enc[enc_rt]; - if (rs) { - tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); - } else { - tcg_gen_movi_tl(cpu_gpr[rd], 0); - } - if (rt) { - tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]); - } else { - tcg_gen_movi_tl(cpu_gpr[re], 0); - } -} - -static void gen_pool16c_r6_insn(DisasContext *ctx) -{ - int rt =3D mmreg((ctx->opcode >> 7) & 0x7); - int rs =3D mmreg((ctx->opcode >> 4) & 0x7); - - switch (ctx->opcode & 0xf) { - case R6_NOT16: - gen_logic(ctx, OPC_NOR, rt, rs, 0); - break; - case R6_AND16: - gen_logic(ctx, OPC_AND, rt, rt, rs); - break; - case R6_LWM16: - { - int lwm_converted =3D 0x11 + extract32(ctx->opcode, 8, 2); - int offset =3D extract32(ctx->opcode, 4, 4); - gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2); - } - break; - case R6_JRC16: /* JRCADDIUSP */ - if ((ctx->opcode >> 4) & 1) { - /* JRCADDIUSP */ - int imm =3D extract32(ctx->opcode, 5, 5); - gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0); - gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2); - } else { - /* JRC16 */ - rs =3D extract32(ctx->opcode, 5, 5); - gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0); - } - break; - case MOVEP: - case MOVEP_05: - case MOVEP_06: - case MOVEP_07: - case MOVEP_0C: - case MOVEP_0D: - case MOVEP_0E: - case MOVEP_0F: - { - int enc_dest =3D uMIPS_RD(ctx->opcode); - int enc_rt =3D uMIPS_RS2(ctx->opcode); - int enc_rs =3D (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4); - gen_movep(ctx, enc_dest, enc_rt, enc_rs); - } - break; - case R6_XOR16: - gen_logic(ctx, OPC_XOR, rt, rt, rs); - break; - case R6_OR16: - gen_logic(ctx, OPC_OR, rt, rt, rs); - break; - case R6_SWM16: - { - int swm_converted =3D 0x11 + extract32(ctx->opcode, 8, 2); - int offset =3D extract32(ctx->opcode, 4, 4); - gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2); - } - break; - case JALRC16: /* BREAK16, SDBBP16 */ - switch (ctx->opcode & 0x3f) { - case JALRC16: - case JALRC16 + 0x20: - /* JALRC16 */ - gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f, - 31, 0, 0); - break; - case R6_BREAK16: - /* BREAK16 */ - generate_exception(ctx, EXCP_BREAK); - break; - case R6_SDBBP16: - /* SDBBP16 */ - if (is_uhi(extract32(ctx->opcode, 6, 4))) { - gen_helper_do_semihosting(cpu_env); - } else { - if (ctx->hflags & MIPS_HFLAG_SBRI) { - generate_exception(ctx, EXCP_RI); - } else { - generate_exception(ctx, EXCP_DBp); - } - } - break; - } - break; - default: - generate_exception(ctx, EXCP_RI); - break; - } -} - -static void gen_ldxs(DisasContext *ctx, int base, int index, int rd) -{ - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - - gen_load_gpr(t0, base); - - if (index !=3D 0) { - gen_load_gpr(t1, index); - tcg_gen_shli_tl(t1, t1, 2); - gen_op_addr_add(ctx, t0, t1, t0); - } - - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); - gen_store_gpr(t1, rd); - - tcg_temp_free(t0); - tcg_temp_free(t1); -} - -static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd, - int base, int16_t offset) -{ - TCGv t0, t1; - - if (ctx->hflags & MIPS_HFLAG_BMASK || rd =3D=3D 31) { - generate_exception_end(ctx, EXCP_RI); - return; - } - - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - - gen_base_offset_addr(ctx, t0, base, offset); - - switch (opc) { - case LWP: - if (rd =3D=3D base) { - generate_exception_end(ctx, EXCP_RI); - return; - } - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); - gen_store_gpr(t1, rd); - tcg_gen_movi_tl(t1, 4); - gen_op_addr_add(ctx, t0, t0, t1); - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); - gen_store_gpr(t1, rd + 1); - break; - case SWP: - gen_load_gpr(t1, rd); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); - tcg_gen_movi_tl(t1, 4); - gen_op_addr_add(ctx, t0, t0, t1); - gen_load_gpr(t1, rd + 1); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); - break; -#ifdef TARGET_MIPS64 - case LDP: - if (rd =3D=3D base) { - generate_exception_end(ctx, EXCP_RI); - return; - } - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ); - gen_store_gpr(t1, rd); - tcg_gen_movi_tl(t1, 8); - gen_op_addr_add(ctx, t0, t0, t1); - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ); - gen_store_gpr(t1, rd + 1); - break; - case SDP: - gen_load_gpr(t1, rd); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ); - tcg_gen_movi_tl(t1, 8); - gen_op_addr_add(ctx, t0, t0, t1); - gen_load_gpr(t1, rd + 1); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ); - break; -#endif - } - tcg_temp_free(t0); - tcg_temp_free(t1); -} - -static void gen_sync(int stype) -{ - TCGBar tcg_mo =3D TCG_BAR_SC; - - switch (stype) { - case 0x4: /* SYNC_WMB */ - tcg_mo |=3D TCG_MO_ST_ST; - break; - case 0x10: /* SYNC_MB */ - tcg_mo |=3D TCG_MO_ALL; - break; - case 0x11: /* SYNC_ACQUIRE */ - tcg_mo |=3D TCG_MO_LD_LD | TCG_MO_LD_ST; - break; - case 0x12: /* SYNC_RELEASE */ - tcg_mo |=3D TCG_MO_ST_ST | TCG_MO_LD_ST; - break; - case 0x13: /* SYNC_RMB */ - tcg_mo |=3D TCG_MO_LD_LD; - break; - default: - tcg_mo |=3D TCG_MO_ALL; - break; - } - - tcg_gen_mb(tcg_mo); -} - -static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, in= t rs) -{ - int extension =3D (ctx->opcode >> 6) & 0x3f; - int minor =3D (ctx->opcode >> 12) & 0xf; - uint32_t mips32_op; - - switch (extension) { - case TEQ: - mips32_op =3D OPC_TEQ; - goto do_trap; - case TGE: - mips32_op =3D OPC_TGE; - goto do_trap; - case TGEU: - mips32_op =3D OPC_TGEU; - goto do_trap; - case TLT: - mips32_op =3D OPC_TLT; - goto do_trap; - case TLTU: - mips32_op =3D OPC_TLTU; - goto do_trap; - case TNE: - mips32_op =3D OPC_TNE; - do_trap: - gen_trap(ctx, mips32_op, rs, rt, -1); - break; -#ifndef CONFIG_USER_ONLY - case MFC0: - case MFC0 + 32: - check_cp0_enabled(ctx); - if (rt =3D=3D 0) { - /* Treat as NOP. */ - break; - } - gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7); - break; - case MTC0: - case MTC0 + 32: - check_cp0_enabled(ctx); - { - TCGv t0 =3D tcg_temp_new(); - - gen_load_gpr(t0, rt); - gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7); - tcg_temp_free(t0); - } - break; -#endif - case 0x2a: - switch (minor & 3) { - case MADD_ACC: - gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt); - break; - case MADDU_ACC: - gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt); - break; - case MSUB_ACC: - gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt); - break; - case MSUBU_ACC: - gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt); - break; - default: - goto pool32axf_invalid; - } - break; - case 0x32: - switch (minor & 3) { - case MULT_ACC: - gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt); - break; - case MULTU_ACC: - gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt); - break; - default: - goto pool32axf_invalid; - } - break; - case 0x2c: - switch (minor) { - case BITSWAP: - check_insn(ctx, ISA_MIPS32R6); - gen_bitswap(ctx, OPC_BITSWAP, rs, rt); - break; - case SEB: - gen_bshfl(ctx, OPC_SEB, rs, rt); - break; - case SEH: - gen_bshfl(ctx, OPC_SEH, rs, rt); - break; - case CLO: - mips32_op =3D OPC_CLO; - goto do_cl; - case CLZ: - mips32_op =3D OPC_CLZ; - do_cl: - check_insn(ctx, ISA_MIPS32); - gen_cl(ctx, mips32_op, rt, rs); - break; - case RDHWR: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_rdhwr(ctx, rt, rs, 0); - break; - case WSBH: - gen_bshfl(ctx, OPC_WSBH, rs, rt); - break; - case MULT: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MULT; - goto do_mul; - case MULTU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MULTU; - goto do_mul; - case DIV: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_DIV; - goto do_div; - case DIVU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_DIVU; - goto do_div; - do_div: - check_insn(ctx, ISA_MIPS32); - gen_muldiv(ctx, mips32_op, 0, rs, rt); - break; - case MADD: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MADD; - goto do_mul; - case MADDU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MADDU; - goto do_mul; - case MSUB: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MSUB; - goto do_mul; - case MSUBU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MSUBU; - do_mul: - check_insn(ctx, ISA_MIPS32); - gen_muldiv(ctx, mips32_op, 0, rs, rt); - break; - default: - goto pool32axf_invalid; - } - break; - case 0x34: - switch (minor) { - case MFC2: - case MTC2: - case MFHC2: - case MTHC2: - case CFC2: - case CTC2: - generate_exception_err(ctx, EXCP_CpU, 2); - break; - default: - goto pool32axf_invalid; - } - break; - case 0x3c: - switch (minor) { - case JALR: /* JALRC */ - case JALR_HB: /* JALRC_HB */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* JALRC, JALRC_HB */ - gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0); - } else { - /* JALR, JALR_HB */ - gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - } - break; - case JALRS: - case JALRS_HB: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - break; - default: - goto pool32axf_invalid; - } - break; - case 0x05: - switch (minor) { - case RDPGPR: - check_cp0_enabled(ctx); - check_insn(ctx, ISA_MIPS32R2); - gen_load_srsgpr(rs, rt); - break; - case WRPGPR: - check_cp0_enabled(ctx); - check_insn(ctx, ISA_MIPS32R2); - gen_store_srsgpr(rs, rt); - break; - default: - goto pool32axf_invalid; - } - break; -#ifndef CONFIG_USER_ONLY - case 0x0d: - switch (minor) { - case TLBP: - mips32_op =3D OPC_TLBP; - goto do_cp0; - case TLBR: - mips32_op =3D OPC_TLBR; - goto do_cp0; - case TLBWI: - mips32_op =3D OPC_TLBWI; - goto do_cp0; - case TLBWR: - mips32_op =3D OPC_TLBWR; - goto do_cp0; - case TLBINV: - mips32_op =3D OPC_TLBINV; - goto do_cp0; - case TLBINVF: - mips32_op =3D OPC_TLBINVF; - goto do_cp0; - case WAIT: - mips32_op =3D OPC_WAIT; - goto do_cp0; - case DERET: - mips32_op =3D OPC_DERET; - goto do_cp0; - case ERET: - mips32_op =3D OPC_ERET; - do_cp0: - gen_cp0(env, ctx, mips32_op, rt, rs); - break; - default: - goto pool32axf_invalid; - } - break; - case 0x1d: - switch (minor) { - case DI: - check_cp0_enabled(ctx); - { - TCGv t0 =3D tcg_temp_new(); - - save_cpu_state(ctx, 1); - gen_helper_di(t0, cpu_env); - gen_store_gpr(t0, rs); - /* - * Stop translation as we may have switched the execution - * mode. - */ - ctx->base.is_jmp =3D DISAS_STOP; - tcg_temp_free(t0); - } - break; - case EI: - check_cp0_enabled(ctx); - { - TCGv t0 =3D tcg_temp_new(); - - save_cpu_state(ctx, 1); - gen_helper_ei(t0, cpu_env); - gen_store_gpr(t0, rs); - /* - * DISAS_STOP isn't sufficient, we need to ensure we break= out - * of translated code to check for pending interrupts. - */ - gen_save_pc(ctx->base.pc_next + 4); - ctx->base.is_jmp =3D DISAS_EXIT; - tcg_temp_free(t0); - } - break; - default: - goto pool32axf_invalid; - } - break; -#endif - case 0x2d: - switch (minor) { - case SYNC: - gen_sync(extract32(ctx->opcode, 16, 5)); - break; - case SYSCALL: - generate_exception_end(ctx, EXCP_SYSCALL); - break; - case SDBBP: - if (is_uhi(extract32(ctx->opcode, 16, 10))) { - gen_helper_do_semihosting(cpu_env); - } else { - check_insn(ctx, ISA_MIPS32); - if (ctx->hflags & MIPS_HFLAG_SBRI) { - generate_exception_end(ctx, EXCP_RI); - } else { - generate_exception_end(ctx, EXCP_DBp); - } - } - break; - default: - goto pool32axf_invalid; - } - break; - case 0x01: - switch (minor & 3) { - case MFHI_ACC: - gen_HILO(ctx, OPC_MFHI, minor >> 2, rs); - break; - case MFLO_ACC: - gen_HILO(ctx, OPC_MFLO, minor >> 2, rs); - break; - case MTHI_ACC: - gen_HILO(ctx, OPC_MTHI, minor >> 2, rs); - break; - case MTLO_ACC: - gen_HILO(ctx, OPC_MTLO, minor >> 2, rs); - break; - default: - goto pool32axf_invalid; - } - break; - case 0x35: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - switch (minor) { - case MFHI32: - gen_HILO(ctx, OPC_MFHI, 0, rs); - break; - case MFLO32: - gen_HILO(ctx, OPC_MFLO, 0, rs); - break; - case MTHI32: - gen_HILO(ctx, OPC_MTHI, 0, rs); - break; - case MTLO32: - gen_HILO(ctx, OPC_MTLO, 0, rs); - break; - default: - goto pool32axf_invalid; - } - break; - default: - pool32axf_invalid: - MIPS_INVAL("pool32axf"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * Values for microMIPS fmt field. Variable-width, depending on which - * formats the instruction supports. - */ -enum { - FMT_SD_S =3D 0, - FMT_SD_D =3D 1, - - FMT_SDPS_S =3D 0, - FMT_SDPS_D =3D 1, - FMT_SDPS_PS =3D 2, - - FMT_SWL_S =3D 0, - FMT_SWL_W =3D 1, - FMT_SWL_L =3D 2, - - FMT_DWL_D =3D 0, - FMT_DWL_W =3D 1, - FMT_DWL_L =3D 2 -}; - -static void gen_pool32fxf(DisasContext *ctx, int rt, int rs) -{ - int extension =3D (ctx->opcode >> 6) & 0x3ff; - uint32_t mips32_op; - -#define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc) -#define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc) -#define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc) - - switch (extension) { - case FLOAT_1BIT_FMT(CFC1, 0): - mips32_op =3D OPC_CFC1; - goto do_cp1; - case FLOAT_1BIT_FMT(CTC1, 0): - mips32_op =3D OPC_CTC1; - goto do_cp1; - case FLOAT_1BIT_FMT(MFC1, 0): - mips32_op =3D OPC_MFC1; - goto do_cp1; - case FLOAT_1BIT_FMT(MTC1, 0): - mips32_op =3D OPC_MTC1; - goto do_cp1; - case FLOAT_1BIT_FMT(MFHC1, 0): - mips32_op =3D OPC_MFHC1; - goto do_cp1; - case FLOAT_1BIT_FMT(MTHC1, 0): - mips32_op =3D OPC_MTHC1; - do_cp1: - gen_cp1(ctx, mips32_op, rt, rs); - break; - - /* Reciprocal square root */ - case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S): - mips32_op =3D OPC_RSQRT_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D): - mips32_op =3D OPC_RSQRT_D; - goto do_unaryfp; - - /* Square root */ - case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S): - mips32_op =3D OPC_SQRT_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D): - mips32_op =3D OPC_SQRT_D; - goto do_unaryfp; - - /* Reciprocal */ - case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S): - mips32_op =3D OPC_RECIP_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D): - mips32_op =3D OPC_RECIP_D; - goto do_unaryfp; - - /* Floor */ - case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S): - mips32_op =3D OPC_FLOOR_L_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D): - mips32_op =3D OPC_FLOOR_L_D; - goto do_unaryfp; - case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S): - mips32_op =3D OPC_FLOOR_W_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D): - mips32_op =3D OPC_FLOOR_W_D; - goto do_unaryfp; - - /* Ceiling */ - case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S): - mips32_op =3D OPC_CEIL_L_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D): - mips32_op =3D OPC_CEIL_L_D; - goto do_unaryfp; - case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S): - mips32_op =3D OPC_CEIL_W_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D): - mips32_op =3D OPC_CEIL_W_D; - goto do_unaryfp; - - /* Truncation */ - case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S): - mips32_op =3D OPC_TRUNC_L_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D): - mips32_op =3D OPC_TRUNC_L_D; - goto do_unaryfp; - case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S): - mips32_op =3D OPC_TRUNC_W_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D): - mips32_op =3D OPC_TRUNC_W_D; - goto do_unaryfp; - - /* Round */ - case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S): - mips32_op =3D OPC_ROUND_L_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D): - mips32_op =3D OPC_ROUND_L_D; - goto do_unaryfp; - case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S): - mips32_op =3D OPC_ROUND_W_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D): - mips32_op =3D OPC_ROUND_W_D; - goto do_unaryfp; - - /* Integer to floating-point conversion */ - case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S): - mips32_op =3D OPC_CVT_L_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D): - mips32_op =3D OPC_CVT_L_D; - goto do_unaryfp; - case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S): - mips32_op =3D OPC_CVT_W_S; - goto do_unaryfp; - case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D): - mips32_op =3D OPC_CVT_W_D; - goto do_unaryfp; - - /* Paired-foo conversions */ - case FLOAT_1BIT_FMT(CVT_S_PL, 0): - mips32_op =3D OPC_CVT_S_PL; - goto do_unaryfp; - case FLOAT_1BIT_FMT(CVT_S_PU, 0): - mips32_op =3D OPC_CVT_S_PU; - goto do_unaryfp; - case FLOAT_1BIT_FMT(CVT_PW_PS, 0): - mips32_op =3D OPC_CVT_PW_PS; - goto do_unaryfp; - case FLOAT_1BIT_FMT(CVT_PS_PW, 0): - mips32_op =3D OPC_CVT_PS_PW; - goto do_unaryfp; - - /* Floating-point moves */ - case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S): - mips32_op =3D OPC_MOV_S; - goto do_unaryfp; - case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D): - mips32_op =3D OPC_MOV_D; - goto do_unaryfp; - case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS): - mips32_op =3D OPC_MOV_PS; - goto do_unaryfp; - - /* Absolute value */ - case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S): - mips32_op =3D OPC_ABS_S; - goto do_unaryfp; - case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D): - mips32_op =3D OPC_ABS_D; - goto do_unaryfp; - case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS): - mips32_op =3D OPC_ABS_PS; - goto do_unaryfp; - - /* Negation */ - case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S): - mips32_op =3D OPC_NEG_S; - goto do_unaryfp; - case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D): - mips32_op =3D OPC_NEG_D; - goto do_unaryfp; - case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS): - mips32_op =3D OPC_NEG_PS; - goto do_unaryfp; - - /* Reciprocal square root step */ - case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S): - mips32_op =3D OPC_RSQRT1_S; - goto do_unaryfp; - case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D): - mips32_op =3D OPC_RSQRT1_D; - goto do_unaryfp; - case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS): - mips32_op =3D OPC_RSQRT1_PS; - goto do_unaryfp; - - /* Reciprocal step */ - case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S): - mips32_op =3D OPC_RECIP1_S; - goto do_unaryfp; - case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D): - mips32_op =3D OPC_RECIP1_S; - goto do_unaryfp; - case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS): - mips32_op =3D OPC_RECIP1_PS; - goto do_unaryfp; - - /* Conversions from double */ - case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S): - mips32_op =3D OPC_CVT_D_S; - goto do_unaryfp; - case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W): - mips32_op =3D OPC_CVT_D_W; - goto do_unaryfp; - case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L): - mips32_op =3D OPC_CVT_D_L; - goto do_unaryfp; - - /* Conversions from single */ - case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D): - mips32_op =3D OPC_CVT_S_D; - goto do_unaryfp; - case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W): - mips32_op =3D OPC_CVT_S_W; - goto do_unaryfp; - case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L): - mips32_op =3D OPC_CVT_S_L; - do_unaryfp: - gen_farith(ctx, mips32_op, -1, rs, rt, 0); - break; - - /* Conditional moves on floating-point codes */ - case COND_FLOAT_MOV(MOVT, 0): - case COND_FLOAT_MOV(MOVT, 1): - case COND_FLOAT_MOV(MOVT, 2): - case COND_FLOAT_MOV(MOVT, 3): - case COND_FLOAT_MOV(MOVT, 4): - case COND_FLOAT_MOV(MOVT, 5): - case COND_FLOAT_MOV(MOVT, 6): - case COND_FLOAT_MOV(MOVT, 7): - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1); - break; - case COND_FLOAT_MOV(MOVF, 0): - case COND_FLOAT_MOV(MOVF, 1): - case COND_FLOAT_MOV(MOVF, 2): - case COND_FLOAT_MOV(MOVF, 3): - case COND_FLOAT_MOV(MOVF, 4): - case COND_FLOAT_MOV(MOVF, 5): - case COND_FLOAT_MOV(MOVF, 6): - case COND_FLOAT_MOV(MOVF, 7): - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0); - break; - default: - MIPS_INVAL("pool32fxf"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) -{ - int32_t offset; - uint16_t insn; - int rt, rs, rd, rr; - int16_t imm; - uint32_t op, minor, minor2, mips32_op; - uint32_t cond, fmt, cc; - - insn =3D cpu_lduw_code(env, ctx->base.pc_next + 2); - ctx->opcode =3D (ctx->opcode << 16) | insn; - - rt =3D (ctx->opcode >> 21) & 0x1f; - rs =3D (ctx->opcode >> 16) & 0x1f; - rd =3D (ctx->opcode >> 11) & 0x1f; - rr =3D (ctx->opcode >> 6) & 0x1f; - imm =3D (int16_t) ctx->opcode; - - op =3D (ctx->opcode >> 26) & 0x3f; - switch (op) { - case POOL32A: - minor =3D ctx->opcode & 0x3f; - switch (minor) { - case 0x00: - minor =3D (ctx->opcode >> 6) & 0xf; - switch (minor) { - case SLL32: - mips32_op =3D OPC_SLL; - goto do_shifti; - case SRA: - mips32_op =3D OPC_SRA; - goto do_shifti; - case SRL32: - mips32_op =3D OPC_SRL; - goto do_shifti; - case ROTR: - mips32_op =3D OPC_ROTR; - do_shifti: - gen_shift_imm(ctx, mips32_op, rt, rs, rd); - break; - case SELEQZ: - check_insn(ctx, ISA_MIPS32R6); - gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt); - break; - case SELNEZ: - check_insn(ctx, ISA_MIPS32R6); - gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt); - break; - case R6_RDHWR: - check_insn(ctx, ISA_MIPS32R6); - gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3)); - break; - default: - goto pool32a_invalid; - } - break; - case 0x10: - minor =3D (ctx->opcode >> 6) & 0xf; - switch (minor) { - /* Arithmetic */ - case ADD: - mips32_op =3D OPC_ADD; - goto do_arith; - case ADDU32: - mips32_op =3D OPC_ADDU; - goto do_arith; - case SUB: - mips32_op =3D OPC_SUB; - goto do_arith; - case SUBU32: - mips32_op =3D OPC_SUBU; - goto do_arith; - case MUL: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MUL; - do_arith: - gen_arith(ctx, mips32_op, rd, rs, rt); - break; - /* Shifts */ - case SLLV: - mips32_op =3D OPC_SLLV; - goto do_shift; - case SRLV: - mips32_op =3D OPC_SRLV; - goto do_shift; - case SRAV: - mips32_op =3D OPC_SRAV; - goto do_shift; - case ROTRV: - mips32_op =3D OPC_ROTRV; - do_shift: - gen_shift(ctx, mips32_op, rd, rs, rt); - break; - /* Logical operations */ - case AND: - mips32_op =3D OPC_AND; - goto do_logic; - case OR32: - mips32_op =3D OPC_OR; - goto do_logic; - case NOR: - mips32_op =3D OPC_NOR; - goto do_logic; - case XOR32: - mips32_op =3D OPC_XOR; - do_logic: - gen_logic(ctx, mips32_op, rd, rs, rt); - break; - /* Set less than */ - case SLT: - mips32_op =3D OPC_SLT; - goto do_slt; - case SLTU: - mips32_op =3D OPC_SLTU; - do_slt: - gen_slt(ctx, mips32_op, rd, rs, rt); - break; - default: - goto pool32a_invalid; - } - break; - case 0x18: - minor =3D (ctx->opcode >> 6) & 0xf; - switch (minor) { - /* Conditional moves */ - case MOVN: /* MUL */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* MUL */ - gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt); - } else { - /* MOVN */ - gen_cond_move(ctx, OPC_MOVN, rd, rs, rt); - } - break; - case MOVZ: /* MUH */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* MUH */ - gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt); - } else { - /* MOVZ */ - gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt); - } - break; - case MULU: - check_insn(ctx, ISA_MIPS32R6); - gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt); - break; - case MUHU: - check_insn(ctx, ISA_MIPS32R6); - gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt); - break; - case LWXS: /* DIV */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* DIV */ - gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt); - } else { - /* LWXS */ - gen_ldxs(ctx, rs, rt, rd); - } - break; - case MOD: - check_insn(ctx, ISA_MIPS32R6); - gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt); - break; - case R6_DIVU: - check_insn(ctx, ISA_MIPS32R6); - gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt); - break; - case MODU: - check_insn(ctx, ISA_MIPS32R6); - gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt); - break; - default: - goto pool32a_invalid; - } - break; - case INS: - gen_bitops(ctx, OPC_INS, rt, rs, rr, rd); - return; - case LSA: - check_insn(ctx, ISA_MIPS32R6); - gen_lsa(ctx, OPC_LSA, rd, rs, rt, - extract32(ctx->opcode, 9, 2)); - break; - case ALIGN: - check_insn(ctx, ISA_MIPS32R6); - gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2)); - break; - case EXT: - gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd); - return; - case POOL32AXF: - gen_pool32axf(env, ctx, rt, rs); - break; - case BREAK32: - generate_exception_end(ctx, EXCP_BREAK); - break; - case SIGRIE: - check_insn(ctx, ISA_MIPS32R6); - generate_exception_end(ctx, EXCP_RI); - break; - default: - pool32a_invalid: - MIPS_INVAL("pool32a"); - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case POOL32B: - minor =3D (ctx->opcode >> 12) & 0xf; - switch (minor) { - case CACHE: - check_cp0_enabled(ctx); - if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { - gen_cache_operation(ctx, rt, rs, imm); - } - break; - case LWC2: - case SWC2: - /* COP2: Not implemented. */ - generate_exception_err(ctx, EXCP_CpU, 2); - break; -#ifdef TARGET_MIPS64 - case LDP: - case SDP: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); -#endif - /* fall through */ - case LWP: - case SWP: - gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12)); - break; -#ifdef TARGET_MIPS64 - case LDM: - case SDM: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); -#endif - /* fall through */ - case LWM32: - case SWM32: - gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12)= ); - break; - default: - MIPS_INVAL("pool32b"); - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case POOL32F: - if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { - minor =3D ctx->opcode & 0x3f; - check_cp1_enabled(ctx); - switch (minor) { - case ALNV_PS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_ALNV_PS; - goto do_madd; - case MADD_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MADD_S; - goto do_madd; - case MADD_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MADD_D; - goto do_madd; - case MADD_PS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MADD_PS; - goto do_madd; - case MSUB_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MSUB_S; - goto do_madd; - case MSUB_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MSUB_D; - goto do_madd; - case MSUB_PS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_MSUB_PS; - goto do_madd; - case NMADD_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_NMADD_S; - goto do_madd; - case NMADD_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_NMADD_D; - goto do_madd; - case NMADD_PS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_NMADD_PS; - goto do_madd; - case NMSUB_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_NMSUB_S; - goto do_madd; - case NMSUB_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_NMSUB_D; - goto do_madd; - case NMSUB_PS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_NMSUB_PS; - do_madd: - gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt); - break; - case CABS_COND_FMT: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - cond =3D (ctx->opcode >> 6) & 0xf; - cc =3D (ctx->opcode >> 13) & 0x7; - fmt =3D (ctx->opcode >> 10) & 0x3; - switch (fmt) { - case 0x0: - gen_cmpabs_s(ctx, cond, rt, rs, cc); - break; - case 0x1: - gen_cmpabs_d(ctx, cond, rt, rs, cc); - break; - case 0x2: - gen_cmpabs_ps(ctx, cond, rt, rs, cc); - break; - default: - goto pool32f_invalid; - } - break; - case C_COND_FMT: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - cond =3D (ctx->opcode >> 6) & 0xf; - cc =3D (ctx->opcode >> 13) & 0x7; - fmt =3D (ctx->opcode >> 10) & 0x3; - switch (fmt) { - case 0x0: - gen_cmp_s(ctx, cond, rt, rs, cc); - break; - case 0x1: - gen_cmp_d(ctx, cond, rt, rs, cc); - break; - case 0x2: - gen_cmp_ps(ctx, cond, rt, rs, cc); - break; - default: - goto pool32f_invalid; - } - break; - case CMP_CONDN_S: - check_insn(ctx, ISA_MIPS32R6); - gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd); - break; - case CMP_CONDN_D: - check_insn(ctx, ISA_MIPS32R6); - gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd); - break; - case POOL32FXF: - gen_pool32fxf(ctx, rt, rs); - break; - case 0x00: - /* PLL foo */ - switch ((ctx->opcode >> 6) & 0x7) { - case PLL_PS: - mips32_op =3D OPC_PLL_PS; - goto do_ps; - case PLU_PS: - mips32_op =3D OPC_PLU_PS; - goto do_ps; - case PUL_PS: - mips32_op =3D OPC_PUL_PS; - goto do_ps; - case PUU_PS: - mips32_op =3D OPC_PUU_PS; - goto do_ps; - case CVT_PS_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_CVT_PS_S; - do_ps: - gen_farith(ctx, mips32_op, rt, rs, rd, 0); - break; - default: - goto pool32f_invalid; - } - break; - case MIN_FMT: - check_insn(ctx, ISA_MIPS32R6); - switch ((ctx->opcode >> 9) & 0x3) { - case FMT_SDPS_S: - gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); - break; - case FMT_SDPS_D: - gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0); - break; - default: - goto pool32f_invalid; - } - break; - case 0x08: - /* [LS][WDU]XC1 */ - switch ((ctx->opcode >> 6) & 0x7) { - case LWXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_LWXC1; - goto do_ldst_cp1; - case SWXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_SWXC1; - goto do_ldst_cp1; - case LDXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_LDXC1; - goto do_ldst_cp1; - case SDXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_SDXC1; - goto do_ldst_cp1; - case LUXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_LUXC1; - goto do_ldst_cp1; - case SUXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_SUXC1; - do_ldst_cp1: - gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs); - break; - default: - goto pool32f_invalid; - } - break; - case MAX_FMT: - check_insn(ctx, ISA_MIPS32R6); - switch ((ctx->opcode >> 9) & 0x3) { - case FMT_SDPS_S: - gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); - break; - case FMT_SDPS_D: - gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0); - break; - default: - goto pool32f_invalid; - } - break; - case 0x18: - /* 3D insns */ - check_insn_opc_removed(ctx, ISA_MIPS32R6); - fmt =3D (ctx->opcode >> 9) & 0x3; - switch ((ctx->opcode >> 6) & 0x7) { - case RSQRT2_FMT: - switch (fmt) { - case FMT_SDPS_S: - mips32_op =3D OPC_RSQRT2_S; - goto do_3d; - case FMT_SDPS_D: - mips32_op =3D OPC_RSQRT2_D; - goto do_3d; - case FMT_SDPS_PS: - mips32_op =3D OPC_RSQRT2_PS; - goto do_3d; - default: - goto pool32f_invalid; - } - break; - case RECIP2_FMT: - switch (fmt) { - case FMT_SDPS_S: - mips32_op =3D OPC_RECIP2_S; - goto do_3d; - case FMT_SDPS_D: - mips32_op =3D OPC_RECIP2_D; - goto do_3d; - case FMT_SDPS_PS: - mips32_op =3D OPC_RECIP2_PS; - goto do_3d; - default: - goto pool32f_invalid; - } - break; - case ADDR_PS: - mips32_op =3D OPC_ADDR_PS; - goto do_3d; - case MULR_PS: - mips32_op =3D OPC_MULR_PS; - do_3d: - gen_farith(ctx, mips32_op, rt, rs, rd, 0); - break; - default: - goto pool32f_invalid; - } - break; - case 0x20: - /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/ - cc =3D (ctx->opcode >> 13) & 0x7; - fmt =3D (ctx->opcode >> 9) & 0x3; - switch ((ctx->opcode >> 6) & 0x7) { - case MOVF_FMT: /* RINT_FMT */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* RINT_FMT */ - switch (fmt) { - case FMT_SDPS_S: - gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0); - break; - case FMT_SDPS_D: - gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0); - break; - default: - goto pool32f_invalid; - } - } else { - /* MOVF_FMT */ - switch (fmt) { - case FMT_SDPS_S: - gen_movcf_s(ctx, rs, rt, cc, 0); - break; - case FMT_SDPS_D: - gen_movcf_d(ctx, rs, rt, cc, 0); - break; - case FMT_SDPS_PS: - check_ps(ctx); - gen_movcf_ps(ctx, rs, rt, cc, 0); - break; - default: - goto pool32f_invalid; - } - } - break; - case MOVT_FMT: /* CLASS_FMT */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* CLASS_FMT */ - switch (fmt) { - case FMT_SDPS_S: - gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0); - break; - case FMT_SDPS_D: - gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0); - break; - default: - goto pool32f_invalid; - } - } else { - /* MOVT_FMT */ - switch (fmt) { - case FMT_SDPS_S: - gen_movcf_s(ctx, rs, rt, cc, 1); - break; - case FMT_SDPS_D: - gen_movcf_d(ctx, rs, rt, cc, 1); - break; - case FMT_SDPS_PS: - check_ps(ctx); - gen_movcf_ps(ctx, rs, rt, cc, 1); - break; - default: - goto pool32f_invalid; - } - } - break; - case PREFX: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - break; - default: - goto pool32f_invalid; - } - break; -#define FINSN_3ARG_SDPS(prfx) \ - switch ((ctx->opcode >> 8) & 0x3) { \ - case FMT_SDPS_S: \ - mips32_op =3D OPC_##prfx##_S; \ - goto do_fpop; \ - case FMT_SDPS_D: \ - mips32_op =3D OPC_##prfx##_D; \ - goto do_fpop; \ - case FMT_SDPS_PS: \ - check_ps(ctx); \ - mips32_op =3D OPC_##prfx##_PS; \ - goto do_fpop; \ - default: \ - goto pool32f_invalid; \ - } - case MINA_FMT: - check_insn(ctx, ISA_MIPS32R6); - switch ((ctx->opcode >> 9) & 0x3) { - case FMT_SDPS_S: - gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); - break; - case FMT_SDPS_D: - gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0); - break; - default: - goto pool32f_invalid; - } - break; - case MAXA_FMT: - check_insn(ctx, ISA_MIPS32R6); - switch ((ctx->opcode >> 9) & 0x3) { - case FMT_SDPS_S: - gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); - break; - case FMT_SDPS_D: - gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0); - break; - default: - goto pool32f_invalid; - } - break; - case 0x30: - /* regular FP ops */ - switch ((ctx->opcode >> 6) & 0x3) { - case ADD_FMT: - FINSN_3ARG_SDPS(ADD); - break; - case SUB_FMT: - FINSN_3ARG_SDPS(SUB); - break; - case MUL_FMT: - FINSN_3ARG_SDPS(MUL); - break; - case DIV_FMT: - fmt =3D (ctx->opcode >> 8) & 0x3; - if (fmt =3D=3D 1) { - mips32_op =3D OPC_DIV_D; - } else if (fmt =3D=3D 0) { - mips32_op =3D OPC_DIV_S; - } else { - goto pool32f_invalid; - } - goto do_fpop; - default: - goto pool32f_invalid; - } - break; - case 0x38: - /* cmovs */ - switch ((ctx->opcode >> 6) & 0x7) { - case MOVN_FMT: /* SELEQZ_FMT */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* SELEQZ_FMT */ - switch ((ctx->opcode >> 9) & 0x3) { - case FMT_SDPS_S: - gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs); - break; - case FMT_SDPS_D: - gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs); - break; - default: - goto pool32f_invalid; - } - } else { - /* MOVN_FMT */ - FINSN_3ARG_SDPS(MOVN); - } - break; - case MOVN_FMT_04: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - FINSN_3ARG_SDPS(MOVN); - break; - case MOVZ_FMT: /* SELNEZ_FMT */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* SELNEZ_FMT */ - switch ((ctx->opcode >> 9) & 0x3) { - case FMT_SDPS_S: - gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs); - break; - case FMT_SDPS_D: - gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs); - break; - default: - goto pool32f_invalid; - } - } else { - /* MOVZ_FMT */ - FINSN_3ARG_SDPS(MOVZ); - } - break; - case MOVZ_FMT_05: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - FINSN_3ARG_SDPS(MOVZ); - break; - case SEL_FMT: - check_insn(ctx, ISA_MIPS32R6); - switch ((ctx->opcode >> 9) & 0x3) { - case FMT_SDPS_S: - gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); - break; - case FMT_SDPS_D: - gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs); - break; - default: - goto pool32f_invalid; - } - break; - case MADDF_FMT: - check_insn(ctx, ISA_MIPS32R6); - switch ((ctx->opcode >> 9) & 0x3) { - case FMT_SDPS_S: - mips32_op =3D OPC_MADDF_S; - goto do_fpop; - case FMT_SDPS_D: - mips32_op =3D OPC_MADDF_D; - goto do_fpop; - default: - goto pool32f_invalid; - } - break; - case MSUBF_FMT: - check_insn(ctx, ISA_MIPS32R6); - switch ((ctx->opcode >> 9) & 0x3) { - case FMT_SDPS_S: - mips32_op =3D OPC_MSUBF_S; - goto do_fpop; - case FMT_SDPS_D: - mips32_op =3D OPC_MSUBF_D; - goto do_fpop; - default: - goto pool32f_invalid; - } - break; - default: - goto pool32f_invalid; - } - break; - do_fpop: - gen_farith(ctx, mips32_op, rt, rs, rd, 0); - break; - default: - pool32f_invalid: - MIPS_INVAL("pool32f"); - generate_exception_end(ctx, EXCP_RI); - break; - } - } else { - generate_exception_err(ctx, EXCP_CpU, 1); - } - break; - case POOL32I: - minor =3D (ctx->opcode >> 21) & 0x1f; - switch (minor) { - case BLTZ: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4); - break; - case BLTZAL: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - break; - case BLTZALS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - break; - case BGEZ: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4); - break; - case BGEZAL: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - break; - case BGEZALS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - break; - case BLEZ: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4); - break; - case BGTZ: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4); - break; - - /* Traps */ - case TLTI: /* BC1EQZC */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* BC1EQZC */ - check_cp1_enabled(ctx); - gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0); - } else { - /* TLTI */ - mips32_op =3D OPC_TLTI; - goto do_trapi; - } - break; - case TGEI: /* BC1NEZC */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* BC1NEZC */ - check_cp1_enabled(ctx); - gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0); - } else { - /* TGEI */ - mips32_op =3D OPC_TGEI; - goto do_trapi; - } - break; - case TLTIU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_TLTIU; - goto do_trapi; - case TGEIU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_TGEIU; - goto do_trapi; - case TNEI: /* SYNCI */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* SYNCI */ - /* - * Break the TB to be able to sync copied instructions - * immediately. - */ - ctx->base.is_jmp =3D DISAS_STOP; - } else { - /* TNEI */ - mips32_op =3D OPC_TNEI; - goto do_trapi; - } - break; - case TEQI: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_TEQI; - do_trapi: - gen_trap(ctx, mips32_op, rs, -1, imm); - break; - - case BNEZC: - case BEQZC: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_compute_branch(ctx, minor =3D=3D BNEZC ? OPC_BNE : OPC_BEQ, - 4, rs, 0, imm << 1, 0); - /* - * Compact branches don't have a delay slot, so just let - * the normal delay slot handling take us to the branch - * target. - */ - break; - case LUI: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - gen_logic_imm(ctx, OPC_LUI, rs, 0, imm); - break; - case SYNCI: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - /* - * Break the TB to be able to sync copied instructions - * immediately. - */ - ctx->base.is_jmp =3D DISAS_STOP; - break; - case BC2F: - case BC2T: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - /* COP2: Not implemented. */ - generate_exception_err(ctx, EXCP_CpU, 2); - break; - case BC1F: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_B= C1F; - goto do_cp1branch; - case BC1T: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_B= C1T; - goto do_cp1branch; - case BC1ANY4F: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_BC1FANY4; - goto do_cp1mips3d; - case BC1ANY4T: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_BC1TANY4; - do_cp1mips3d: - check_cop1x(ctx); - check_insn(ctx, ASE_MIPS3D); - /* Fall through */ - do_cp1branch: - if (env->CP0_Config1 & (1 << CP0C1_FP)) { - check_cp1_enabled(ctx); - gen_compute_branch1(ctx, mips32_op, - (ctx->opcode >> 18) & 0x7, imm << 1); - } else { - generate_exception_err(ctx, EXCP_CpU, 1); - } - break; - case BPOSGE64: - case BPOSGE32: - /* MIPS DSP: not implemented */ - /* Fall through */ - default: - MIPS_INVAL("pool32i"); - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case POOL32C: - minor =3D (ctx->opcode >> 12) & 0xf; - offset =3D sextract32(ctx->opcode, 0, - (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12); - switch (minor) { - case LWL: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_LWL; - goto do_ld_lr; - case SWL: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_SWL; - goto do_st_lr; - case LWR: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_LWR; - goto do_ld_lr; - case SWR: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_SWR; - goto do_st_lr; -#if defined(TARGET_MIPS64) - case LDL: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_LDL; - goto do_ld_lr; - case SDL: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_SDL; - goto do_st_lr; - case LDR: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_LDR; - goto do_ld_lr; - case SDR: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_SDR; - goto do_st_lr; - case LWU: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - mips32_op =3D OPC_LWU; - goto do_ld_lr; - case LLD: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - mips32_op =3D OPC_LLD; - goto do_ld_lr; -#endif - case LL: - mips32_op =3D OPC_LL; - goto do_ld_lr; - do_ld_lr: - gen_ld(ctx, mips32_op, rt, rs, offset); - break; - do_st_lr: - gen_st(ctx, mips32_op, rt, rs, offset); - break; - case SC: - gen_st_cond(ctx, rt, rs, offset, MO_TESL, false); - break; -#if defined(TARGET_MIPS64) - case SCD: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false); - break; -#endif - case LD_EVA: - if (!ctx->eva) { - MIPS_INVAL("pool32c ld-eva"); - generate_exception_end(ctx, EXCP_RI); - break; - } - check_cp0_enabled(ctx); - - minor2 =3D (ctx->opcode >> 9) & 0x7; - offset =3D sextract32(ctx->opcode, 0, 9); - switch (minor2) { - case LBUE: - mips32_op =3D OPC_LBUE; - goto do_ld_lr; - case LHUE: - mips32_op =3D OPC_LHUE; - goto do_ld_lr; - case LWLE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_LWLE; - goto do_ld_lr; - case LWRE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_LWRE; - goto do_ld_lr; - case LBE: - mips32_op =3D OPC_LBE; - goto do_ld_lr; - case LHE: - mips32_op =3D OPC_LHE; - goto do_ld_lr; - case LLE: - mips32_op =3D OPC_LLE; - goto do_ld_lr; - case LWE: - mips32_op =3D OPC_LWE; - goto do_ld_lr; - }; - break; - case ST_EVA: - if (!ctx->eva) { - MIPS_INVAL("pool32c st-eva"); - generate_exception_end(ctx, EXCP_RI); - break; - } - check_cp0_enabled(ctx); - - minor2 =3D (ctx->opcode >> 9) & 0x7; - offset =3D sextract32(ctx->opcode, 0, 9); - switch (minor2) { - case SWLE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_SWLE; - goto do_st_lr; - case SWRE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - mips32_op =3D OPC_SWRE; - goto do_st_lr; - case PREFE: - /* Treat as no-op */ - if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >=3D 24)) { - /* hint codes 24-31 are reserved and signal RI */ - generate_exception(ctx, EXCP_RI); - } - break; - case CACHEE: - /* Treat as no-op */ - if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { - gen_cache_operation(ctx, rt, rs, offset); - } - break; - case SBE: - mips32_op =3D OPC_SBE; - goto do_st_lr; - case SHE: - mips32_op =3D OPC_SHE; - goto do_st_lr; - case SCE: - gen_st_cond(ctx, rt, rs, offset, MO_TESL, true); - break; - case SWE: - mips32_op =3D OPC_SWE; - goto do_st_lr; - }; - break; - case PREF: - /* Treat as no-op */ - if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >=3D 24)) { - /* hint codes 24-31 are reserved and signal RI */ - generate_exception(ctx, EXCP_RI); - } - break; - default: - MIPS_INVAL("pool32c"); - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case ADDI32: /* AUI, LUI */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* AUI, LUI */ - gen_logic_imm(ctx, OPC_LUI, rt, rs, imm); - } else { - /* ADDI32 */ - mips32_op =3D OPC_ADDI; - goto do_addi; - } - break; - case ADDIU32: - mips32_op =3D OPC_ADDIU; - do_addi: - gen_arith_imm(ctx, mips32_op, rt, rs, imm); - break; - - /* Logical operations */ - case ORI32: - mips32_op =3D OPC_ORI; - goto do_logici; - case XORI32: - mips32_op =3D OPC_XORI; - goto do_logici; - case ANDI32: - mips32_op =3D OPC_ANDI; - do_logici: - gen_logic_imm(ctx, mips32_op, rt, rs, imm); - break; - - /* Set less than immediate */ - case SLTI32: - mips32_op =3D OPC_SLTI; - goto do_slti; - case SLTIU32: - mips32_op =3D OPC_SLTIU; - do_slti: - gen_slt_imm(ctx, mips32_op, rt, rs, imm); - break; - case JALX32: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - offset =3D (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; - gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - break; - case JALS32: /* BOVC, BEQC, BEQZALC */ - if (ctx->insn_flags & ISA_MIPS32R6) { - if (rs >=3D rt) { - /* BOVC */ - mips32_op =3D OPC_BOVC; - } else if (rs < rt && rs =3D=3D 0) { - /* BEQZALC */ - mips32_op =3D OPC_BEQZALC; - } else { - /* BEQC */ - mips32_op =3D OPC_BEQC; - } - gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); - } else { - /* JALS32 */ - offset =3D (int32_t)(ctx->opcode & 0x3FFFFFF) << 1; - gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - } - break; - case BEQ32: /* BC */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* BC */ - gen_compute_compact_branch(ctx, OPC_BC, 0, 0, - sextract32(ctx->opcode << 1, 0, 27)= ); - } else { - /* BEQ32 */ - gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4); - } - break; - case BNE32: /* BALC */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* BALC */ - gen_compute_compact_branch(ctx, OPC_BALC, 0, 0, - sextract32(ctx->opcode << 1, 0, 27)= ); - } else { - /* BNE32 */ - gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4); - } - break; - case J32: /* BGTZC, BLTZC, BLTC */ - if (ctx->insn_flags & ISA_MIPS32R6) { - if (rs =3D=3D 0 && rt !=3D 0) { - /* BGTZC */ - mips32_op =3D OPC_BGTZC; - } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { - /* BLTZC */ - mips32_op =3D OPC_BLTZC; - } else { - /* BLTC */ - mips32_op =3D OPC_BLTC; - } - gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); - } else { - /* J32 */ - gen_compute_branch(ctx, OPC_J, 4, rt, rs, - (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4); - } - break; - case JAL32: /* BLEZC, BGEZC, BGEC */ - if (ctx->insn_flags & ISA_MIPS32R6) { - if (rs =3D=3D 0 && rt !=3D 0) { - /* BLEZC */ - mips32_op =3D OPC_BLEZC; - } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { - /* BGEZC */ - mips32_op =3D OPC_BGEZC; - } else { - /* BGEC */ - mips32_op =3D OPC_BGEC; - } - gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); - } else { - /* JAL32 */ - gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, - (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4); - ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; - } - break; - /* Floating point (COP1) */ - case LWC132: - mips32_op =3D OPC_LWC1; - goto do_cop1; - case LDC132: - mips32_op =3D OPC_LDC1; - goto do_cop1; - case SWC132: - mips32_op =3D OPC_SWC1; - goto do_cop1; - case SDC132: - mips32_op =3D OPC_SDC1; - do_cop1: - gen_cop1_ldst(ctx, mips32_op, rt, rs, imm); - break; - case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */ - if (ctx->insn_flags & ISA_MIPS32R6) { - /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */ - switch ((ctx->opcode >> 16) & 0x1f) { - case ADDIUPC_00: - case ADDIUPC_01: - case ADDIUPC_02: - case ADDIUPC_03: - case ADDIUPC_04: - case ADDIUPC_05: - case ADDIUPC_06: - case ADDIUPC_07: - gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt); - break; - case AUIPC: - gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt); - break; - case ALUIPC: - gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt); - break; - case LWPC_08: - case LWPC_09: - case LWPC_0A: - case LWPC_0B: - case LWPC_0C: - case LWPC_0D: - case LWPC_0E: - case LWPC_0F: - gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt); - break; - default: - generate_exception(ctx, EXCP_RI); - break; - } - } else { - /* ADDIUPC */ - int reg =3D mmreg(ZIMM(ctx->opcode, 23, 3)); - offset =3D SIMM(ctx->opcode, 0, 23) << 2; - - gen_addiupc(ctx, reg, offset, 0, 0); - } - break; - case BNVC: /* BNEC, BNEZALC */ - check_insn(ctx, ISA_MIPS32R6); - if (rs >=3D rt) { - /* BNVC */ - mips32_op =3D OPC_BNVC; - } else if (rs < rt && rs =3D=3D 0) { - /* BNEZALC */ - mips32_op =3D OPC_BNEZALC; - } else { - /* BNEC */ - mips32_op =3D OPC_BNEC; - } - gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); - break; - case R6_BNEZC: /* JIALC */ - check_insn(ctx, ISA_MIPS32R6); - if (rt !=3D 0) { - /* BNEZC */ - gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0, - sextract32(ctx->opcode << 1, 0, 22)= ); - } else { - /* JIALC */ - gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm); - } - break; - case R6_BEQZC: /* JIC */ - check_insn(ctx, ISA_MIPS32R6); - if (rt !=3D 0) { - /* BEQZC */ - gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0, - sextract32(ctx->opcode << 1, 0, 22)= ); - } else { - /* JIC */ - gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm); - } - break; - case BLEZALC: /* BGEZALC, BGEUC */ - check_insn(ctx, ISA_MIPS32R6); - if (rs =3D=3D 0 && rt !=3D 0) { - /* BLEZALC */ - mips32_op =3D OPC_BLEZALC; - } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { - /* BGEZALC */ - mips32_op =3D OPC_BGEZALC; - } else { - /* BGEUC */ - mips32_op =3D OPC_BGEUC; - } - gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); - break; - case BGTZALC: /* BLTZALC, BLTUC */ - check_insn(ctx, ISA_MIPS32R6); - if (rs =3D=3D 0 && rt !=3D 0) { - /* BGTZALC */ - mips32_op =3D OPC_BGTZALC; - } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { - /* BLTZALC */ - mips32_op =3D OPC_BLTZALC; - } else { - /* BLTUC */ - mips32_op =3D OPC_BLTUC; - } - gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); - break; - /* Loads and stores */ - case LB32: - mips32_op =3D OPC_LB; - goto do_ld; - case LBU32: - mips32_op =3D OPC_LBU; - goto do_ld; - case LH32: - mips32_op =3D OPC_LH; - goto do_ld; - case LHU32: - mips32_op =3D OPC_LHU; - goto do_ld; - case LW32: - mips32_op =3D OPC_LW; - goto do_ld; -#ifdef TARGET_MIPS64 - case LD32: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - mips32_op =3D OPC_LD; - goto do_ld; - case SD32: - check_insn(ctx, ISA_MIPS3); - check_mips_64(ctx); - mips32_op =3D OPC_SD; - goto do_st; -#endif - case SB32: - mips32_op =3D OPC_SB; - goto do_st; - case SH32: - mips32_op =3D OPC_SH; - goto do_st; - case SW32: - mips32_op =3D OPC_SW; - goto do_st; - do_ld: - gen_ld(ctx, mips32_op, rt, rs, imm); - break; - do_st: - gen_st(ctx, mips32_op, rt, rs, imm); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t op; - - /* make sure instructions are on a halfword boundary */ - if (ctx->base.pc_next & 0x1) { - env->CP0_BadVAddr =3D ctx->base.pc_next; - generate_exception_end(ctx, EXCP_AdEL); - return 2; - } - - op =3D (ctx->opcode >> 10) & 0x3f; - /* Enforce properly-sized instructions in a delay slot */ - if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) { - switch (op & 0x7) { /* MSB-3..MSB-5 */ - case 0: - /* POOL32A, POOL32B, POOL32I, POOL32C */ - case 4: - /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32= */ - case 5: - /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */ - case 6: - /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */ - case 7: - /* LB32, LH32, LWC132, LDC132, LW32 */ - if (ctx->hflags & MIPS_HFLAG_BDS16) { - generate_exception_end(ctx, EXCP_RI); - return 2; - } - break; - case 1: - /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */ - case 2: - /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */ - case 3: - /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */ - if (ctx->hflags & MIPS_HFLAG_BDS32) { - generate_exception_end(ctx, EXCP_RI); - return 2; - } - break; - } - } - - switch (op) { - case POOL16A: - { - int rd =3D mmreg(uMIPS_RD(ctx->opcode)); - int rs1 =3D mmreg(uMIPS_RS1(ctx->opcode)); - int rs2 =3D mmreg(uMIPS_RS2(ctx->opcode)); - uint32_t opc =3D 0; - - switch (ctx->opcode & 0x1) { - case ADDU16: - opc =3D OPC_ADDU; - break; - case SUBU16: - opc =3D OPC_SUBU; - break; - } - if (ctx->insn_flags & ISA_MIPS32R6) { - /* - * In the Release 6, the register number location in - * the instruction encoding has changed. - */ - gen_arith(ctx, opc, rs1, rd, rs2); - } else { - gen_arith(ctx, opc, rd, rs1, rs2); - } - } - break; - case POOL16B: - { - int rd =3D mmreg(uMIPS_RD(ctx->opcode)); - int rs =3D mmreg(uMIPS_RS(ctx->opcode)); - int amount =3D (ctx->opcode >> 1) & 0x7; - uint32_t opc =3D 0; - amount =3D amount =3D=3D 0 ? 8 : amount; - - switch (ctx->opcode & 0x1) { - case SLL16: - opc =3D OPC_SLL; - break; - case SRL16: - opc =3D OPC_SRL; - break; - } - - gen_shift_imm(ctx, opc, rd, rs, amount); - } - break; - case POOL16C: - if (ctx->insn_flags & ISA_MIPS32R6) { - gen_pool16c_r6_insn(ctx); - } else { - gen_pool16c_insn(ctx); - } - break; - case LWGP16: - { - int rd =3D mmreg(uMIPS_RD(ctx->opcode)); - int rb =3D 28; /* GP */ - int16_t offset =3D SIMM(ctx->opcode, 0, 7) << 2; - - gen_ld(ctx, OPC_LW, rd, rb, offset); - } - break; - case POOL16F: - check_insn_opc_removed(ctx, ISA_MIPS32R6); - if (ctx->opcode & 1) { - generate_exception_end(ctx, EXCP_RI); - } else { - /* MOVEP */ - int enc_dest =3D uMIPS_RD(ctx->opcode); - int enc_rt =3D uMIPS_RS2(ctx->opcode); - int enc_rs =3D uMIPS_RS1(ctx->opcode); - gen_movep(ctx, enc_dest, enc_rt, enc_rs); - } - break; - case LBU16: - { - int rd =3D mmreg(uMIPS_RD(ctx->opcode)); - int rb =3D mmreg(uMIPS_RS(ctx->opcode)); - int16_t offset =3D ZIMM(ctx->opcode, 0, 4); - offset =3D (offset =3D=3D 0xf ? -1 : offset); - - gen_ld(ctx, OPC_LBU, rd, rb, offset); - } - break; - case LHU16: - { - int rd =3D mmreg(uMIPS_RD(ctx->opcode)); - int rb =3D mmreg(uMIPS_RS(ctx->opcode)); - int16_t offset =3D ZIMM(ctx->opcode, 0, 4) << 1; - - gen_ld(ctx, OPC_LHU, rd, rb, offset); - } - break; - case LWSP16: - { - int rd =3D (ctx->opcode >> 5) & 0x1f; - int rb =3D 29; /* SP */ - int16_t offset =3D ZIMM(ctx->opcode, 0, 5) << 2; - - gen_ld(ctx, OPC_LW, rd, rb, offset); - } - break; - case LW16: - { - int rd =3D mmreg(uMIPS_RD(ctx->opcode)); - int rb =3D mmreg(uMIPS_RS(ctx->opcode)); - int16_t offset =3D ZIMM(ctx->opcode, 0, 4) << 2; - - gen_ld(ctx, OPC_LW, rd, rb, offset); - } - break; - case SB16: - { - int rd =3D mmreg2(uMIPS_RD(ctx->opcode)); - int rb =3D mmreg(uMIPS_RS(ctx->opcode)); - int16_t offset =3D ZIMM(ctx->opcode, 0, 4); - - gen_st(ctx, OPC_SB, rd, rb, offset); - } - break; - case SH16: - { - int rd =3D mmreg2(uMIPS_RD(ctx->opcode)); - int rb =3D mmreg(uMIPS_RS(ctx->opcode)); - int16_t offset =3D ZIMM(ctx->opcode, 0, 4) << 1; - - gen_st(ctx, OPC_SH, rd, rb, offset); - } - break; - case SWSP16: - { - int rd =3D (ctx->opcode >> 5) & 0x1f; - int rb =3D 29; /* SP */ - int16_t offset =3D ZIMM(ctx->opcode, 0, 5) << 2; - - gen_st(ctx, OPC_SW, rd, rb, offset); - } - break; - case SW16: - { - int rd =3D mmreg2(uMIPS_RD(ctx->opcode)); - int rb =3D mmreg(uMIPS_RS(ctx->opcode)); - int16_t offset =3D ZIMM(ctx->opcode, 0, 4) << 2; - - gen_st(ctx, OPC_SW, rd, rb, offset); - } - break; - case MOVE16: - { - int rd =3D uMIPS_RD5(ctx->opcode); - int rs =3D uMIPS_RS5(ctx->opcode); - - gen_arith(ctx, OPC_ADDU, rd, rs, 0); - } - break; - case ANDI16: - gen_andi16(ctx); - break; - case POOL16D: - switch (ctx->opcode & 0x1) { - case ADDIUS5: - gen_addius5(ctx); - break; - case ADDIUSP: - gen_addiusp(ctx); - break; - } - break; - case POOL16E: - switch (ctx->opcode & 0x1) { - case ADDIUR2: - gen_addiur2(ctx); - break; - case ADDIUR1SP: - gen_addiur1sp(ctx); - break; - } - break; - case B16: /* BC16 */ - gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, - sextract32(ctx->opcode, 0, 10) << 1, - (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4); - break; - case BNEZ16: /* BNEZC16 */ - case BEQZ16: /* BEQZC16 */ - gen_compute_branch(ctx, op =3D=3D BNEZ16 ? OPC_BNE : OPC_BEQ, 2, - mmreg(uMIPS_RD(ctx->opcode)), - 0, sextract32(ctx->opcode, 0, 7) << 1, - (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4); - - break; - case LI16: - { - int reg =3D mmreg(uMIPS_RD(ctx->opcode)); - int imm =3D ZIMM(ctx->opcode, 0, 7); - - imm =3D (imm =3D=3D 0x7f ? -1 : imm); - tcg_gen_movi_tl(cpu_gpr[reg], imm); - } - break; - case RES_29: - case RES_31: - case RES_39: - generate_exception_end(ctx, EXCP_RI); - break; - default: - decode_micromips32_opc(env, ctx); - return 4; - } - - return 2; -} +#include "isa-micromips_translate.c.inc" =20 /* * diff --git a/target/mips/isa-micromips_translate.c.inc b/target/mips/isa-mi= cromips_translate.c.inc new file mode 100644 index 00000000000..c5e2c844c4b --- /dev/null +++ b/target/mips/isa-micromips_translate.c.inc @@ -0,0 +1,3316 @@ +/* + * microMIPS translation routines + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +/* + * microMIPS32/microMIPS64 major opcodes + * + * 1. MIPS Architecture for Programmers Volume II-B: + * The microMIPS32 Instruction Set (Revision 3.05) + * + * Table 6.2 microMIPS32 Encoding of Major Opcode Field + * + * 2. MIPS Architecture For Programmers Volume II-A: + * The MIPS64 Instruction Set (Revision 3.51) + */ + +enum { + POOL32A =3D 0x00, + POOL16A =3D 0x01, + LBU16 =3D 0x02, + MOVE16 =3D 0x03, + ADDI32 =3D 0x04, + R6_LUI =3D 0x04, + AUI =3D 0x04, + LBU32 =3D 0x05, + SB32 =3D 0x06, + LB32 =3D 0x07, + + POOL32B =3D 0x08, + POOL16B =3D 0x09, + LHU16 =3D 0x0a, + ANDI16 =3D 0x0b, + ADDIU32 =3D 0x0c, + LHU32 =3D 0x0d, + SH32 =3D 0x0e, + LH32 =3D 0x0f, + + POOL32I =3D 0x10, + POOL16C =3D 0x11, + LWSP16 =3D 0x12, + POOL16D =3D 0x13, + ORI32 =3D 0x14, + POOL32F =3D 0x15, + POOL32S =3D 0x16, /* MIPS64 */ + DADDIU32 =3D 0x17, /* MIPS64 */ + + POOL32C =3D 0x18, + LWGP16 =3D 0x19, + LW16 =3D 0x1a, + POOL16E =3D 0x1b, + XORI32 =3D 0x1c, + JALS32 =3D 0x1d, + BOVC =3D 0x1d, + BEQC =3D 0x1d, + BEQZALC =3D 0x1d, + ADDIUPC =3D 0x1e, + PCREL =3D 0x1e, + BNVC =3D 0x1f, + BNEC =3D 0x1f, + BNEZALC =3D 0x1f, + + R6_BEQZC =3D 0x20, + JIC =3D 0x20, + POOL16F =3D 0x21, + SB16 =3D 0x22, + BEQZ16 =3D 0x23, + BEQZC16 =3D 0x23, + SLTI32 =3D 0x24, + BEQ32 =3D 0x25, + BC =3D 0x25, + SWC132 =3D 0x26, + LWC132 =3D 0x27, + + /* 0x29 is reserved */ + RES_29 =3D 0x29, + R6_BNEZC =3D 0x28, + JIALC =3D 0x28, + SH16 =3D 0x2a, + BNEZ16 =3D 0x2b, + BNEZC16 =3D 0x2b, + SLTIU32 =3D 0x2c, + BNE32 =3D 0x2d, + BALC =3D 0x2d, + SDC132 =3D 0x2e, + LDC132 =3D 0x2f, + + /* 0x31 is reserved */ + RES_31 =3D 0x31, + BLEZALC =3D 0x30, + BGEZALC =3D 0x30, + BGEUC =3D 0x30, + SWSP16 =3D 0x32, + B16 =3D 0x33, + BC16 =3D 0x33, + ANDI32 =3D 0x34, + J32 =3D 0x35, + BGTZC =3D 0x35, + BLTZC =3D 0x35, + BLTC =3D 0x35, + SD32 =3D 0x36, /* MIPS64 */ + LD32 =3D 0x37, /* MIPS64 */ + + /* 0x39 is reserved */ + RES_39 =3D 0x39, + BGTZALC =3D 0x38, + BLTZALC =3D 0x38, + BLTUC =3D 0x38, + SW16 =3D 0x3a, + LI16 =3D 0x3b, + JALX32 =3D 0x3c, + JAL32 =3D 0x3d, + BLEZC =3D 0x3d, + BGEZC =3D 0x3d, + BGEC =3D 0x3d, + SW32 =3D 0x3e, + LW32 =3D 0x3f +}; + +/* PCREL Instructions perform PC-Relative address calculation. bits 20..16= */ +enum { + ADDIUPC_00 =3D 0x00, + ADDIUPC_01 =3D 0x01, + ADDIUPC_02 =3D 0x02, + ADDIUPC_03 =3D 0x03, + ADDIUPC_04 =3D 0x04, + ADDIUPC_05 =3D 0x05, + ADDIUPC_06 =3D 0x06, + ADDIUPC_07 =3D 0x07, + AUIPC =3D 0x1e, + ALUIPC =3D 0x1f, + LWPC_08 =3D 0x08, + LWPC_09 =3D 0x09, + LWPC_0A =3D 0x0A, + LWPC_0B =3D 0x0B, + LWPC_0C =3D 0x0C, + LWPC_0D =3D 0x0D, + LWPC_0E =3D 0x0E, + LWPC_0F =3D 0x0F, +}; + +/* POOL32A encoding of minor opcode field */ + +enum { + /* + * These opcodes are distinguished only by bits 9..6; those bits are + * what are recorded below. + */ + SLL32 =3D 0x0, + SRL32 =3D 0x1, + SRA =3D 0x2, + ROTR =3D 0x3, + SELEQZ =3D 0x5, + SELNEZ =3D 0x6, + R6_RDHWR =3D 0x7, + + SLLV =3D 0x0, + SRLV =3D 0x1, + SRAV =3D 0x2, + ROTRV =3D 0x3, + ADD =3D 0x4, + ADDU32 =3D 0x5, + SUB =3D 0x6, + SUBU32 =3D 0x7, + MUL =3D 0x8, + AND =3D 0x9, + OR32 =3D 0xa, + NOR =3D 0xb, + XOR32 =3D 0xc, + SLT =3D 0xd, + SLTU =3D 0xe, + + MOVN =3D 0x0, + R6_MUL =3D 0x0, + MOVZ =3D 0x1, + MUH =3D 0x1, + MULU =3D 0x2, + MUHU =3D 0x3, + LWXS =3D 0x4, + R6_DIV =3D 0x4, + MOD =3D 0x5, + R6_DIVU =3D 0x6, + MODU =3D 0x7, + + /* The following can be distinguished by their lower 6 bits. */ + BREAK32 =3D 0x07, + INS =3D 0x0c, + LSA =3D 0x0f, + ALIGN =3D 0x1f, + EXT =3D 0x2c, + POOL32AXF =3D 0x3c, + SIGRIE =3D 0x3f +}; + +/* POOL32AXF encoding of minor opcode field extension */ + +/* + * 1. MIPS Architecture for Programmers Volume II-B: + * The microMIPS32 Instruction Set (Revision 3.05) + * + * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field + * + * 2. MIPS Architecture for Programmers VolumeIV-e: + * The MIPS DSP Application-Specific Extension + * to the microMIPS32 Architecture (Revision 2.34) + * + * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field + */ + +enum { + /* bits 11..6 */ + TEQ =3D 0x00, + TGE =3D 0x08, + TGEU =3D 0x10, + TLT =3D 0x20, + TLTU =3D 0x28, + TNE =3D 0x30, + + MFC0 =3D 0x03, + MTC0 =3D 0x0b, + + /* begin of microMIPS32 DSP */ + + /* bits 13..12 for 0x01 */ + MFHI_ACC =3D 0x0, + MFLO_ACC =3D 0x1, + MTHI_ACC =3D 0x2, + MTLO_ACC =3D 0x3, + + /* bits 13..12 for 0x2a */ + MADD_ACC =3D 0x0, + MADDU_ACC =3D 0x1, + MSUB_ACC =3D 0x2, + MSUBU_ACC =3D 0x3, + + /* bits 13..12 for 0x32 */ + MULT_ACC =3D 0x0, + MULTU_ACC =3D 0x1, + + /* end of microMIPS32 DSP */ + + /* bits 15..12 for 0x2c */ + BITSWAP =3D 0x0, + SEB =3D 0x2, + SEH =3D 0x3, + CLO =3D 0x4, + CLZ =3D 0x5, + RDHWR =3D 0x6, + WSBH =3D 0x7, + MULT =3D 0x8, + MULTU =3D 0x9, + DIV =3D 0xa, + DIVU =3D 0xb, + MADD =3D 0xc, + MADDU =3D 0xd, + MSUB =3D 0xe, + MSUBU =3D 0xf, + + /* bits 15..12 for 0x34 */ + MFC2 =3D 0x4, + MTC2 =3D 0x5, + MFHC2 =3D 0x8, + MTHC2 =3D 0x9, + CFC2 =3D 0xc, + CTC2 =3D 0xd, + + /* bits 15..12 for 0x3c */ + JALR =3D 0x0, + JR =3D 0x0, /* alias */ + JALRC =3D 0x0, + JRC =3D 0x0, + JALR_HB =3D 0x1, + JALRC_HB =3D 0x1, + JALRS =3D 0x4, + JALRS_HB =3D 0x5, + + /* bits 15..12 for 0x05 */ + RDPGPR =3D 0xe, + WRPGPR =3D 0xf, + + /* bits 15..12 for 0x0d */ + TLBP =3D 0x0, + TLBR =3D 0x1, + TLBWI =3D 0x2, + TLBWR =3D 0x3, + TLBINV =3D 0x4, + TLBINVF =3D 0x5, + WAIT =3D 0x9, + IRET =3D 0xd, + DERET =3D 0xe, + ERET =3D 0xf, + + /* bits 15..12 for 0x15 */ + DMT =3D 0x0, + DVPE =3D 0x1, + EMT =3D 0x2, + EVPE =3D 0x3, + + /* bits 15..12 for 0x1d */ + DI =3D 0x4, + EI =3D 0x5, + + /* bits 15..12 for 0x2d */ + SYNC =3D 0x6, + SYSCALL =3D 0x8, + SDBBP =3D 0xd, + + /* bits 15..12 for 0x35 */ + MFHI32 =3D 0x0, + MFLO32 =3D 0x1, + MTHI32 =3D 0x2, + MTLO32 =3D 0x3, +}; + +/* POOL32B encoding of minor opcode field (bits 15..12) */ + +enum { + LWC2 =3D 0x0, + LWP =3D 0x1, + LDP =3D 0x4, + LWM32 =3D 0x5, + CACHE =3D 0x6, + LDM =3D 0x7, + SWC2 =3D 0x8, + SWP =3D 0x9, + SDP =3D 0xc, + SWM32 =3D 0xd, + SDM =3D 0xf +}; + +/* POOL32C encoding of minor opcode field (bits 15..12) */ + +enum { + LWL =3D 0x0, + SWL =3D 0x8, + LWR =3D 0x1, + SWR =3D 0x9, + PREF =3D 0x2, + ST_EVA =3D 0xa, + LL =3D 0x3, + SC =3D 0xb, + LDL =3D 0x4, + SDL =3D 0xc, + LDR =3D 0x5, + SDR =3D 0xd, + LD_EVA =3D 0x6, + LWU =3D 0xe, + LLD =3D 0x7, + SCD =3D 0xf +}; + +/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */ + +enum { + LBUE =3D 0x0, + LHUE =3D 0x1, + LWLE =3D 0x2, + LWRE =3D 0x3, + LBE =3D 0x4, + LHE =3D 0x5, + LLE =3D 0x6, + LWE =3D 0x7, +}; + +/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */ + +enum { + SWLE =3D 0x0, + SWRE =3D 0x1, + PREFE =3D 0x2, + CACHEE =3D 0x3, + SBE =3D 0x4, + SHE =3D 0x5, + SCE =3D 0x6, + SWE =3D 0x7, +}; + +/* POOL32F encoding of minor opcode field (bits 5..0) */ + +enum { + /* These are the bit 7..6 values */ + ADD_FMT =3D 0x0, + + SUB_FMT =3D 0x1, + + MUL_FMT =3D 0x2, + + DIV_FMT =3D 0x3, + + /* These are the bit 8..6 values */ + MOVN_FMT =3D 0x0, + RSQRT2_FMT =3D 0x0, + MOVF_FMT =3D 0x0, + RINT_FMT =3D 0x0, + SELNEZ_FMT =3D 0x0, + + MOVZ_FMT =3D 0x1, + LWXC1 =3D 0x1, + MOVT_FMT =3D 0x1, + CLASS_FMT =3D 0x1, + SELEQZ_FMT =3D 0x1, + + PLL_PS =3D 0x2, + SWXC1 =3D 0x2, + SEL_FMT =3D 0x2, + + PLU_PS =3D 0x3, + LDXC1 =3D 0x3, + + MOVN_FMT_04 =3D 0x4, + PUL_PS =3D 0x4, + SDXC1 =3D 0x4, + RECIP2_FMT =3D 0x4, + + MOVZ_FMT_05 =3D 0x05, + PUU_PS =3D 0x5, + LUXC1 =3D 0x5, + + CVT_PS_S =3D 0x6, + SUXC1 =3D 0x6, + ADDR_PS =3D 0x6, + PREFX =3D 0x6, + MADDF_FMT =3D 0x6, + + MULR_PS =3D 0x7, + MSUBF_FMT =3D 0x7, + + MADD_S =3D 0x01, + MADD_D =3D 0x09, + MADD_PS =3D 0x11, + ALNV_PS =3D 0x19, + MSUB_S =3D 0x21, + MSUB_D =3D 0x29, + MSUB_PS =3D 0x31, + + NMADD_S =3D 0x02, + NMADD_D =3D 0x0a, + NMADD_PS =3D 0x12, + NMSUB_S =3D 0x22, + NMSUB_D =3D 0x2a, + NMSUB_PS =3D 0x32, + + MIN_FMT =3D 0x3, + MAX_FMT =3D 0xb, + MINA_FMT =3D 0x23, + MAXA_FMT =3D 0x2b, + POOL32FXF =3D 0x3b, + + CABS_COND_FMT =3D 0x1c, /* MIPS3D */ + C_COND_FMT =3D 0x3c, + + CMP_CONDN_S =3D 0x5, + CMP_CONDN_D =3D 0x15 +}; + +/* POOL32Fxf encoding of minor opcode extension field */ + +enum { + CVT_L =3D 0x04, + RSQRT_FMT =3D 0x08, + FLOOR_L =3D 0x0c, + CVT_PW_PS =3D 0x1c, + CVT_W =3D 0x24, + SQRT_FMT =3D 0x28, + FLOOR_W =3D 0x2c, + CVT_PS_PW =3D 0x3c, + CFC1 =3D 0x40, + RECIP_FMT =3D 0x48, + CEIL_L =3D 0x4c, + CTC1 =3D 0x60, + CEIL_W =3D 0x6c, + MFC1 =3D 0x80, + CVT_S_PL =3D 0x84, + TRUNC_L =3D 0x8c, + MTC1 =3D 0xa0, + CVT_S_PU =3D 0xa4, + TRUNC_W =3D 0xac, + MFHC1 =3D 0xc0, + ROUND_L =3D 0xcc, + MTHC1 =3D 0xe0, + ROUND_W =3D 0xec, + + MOV_FMT =3D 0x01, + MOVF =3D 0x05, + ABS_FMT =3D 0x0d, + RSQRT1_FMT =3D 0x1d, + MOVT =3D 0x25, + NEG_FMT =3D 0x2d, + CVT_D =3D 0x4d, + RECIP1_FMT =3D 0x5d, + CVT_S =3D 0x6d +}; + +/* POOL32I encoding of minor opcode field (bits 25..21) */ + +enum { + BLTZ =3D 0x00, + BLTZAL =3D 0x01, + BGEZ =3D 0x02, + BGEZAL =3D 0x03, + BLEZ =3D 0x04, + BNEZC =3D 0x05, + BGTZ =3D 0x06, + BEQZC =3D 0x07, + TLTI =3D 0x08, + BC1EQZC =3D 0x08, + TGEI =3D 0x09, + BC1NEZC =3D 0x09, + TLTIU =3D 0x0a, + BC2EQZC =3D 0x0a, + TGEIU =3D 0x0b, + BC2NEZC =3D 0x0a, + TNEI =3D 0x0c, + R6_SYNCI =3D 0x0c, + LUI =3D 0x0d, + TEQI =3D 0x0e, + SYNCI =3D 0x10, + BLTZALS =3D 0x11, + BGEZALS =3D 0x13, + BC2F =3D 0x14, + BC2T =3D 0x15, + BPOSGE64 =3D 0x1a, + BPOSGE32 =3D 0x1b, + /* These overlap and are distinguished by bit16 of the instruction */ + BC1F =3D 0x1c, + BC1T =3D 0x1d, + BC1ANY2F =3D 0x1c, + BC1ANY2T =3D 0x1d, + BC1ANY4F =3D 0x1e, + BC1ANY4T =3D 0x1f +}; + +/* POOL16A encoding of minor opcode field */ + +enum { + ADDU16 =3D 0x0, + SUBU16 =3D 0x1 +}; + +/* POOL16B encoding of minor opcode field */ + +enum { + SLL16 =3D 0x0, + SRL16 =3D 0x1 +}; + +/* POOL16C encoding of minor opcode field */ + +enum { + NOT16 =3D 0x00, + XOR16 =3D 0x04, + AND16 =3D 0x08, + OR16 =3D 0x0c, + LWM16 =3D 0x10, + SWM16 =3D 0x14, + JR16 =3D 0x18, + JRC16 =3D 0x1a, + JALR16 =3D 0x1c, + JALR16S =3D 0x1e, + MFHI16 =3D 0x20, + MFLO16 =3D 0x24, + BREAK16 =3D 0x28, + SDBBP16 =3D 0x2c, + JRADDIUSP =3D 0x30 +}; + +/* R6 POOL16C encoding of minor opcode field (bits 0..5) */ + +enum { + R6_NOT16 =3D 0x00, + R6_AND16 =3D 0x01, + R6_LWM16 =3D 0x02, + R6_JRC16 =3D 0x03, + MOVEP =3D 0x04, + MOVEP_05 =3D 0x05, + MOVEP_06 =3D 0x06, + MOVEP_07 =3D 0x07, + R6_XOR16 =3D 0x08, + R6_OR16 =3D 0x09, + R6_SWM16 =3D 0x0a, + JALRC16 =3D 0x0b, + MOVEP_0C =3D 0x0c, + MOVEP_0D =3D 0x0d, + MOVEP_0E =3D 0x0e, + MOVEP_0F =3D 0x0f, + JRCADDIUSP =3D 0x13, + R6_BREAK16 =3D 0x1b, + R6_SDBBP16 =3D 0x3b +}; + +/* POOL16D encoding of minor opcode field */ + +enum { + ADDIUS5 =3D 0x0, + ADDIUSP =3D 0x1 +}; + +/* POOL16E encoding of minor opcode field */ + +enum { + ADDIUR2 =3D 0x0, + ADDIUR1SP =3D 0x1 +}; + +static int mmreg(int r) +{ + static const int map[] =3D { 16, 17, 2, 3, 4, 5, 6, 7 }; + + return map[r]; +} + +/* Used for 16-bit store instructions. */ +static int mmreg2(int r) +{ + static const int map[] =3D { 0, 17, 2, 3, 4, 5, 6, 7 }; + + return map[r]; +} + +#define uMIPS_RD(op) ((op >> 7) & 0x7) +#define uMIPS_RS(op) ((op >> 4) & 0x7) +#define uMIPS_RS2(op) uMIPS_RS(op) +#define uMIPS_RS1(op) ((op >> 1) & 0x7) +#define uMIPS_RD5(op) ((op >> 5) & 0x1f) +#define uMIPS_RS5(op) (op & 0x1f) + +/* Signed immediate */ +#define SIMM(op, start, width) \ + ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \ + << (32 - width)) \ + >> (32 - width)) +/* Zero-extended immediate */ +#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width))) + +static void gen_addiur1sp(DisasContext *ctx) +{ + int rd =3D mmreg(uMIPS_RD(ctx->opcode)); + + gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2= ); +} + +static void gen_addiur2(DisasContext *ctx) +{ + static const int decoded_imm[] =3D { 1, 4, 8, 12, 16, 20, 24, -1 }; + int rd =3D mmreg(uMIPS_RD(ctx->opcode)); + int rs =3D mmreg(uMIPS_RS(ctx->opcode)); + + gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1,= 3)]); +} + +static void gen_addiusp(DisasContext *ctx) +{ + int encoded =3D ZIMM(ctx->opcode, 1, 9); + int decoded; + + if (encoded <=3D 1) { + decoded =3D 256 + encoded; + } else if (encoded <=3D 255) { + decoded =3D encoded; + } else if (encoded <=3D 509) { + decoded =3D encoded - 512; + } else { + decoded =3D encoded - 768; + } + + gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2); +} + +static void gen_addius5(DisasContext *ctx) +{ + int imm =3D SIMM(ctx->opcode, 1, 4); + int rd =3D (ctx->opcode >> 5) & 0x1f; + + gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm); +} + +static void gen_andi16(DisasContext *ctx) +{ + static const int decoded_imm[] =3D { 128, 1, 2, 3, 4, 7, 8, 15, 16, + 31, 32, 63, 64, 255, 32768, 65535 }; + int rd =3D mmreg(uMIPS_RD(ctx->opcode)); + int rs =3D mmreg(uMIPS_RS(ctx->opcode)); + int encoded =3D ZIMM(ctx->opcode, 0, 4); + + gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]); +} + +static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist, + int base, int16_t offset) +{ + TCGv t0, t1; + TCGv_i32 t2; + + if (ctx->hflags & MIPS_HFLAG_BMASK) { + generate_exception_end(ctx, EXCP_RI); + return; + } + + t0 =3D tcg_temp_new(); + + gen_base_offset_addr(ctx, t0, base, offset); + + t1 =3D tcg_const_tl(reglist); + t2 =3D tcg_const_i32(ctx->mem_idx); + + save_cpu_state(ctx, 1); + switch (opc) { + case LWM32: + gen_helper_lwm(cpu_env, t0, t1, t2); + break; + case SWM32: + gen_helper_swm(cpu_env, t0, t1, t2); + break; +#ifdef TARGET_MIPS64 + case LDM: + gen_helper_ldm(cpu_env, t0, t1, t2); + break; + case SDM: + gen_helper_sdm(cpu_env, t0, t1, t2); + break; +#endif + } + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free_i32(t2); +} + + +static void gen_pool16c_insn(DisasContext *ctx) +{ + int rd =3D mmreg((ctx->opcode >> 3) & 0x7); + int rs =3D mmreg(ctx->opcode & 0x7); + + switch (((ctx->opcode) >> 4) & 0x3f) { + case NOT16 + 0: + case NOT16 + 1: + case NOT16 + 2: + case NOT16 + 3: + gen_logic(ctx, OPC_NOR, rd, rs, 0); + break; + case XOR16 + 0: + case XOR16 + 1: + case XOR16 + 2: + case XOR16 + 3: + gen_logic(ctx, OPC_XOR, rd, rd, rs); + break; + case AND16 + 0: + case AND16 + 1: + case AND16 + 2: + case AND16 + 3: + gen_logic(ctx, OPC_AND, rd, rd, rs); + break; + case OR16 + 0: + case OR16 + 1: + case OR16 + 2: + case OR16 + 3: + gen_logic(ctx, OPC_OR, rd, rd, rs); + break; + case LWM16 + 0: + case LWM16 + 1: + case LWM16 + 2: + case LWM16 + 3: + { + static const int lwm_convert[] =3D { 0x11, 0x12, 0x13, 0x14 }; + int offset =3D ZIMM(ctx->opcode, 0, 4); + + gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) &= 0x3], + 29, offset << 2); + } + break; + case SWM16 + 0: + case SWM16 + 1: + case SWM16 + 2: + case SWM16 + 3: + { + static const int swm_convert[] =3D { 0x11, 0x12, 0x13, 0x14 }; + int offset =3D ZIMM(ctx->opcode, 0, 4); + + gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) &= 0x3], + 29, offset << 2); + } + break; + case JR16 + 0: + case JR16 + 1: + { + int reg =3D ctx->opcode & 0x1f; + + gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4); + } + break; + case JRC16 + 0: + case JRC16 + 1: + { + int reg =3D ctx->opcode & 0x1f; + gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0); + /* + * Let normal delay slot handling in our caller take us + * to the branch target. + */ + } + break; + case JALR16 + 0: + case JALR16 + 1: + gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + break; + case JALR16S + 0: + case JALR16S + 1: + gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + break; + case MFHI16 + 0: + case MFHI16 + 1: + gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode)); + break; + case MFLO16 + 0: + case MFLO16 + 1: + gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode)); + break; + case BREAK16: + generate_exception_end(ctx, EXCP_BREAK); + break; + case SDBBP16: + if (is_uhi(extract32(ctx->opcode, 0, 4))) { + gen_helper_do_semihosting(cpu_env); + } else { + /* + * XXX: not clear which exception should be raised + * when in debug mode... + */ + check_insn(ctx, ISA_MIPS32); + generate_exception_end(ctx, EXCP_DBp); + } + break; + case JRADDIUSP + 0: + case JRADDIUSP + 1: + { + int imm =3D ZIMM(ctx->opcode, 0, 5); + gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0); + gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2); + /* + * Let normal delay slot handling in our caller take us + * to the branch target. + */ + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt, + int enc_rs) +{ + int rd, rs, re, rt; + static const int rd_enc[] =3D { 5, 5, 6, 4, 4, 4, 4, 4 }; + static const int re_enc[] =3D { 6, 7, 7, 21, 22, 5, 6, 7 }; + static const int rs_rt_enc[] =3D { 0, 17, 2, 3, 16, 18, 19, 20 }; + rd =3D rd_enc[enc_dest]; + re =3D re_enc[enc_dest]; + rs =3D rs_rt_enc[enc_rs]; + rt =3D rs_rt_enc[enc_rt]; + if (rs) { + tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); + } else { + tcg_gen_movi_tl(cpu_gpr[rd], 0); + } + if (rt) { + tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]); + } else { + tcg_gen_movi_tl(cpu_gpr[re], 0); + } +} + +static void gen_pool16c_r6_insn(DisasContext *ctx) +{ + int rt =3D mmreg((ctx->opcode >> 7) & 0x7); + int rs =3D mmreg((ctx->opcode >> 4) & 0x7); + + switch (ctx->opcode & 0xf) { + case R6_NOT16: + gen_logic(ctx, OPC_NOR, rt, rs, 0); + break; + case R6_AND16: + gen_logic(ctx, OPC_AND, rt, rt, rs); + break; + case R6_LWM16: + { + int lwm_converted =3D 0x11 + extract32(ctx->opcode, 8, 2); + int offset =3D extract32(ctx->opcode, 4, 4); + gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2); + } + break; + case R6_JRC16: /* JRCADDIUSP */ + if ((ctx->opcode >> 4) & 1) { + /* JRCADDIUSP */ + int imm =3D extract32(ctx->opcode, 5, 5); + gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0); + gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2); + } else { + /* JRC16 */ + rs =3D extract32(ctx->opcode, 5, 5); + gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0); + } + break; + case MOVEP: + case MOVEP_05: + case MOVEP_06: + case MOVEP_07: + case MOVEP_0C: + case MOVEP_0D: + case MOVEP_0E: + case MOVEP_0F: + { + int enc_dest =3D uMIPS_RD(ctx->opcode); + int enc_rt =3D uMIPS_RS2(ctx->opcode); + int enc_rs =3D (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4); + gen_movep(ctx, enc_dest, enc_rt, enc_rs); + } + break; + case R6_XOR16: + gen_logic(ctx, OPC_XOR, rt, rt, rs); + break; + case R6_OR16: + gen_logic(ctx, OPC_OR, rt, rt, rs); + break; + case R6_SWM16: + { + int swm_converted =3D 0x11 + extract32(ctx->opcode, 8, 2); + int offset =3D extract32(ctx->opcode, 4, 4); + gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2); + } + break; + case JALRC16: /* BREAK16, SDBBP16 */ + switch (ctx->opcode & 0x3f) { + case JALRC16: + case JALRC16 + 0x20: + /* JALRC16 */ + gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f, + 31, 0, 0); + break; + case R6_BREAK16: + /* BREAK16 */ + generate_exception(ctx, EXCP_BREAK); + break; + case R6_SDBBP16: + /* SDBBP16 */ + if (is_uhi(extract32(ctx->opcode, 6, 4))) { + gen_helper_do_semihosting(cpu_env); + } else { + if (ctx->hflags & MIPS_HFLAG_SBRI) { + generate_exception(ctx, EXCP_RI); + } else { + generate_exception(ctx, EXCP_DBp); + } + } + break; + } + break; + default: + generate_exception(ctx, EXCP_RI); + break; + } +} + +static void gen_ldxs(DisasContext *ctx, int base, int index, int rd) +{ + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + + gen_load_gpr(t0, base); + + if (index !=3D 0) { + gen_load_gpr(t1, index); + tcg_gen_shli_tl(t1, t1, 2); + gen_op_addr_add(ctx, t0, t1, t0); + } + + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); + gen_store_gpr(t1, rd); + + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd, + int base, int16_t offset) +{ + TCGv t0, t1; + + if (ctx->hflags & MIPS_HFLAG_BMASK || rd =3D=3D 31) { + generate_exception_end(ctx, EXCP_RI); + return; + } + + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + + gen_base_offset_addr(ctx, t0, base, offset); + + switch (opc) { + case LWP: + if (rd =3D=3D base) { + generate_exception_end(ctx, EXCP_RI); + return; + } + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); + gen_store_gpr(t1, rd); + tcg_gen_movi_tl(t1, 4); + gen_op_addr_add(ctx, t0, t0, t1); + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); + gen_store_gpr(t1, rd + 1); + break; + case SWP: + gen_load_gpr(t1, rd); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); + tcg_gen_movi_tl(t1, 4); + gen_op_addr_add(ctx, t0, t0, t1); + gen_load_gpr(t1, rd + 1); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); + break; +#ifdef TARGET_MIPS64 + case LDP: + if (rd =3D=3D base) { + generate_exception_end(ctx, EXCP_RI); + return; + } + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ); + gen_store_gpr(t1, rd); + tcg_gen_movi_tl(t1, 8); + gen_op_addr_add(ctx, t0, t0, t1); + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ); + gen_store_gpr(t1, rd + 1); + break; + case SDP: + gen_load_gpr(t1, rd); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ); + tcg_gen_movi_tl(t1, 8); + gen_op_addr_add(ctx, t0, t0, t1); + gen_load_gpr(t1, rd + 1); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ); + break; +#endif + } + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +static void gen_sync(int stype) +{ + TCGBar tcg_mo =3D TCG_BAR_SC; + + switch (stype) { + case 0x4: /* SYNC_WMB */ + tcg_mo |=3D TCG_MO_ST_ST; + break; + case 0x10: /* SYNC_MB */ + tcg_mo |=3D TCG_MO_ALL; + break; + case 0x11: /* SYNC_ACQUIRE */ + tcg_mo |=3D TCG_MO_LD_LD | TCG_MO_LD_ST; + break; + case 0x12: /* SYNC_RELEASE */ + tcg_mo |=3D TCG_MO_ST_ST | TCG_MO_LD_ST; + break; + case 0x13: /* SYNC_RMB */ + tcg_mo |=3D TCG_MO_LD_LD; + break; + default: + tcg_mo |=3D TCG_MO_ALL; + break; + } + + tcg_gen_mb(tcg_mo); +} + +static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, in= t rs) +{ + int extension =3D (ctx->opcode >> 6) & 0x3f; + int minor =3D (ctx->opcode >> 12) & 0xf; + uint32_t mips32_op; + + switch (extension) { + case TEQ: + mips32_op =3D OPC_TEQ; + goto do_trap; + case TGE: + mips32_op =3D OPC_TGE; + goto do_trap; + case TGEU: + mips32_op =3D OPC_TGEU; + goto do_trap; + case TLT: + mips32_op =3D OPC_TLT; + goto do_trap; + case TLTU: + mips32_op =3D OPC_TLTU; + goto do_trap; + case TNE: + mips32_op =3D OPC_TNE; + do_trap: + gen_trap(ctx, mips32_op, rs, rt, -1); + break; +#ifndef CONFIG_USER_ONLY + case MFC0: + case MFC0 + 32: + check_cp0_enabled(ctx); + if (rt =3D=3D 0) { + /* Treat as NOP. */ + break; + } + gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7); + break; + case MTC0: + case MTC0 + 32: + check_cp0_enabled(ctx); + { + TCGv t0 =3D tcg_temp_new(); + + gen_load_gpr(t0, rt); + gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7); + tcg_temp_free(t0); + } + break; +#endif + case 0x2a: + switch (minor & 3) { + case MADD_ACC: + gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt); + break; + case MADDU_ACC: + gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt); + break; + case MSUB_ACC: + gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt); + break; + case MSUBU_ACC: + gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt); + break; + default: + goto pool32axf_invalid; + } + break; + case 0x32: + switch (minor & 3) { + case MULT_ACC: + gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt); + break; + case MULTU_ACC: + gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt); + break; + default: + goto pool32axf_invalid; + } + break; + case 0x2c: + switch (minor) { + case BITSWAP: + check_insn(ctx, ISA_MIPS32R6); + gen_bitswap(ctx, OPC_BITSWAP, rs, rt); + break; + case SEB: + gen_bshfl(ctx, OPC_SEB, rs, rt); + break; + case SEH: + gen_bshfl(ctx, OPC_SEH, rs, rt); + break; + case CLO: + mips32_op =3D OPC_CLO; + goto do_cl; + case CLZ: + mips32_op =3D OPC_CLZ; + do_cl: + check_insn(ctx, ISA_MIPS32); + gen_cl(ctx, mips32_op, rt, rs); + break; + case RDHWR: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_rdhwr(ctx, rt, rs, 0); + break; + case WSBH: + gen_bshfl(ctx, OPC_WSBH, rs, rt); + break; + case MULT: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MULT; + goto do_mul; + case MULTU: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MULTU; + goto do_mul; + case DIV: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_DIV; + goto do_div; + case DIVU: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_DIVU; + goto do_div; + do_div: + check_insn(ctx, ISA_MIPS32); + gen_muldiv(ctx, mips32_op, 0, rs, rt); + break; + case MADD: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MADD; + goto do_mul; + case MADDU: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MADDU; + goto do_mul; + case MSUB: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MSUB; + goto do_mul; + case MSUBU: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MSUBU; + do_mul: + check_insn(ctx, ISA_MIPS32); + gen_muldiv(ctx, mips32_op, 0, rs, rt); + break; + default: + goto pool32axf_invalid; + } + break; + case 0x34: + switch (minor) { + case MFC2: + case MTC2: + case MFHC2: + case MTHC2: + case CFC2: + case CTC2: + generate_exception_err(ctx, EXCP_CpU, 2); + break; + default: + goto pool32axf_invalid; + } + break; + case 0x3c: + switch (minor) { + case JALR: /* JALRC */ + case JALR_HB: /* JALRC_HB */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* JALRC, JALRC_HB */ + gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0); + } else { + /* JALR, JALR_HB */ + gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + } + break; + case JALRS: + case JALRS_HB: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + break; + default: + goto pool32axf_invalid; + } + break; + case 0x05: + switch (minor) { + case RDPGPR: + check_cp0_enabled(ctx); + check_insn(ctx, ISA_MIPS32R2); + gen_load_srsgpr(rs, rt); + break; + case WRPGPR: + check_cp0_enabled(ctx); + check_insn(ctx, ISA_MIPS32R2); + gen_store_srsgpr(rs, rt); + break; + default: + goto pool32axf_invalid; + } + break; +#ifndef CONFIG_USER_ONLY + case 0x0d: + switch (minor) { + case TLBP: + mips32_op =3D OPC_TLBP; + goto do_cp0; + case TLBR: + mips32_op =3D OPC_TLBR; + goto do_cp0; + case TLBWI: + mips32_op =3D OPC_TLBWI; + goto do_cp0; + case TLBWR: + mips32_op =3D OPC_TLBWR; + goto do_cp0; + case TLBINV: + mips32_op =3D OPC_TLBINV; + goto do_cp0; + case TLBINVF: + mips32_op =3D OPC_TLBINVF; + goto do_cp0; + case WAIT: + mips32_op =3D OPC_WAIT; + goto do_cp0; + case DERET: + mips32_op =3D OPC_DERET; + goto do_cp0; + case ERET: + mips32_op =3D OPC_ERET; + do_cp0: + gen_cp0(env, ctx, mips32_op, rt, rs); + break; + default: + goto pool32axf_invalid; + } + break; + case 0x1d: + switch (minor) { + case DI: + check_cp0_enabled(ctx); + { + TCGv t0 =3D tcg_temp_new(); + + save_cpu_state(ctx, 1); + gen_helper_di(t0, cpu_env); + gen_store_gpr(t0, rs); + /* + * Stop translation as we may have switched the execution + * mode. + */ + ctx->base.is_jmp =3D DISAS_STOP; + tcg_temp_free(t0); + } + break; + case EI: + check_cp0_enabled(ctx); + { + TCGv t0 =3D tcg_temp_new(); + + save_cpu_state(ctx, 1); + gen_helper_ei(t0, cpu_env); + gen_store_gpr(t0, rs); + /* + * DISAS_STOP isn't sufficient, we need to ensure we break= out + * of translated code to check for pending interrupts. + */ + gen_save_pc(ctx->base.pc_next + 4); + ctx->base.is_jmp =3D DISAS_EXIT; + tcg_temp_free(t0); + } + break; + default: + goto pool32axf_invalid; + } + break; +#endif + case 0x2d: + switch (minor) { + case SYNC: + gen_sync(extract32(ctx->opcode, 16, 5)); + break; + case SYSCALL: + generate_exception_end(ctx, EXCP_SYSCALL); + break; + case SDBBP: + if (is_uhi(extract32(ctx->opcode, 16, 10))) { + gen_helper_do_semihosting(cpu_env); + } else { + check_insn(ctx, ISA_MIPS32); + if (ctx->hflags & MIPS_HFLAG_SBRI) { + generate_exception_end(ctx, EXCP_RI); + } else { + generate_exception_end(ctx, EXCP_DBp); + } + } + break; + default: + goto pool32axf_invalid; + } + break; + case 0x01: + switch (minor & 3) { + case MFHI_ACC: + gen_HILO(ctx, OPC_MFHI, minor >> 2, rs); + break; + case MFLO_ACC: + gen_HILO(ctx, OPC_MFLO, minor >> 2, rs); + break; + case MTHI_ACC: + gen_HILO(ctx, OPC_MTHI, minor >> 2, rs); + break; + case MTLO_ACC: + gen_HILO(ctx, OPC_MTLO, minor >> 2, rs); + break; + default: + goto pool32axf_invalid; + } + break; + case 0x35: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + switch (minor) { + case MFHI32: + gen_HILO(ctx, OPC_MFHI, 0, rs); + break; + case MFLO32: + gen_HILO(ctx, OPC_MFLO, 0, rs); + break; + case MTHI32: + gen_HILO(ctx, OPC_MTHI, 0, rs); + break; + case MTLO32: + gen_HILO(ctx, OPC_MTLO, 0, rs); + break; + default: + goto pool32axf_invalid; + } + break; + default: + pool32axf_invalid: + MIPS_INVAL("pool32axf"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * Values for microMIPS fmt field. Variable-width, depending on which + * formats the instruction supports. + */ +enum { + FMT_SD_S =3D 0, + FMT_SD_D =3D 1, + + FMT_SDPS_S =3D 0, + FMT_SDPS_D =3D 1, + FMT_SDPS_PS =3D 2, + + FMT_SWL_S =3D 0, + FMT_SWL_W =3D 1, + FMT_SWL_L =3D 2, + + FMT_DWL_D =3D 0, + FMT_DWL_W =3D 1, + FMT_DWL_L =3D 2 +}; + +static void gen_pool32fxf(DisasContext *ctx, int rt, int rs) +{ + int extension =3D (ctx->opcode >> 6) & 0x3ff; + uint32_t mips32_op; + +#define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc) +#define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc) +#define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc) + + switch (extension) { + case FLOAT_1BIT_FMT(CFC1, 0): + mips32_op =3D OPC_CFC1; + goto do_cp1; + case FLOAT_1BIT_FMT(CTC1, 0): + mips32_op =3D OPC_CTC1; + goto do_cp1; + case FLOAT_1BIT_FMT(MFC1, 0): + mips32_op =3D OPC_MFC1; + goto do_cp1; + case FLOAT_1BIT_FMT(MTC1, 0): + mips32_op =3D OPC_MTC1; + goto do_cp1; + case FLOAT_1BIT_FMT(MFHC1, 0): + mips32_op =3D OPC_MFHC1; + goto do_cp1; + case FLOAT_1BIT_FMT(MTHC1, 0): + mips32_op =3D OPC_MTHC1; + do_cp1: + gen_cp1(ctx, mips32_op, rt, rs); + break; + + /* Reciprocal square root */ + case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S): + mips32_op =3D OPC_RSQRT_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D): + mips32_op =3D OPC_RSQRT_D; + goto do_unaryfp; + + /* Square root */ + case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S): + mips32_op =3D OPC_SQRT_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D): + mips32_op =3D OPC_SQRT_D; + goto do_unaryfp; + + /* Reciprocal */ + case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S): + mips32_op =3D OPC_RECIP_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D): + mips32_op =3D OPC_RECIP_D; + goto do_unaryfp; + + /* Floor */ + case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S): + mips32_op =3D OPC_FLOOR_L_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D): + mips32_op =3D OPC_FLOOR_L_D; + goto do_unaryfp; + case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S): + mips32_op =3D OPC_FLOOR_W_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D): + mips32_op =3D OPC_FLOOR_W_D; + goto do_unaryfp; + + /* Ceiling */ + case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S): + mips32_op =3D OPC_CEIL_L_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D): + mips32_op =3D OPC_CEIL_L_D; + goto do_unaryfp; + case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S): + mips32_op =3D OPC_CEIL_W_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D): + mips32_op =3D OPC_CEIL_W_D; + goto do_unaryfp; + + /* Truncation */ + case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S): + mips32_op =3D OPC_TRUNC_L_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D): + mips32_op =3D OPC_TRUNC_L_D; + goto do_unaryfp; + case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S): + mips32_op =3D OPC_TRUNC_W_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D): + mips32_op =3D OPC_TRUNC_W_D; + goto do_unaryfp; + + /* Round */ + case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S): + mips32_op =3D OPC_ROUND_L_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D): + mips32_op =3D OPC_ROUND_L_D; + goto do_unaryfp; + case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S): + mips32_op =3D OPC_ROUND_W_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D): + mips32_op =3D OPC_ROUND_W_D; + goto do_unaryfp; + + /* Integer to floating-point conversion */ + case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S): + mips32_op =3D OPC_CVT_L_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D): + mips32_op =3D OPC_CVT_L_D; + goto do_unaryfp; + case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S): + mips32_op =3D OPC_CVT_W_S; + goto do_unaryfp; + case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D): + mips32_op =3D OPC_CVT_W_D; + goto do_unaryfp; + + /* Paired-foo conversions */ + case FLOAT_1BIT_FMT(CVT_S_PL, 0): + mips32_op =3D OPC_CVT_S_PL; + goto do_unaryfp; + case FLOAT_1BIT_FMT(CVT_S_PU, 0): + mips32_op =3D OPC_CVT_S_PU; + goto do_unaryfp; + case FLOAT_1BIT_FMT(CVT_PW_PS, 0): + mips32_op =3D OPC_CVT_PW_PS; + goto do_unaryfp; + case FLOAT_1BIT_FMT(CVT_PS_PW, 0): + mips32_op =3D OPC_CVT_PS_PW; + goto do_unaryfp; + + /* Floating-point moves */ + case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S): + mips32_op =3D OPC_MOV_S; + goto do_unaryfp; + case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D): + mips32_op =3D OPC_MOV_D; + goto do_unaryfp; + case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS): + mips32_op =3D OPC_MOV_PS; + goto do_unaryfp; + + /* Absolute value */ + case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S): + mips32_op =3D OPC_ABS_S; + goto do_unaryfp; + case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D): + mips32_op =3D OPC_ABS_D; + goto do_unaryfp; + case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS): + mips32_op =3D OPC_ABS_PS; + goto do_unaryfp; + + /* Negation */ + case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S): + mips32_op =3D OPC_NEG_S; + goto do_unaryfp; + case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D): + mips32_op =3D OPC_NEG_D; + goto do_unaryfp; + case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS): + mips32_op =3D OPC_NEG_PS; + goto do_unaryfp; + + /* Reciprocal square root step */ + case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S): + mips32_op =3D OPC_RSQRT1_S; + goto do_unaryfp; + case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D): + mips32_op =3D OPC_RSQRT1_D; + goto do_unaryfp; + case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS): + mips32_op =3D OPC_RSQRT1_PS; + goto do_unaryfp; + + /* Reciprocal step */ + case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S): + mips32_op =3D OPC_RECIP1_S; + goto do_unaryfp; + case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D): + mips32_op =3D OPC_RECIP1_S; + goto do_unaryfp; + case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS): + mips32_op =3D OPC_RECIP1_PS; + goto do_unaryfp; + + /* Conversions from double */ + case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S): + mips32_op =3D OPC_CVT_D_S; + goto do_unaryfp; + case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W): + mips32_op =3D OPC_CVT_D_W; + goto do_unaryfp; + case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L): + mips32_op =3D OPC_CVT_D_L; + goto do_unaryfp; + + /* Conversions from single */ + case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D): + mips32_op =3D OPC_CVT_S_D; + goto do_unaryfp; + case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W): + mips32_op =3D OPC_CVT_S_W; + goto do_unaryfp; + case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L): + mips32_op =3D OPC_CVT_S_L; + do_unaryfp: + gen_farith(ctx, mips32_op, -1, rs, rt, 0); + break; + + /* Conditional moves on floating-point codes */ + case COND_FLOAT_MOV(MOVT, 0): + case COND_FLOAT_MOV(MOVT, 1): + case COND_FLOAT_MOV(MOVT, 2): + case COND_FLOAT_MOV(MOVT, 3): + case COND_FLOAT_MOV(MOVT, 4): + case COND_FLOAT_MOV(MOVT, 5): + case COND_FLOAT_MOV(MOVT, 6): + case COND_FLOAT_MOV(MOVT, 7): + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1); + break; + case COND_FLOAT_MOV(MOVF, 0): + case COND_FLOAT_MOV(MOVF, 1): + case COND_FLOAT_MOV(MOVF, 2): + case COND_FLOAT_MOV(MOVF, 3): + case COND_FLOAT_MOV(MOVF, 4): + case COND_FLOAT_MOV(MOVF, 5): + case COND_FLOAT_MOV(MOVF, 6): + case COND_FLOAT_MOV(MOVF, 7): + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0); + break; + default: + MIPS_INVAL("pool32fxf"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) +{ + int32_t offset; + uint16_t insn; + int rt, rs, rd, rr; + int16_t imm; + uint32_t op, minor, minor2, mips32_op; + uint32_t cond, fmt, cc; + + insn =3D cpu_lduw_code(env, ctx->base.pc_next + 2); + ctx->opcode =3D (ctx->opcode << 16) | insn; + + rt =3D (ctx->opcode >> 21) & 0x1f; + rs =3D (ctx->opcode >> 16) & 0x1f; + rd =3D (ctx->opcode >> 11) & 0x1f; + rr =3D (ctx->opcode >> 6) & 0x1f; + imm =3D (int16_t) ctx->opcode; + + op =3D (ctx->opcode >> 26) & 0x3f; + switch (op) { + case POOL32A: + minor =3D ctx->opcode & 0x3f; + switch (minor) { + case 0x00: + minor =3D (ctx->opcode >> 6) & 0xf; + switch (minor) { + case SLL32: + mips32_op =3D OPC_SLL; + goto do_shifti; + case SRA: + mips32_op =3D OPC_SRA; + goto do_shifti; + case SRL32: + mips32_op =3D OPC_SRL; + goto do_shifti; + case ROTR: + mips32_op =3D OPC_ROTR; + do_shifti: + gen_shift_imm(ctx, mips32_op, rt, rs, rd); + break; + case SELEQZ: + check_insn(ctx, ISA_MIPS32R6); + gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt); + break; + case SELNEZ: + check_insn(ctx, ISA_MIPS32R6); + gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt); + break; + case R6_RDHWR: + check_insn(ctx, ISA_MIPS32R6); + gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3)); + break; + default: + goto pool32a_invalid; + } + break; + case 0x10: + minor =3D (ctx->opcode >> 6) & 0xf; + switch (minor) { + /* Arithmetic */ + case ADD: + mips32_op =3D OPC_ADD; + goto do_arith; + case ADDU32: + mips32_op =3D OPC_ADDU; + goto do_arith; + case SUB: + mips32_op =3D OPC_SUB; + goto do_arith; + case SUBU32: + mips32_op =3D OPC_SUBU; + goto do_arith; + case MUL: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MUL; + do_arith: + gen_arith(ctx, mips32_op, rd, rs, rt); + break; + /* Shifts */ + case SLLV: + mips32_op =3D OPC_SLLV; + goto do_shift; + case SRLV: + mips32_op =3D OPC_SRLV; + goto do_shift; + case SRAV: + mips32_op =3D OPC_SRAV; + goto do_shift; + case ROTRV: + mips32_op =3D OPC_ROTRV; + do_shift: + gen_shift(ctx, mips32_op, rd, rs, rt); + break; + /* Logical operations */ + case AND: + mips32_op =3D OPC_AND; + goto do_logic; + case OR32: + mips32_op =3D OPC_OR; + goto do_logic; + case NOR: + mips32_op =3D OPC_NOR; + goto do_logic; + case XOR32: + mips32_op =3D OPC_XOR; + do_logic: + gen_logic(ctx, mips32_op, rd, rs, rt); + break; + /* Set less than */ + case SLT: + mips32_op =3D OPC_SLT; + goto do_slt; + case SLTU: + mips32_op =3D OPC_SLTU; + do_slt: + gen_slt(ctx, mips32_op, rd, rs, rt); + break; + default: + goto pool32a_invalid; + } + break; + case 0x18: + minor =3D (ctx->opcode >> 6) & 0xf; + switch (minor) { + /* Conditional moves */ + case MOVN: /* MUL */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* MUL */ + gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt); + } else { + /* MOVN */ + gen_cond_move(ctx, OPC_MOVN, rd, rs, rt); + } + break; + case MOVZ: /* MUH */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* MUH */ + gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt); + } else { + /* MOVZ */ + gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt); + } + break; + case MULU: + check_insn(ctx, ISA_MIPS32R6); + gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt); + break; + case MUHU: + check_insn(ctx, ISA_MIPS32R6); + gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt); + break; + case LWXS: /* DIV */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* DIV */ + gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt); + } else { + /* LWXS */ + gen_ldxs(ctx, rs, rt, rd); + } + break; + case MOD: + check_insn(ctx, ISA_MIPS32R6); + gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt); + break; + case R6_DIVU: + check_insn(ctx, ISA_MIPS32R6); + gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt); + break; + case MODU: + check_insn(ctx, ISA_MIPS32R6); + gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt); + break; + default: + goto pool32a_invalid; + } + break; + case INS: + gen_bitops(ctx, OPC_INS, rt, rs, rr, rd); + return; + case LSA: + check_insn(ctx, ISA_MIPS32R6); + gen_lsa(ctx, OPC_LSA, rd, rs, rt, + extract32(ctx->opcode, 9, 2)); + break; + case ALIGN: + check_insn(ctx, ISA_MIPS32R6); + gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2)); + break; + case EXT: + gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd); + return; + case POOL32AXF: + gen_pool32axf(env, ctx, rt, rs); + break; + case BREAK32: + generate_exception_end(ctx, EXCP_BREAK); + break; + case SIGRIE: + check_insn(ctx, ISA_MIPS32R6); + generate_exception_end(ctx, EXCP_RI); + break; + default: + pool32a_invalid: + MIPS_INVAL("pool32a"); + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case POOL32B: + minor =3D (ctx->opcode >> 12) & 0xf; + switch (minor) { + case CACHE: + check_cp0_enabled(ctx); + if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { + gen_cache_operation(ctx, rt, rs, imm); + } + break; + case LWC2: + case SWC2: + /* COP2: Not implemented. */ + generate_exception_err(ctx, EXCP_CpU, 2); + break; +#ifdef TARGET_MIPS64 + case LDP: + case SDP: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); +#endif + /* fall through */ + case LWP: + case SWP: + gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12)); + break; +#ifdef TARGET_MIPS64 + case LDM: + case SDM: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); +#endif + /* fall through */ + case LWM32: + case SWM32: + gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12)= ); + break; + default: + MIPS_INVAL("pool32b"); + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case POOL32F: + if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { + minor =3D ctx->opcode & 0x3f; + check_cp1_enabled(ctx); + switch (minor) { + case ALNV_PS: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_ALNV_PS; + goto do_madd; + case MADD_S: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MADD_S; + goto do_madd; + case MADD_D: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MADD_D; + goto do_madd; + case MADD_PS: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MADD_PS; + goto do_madd; + case MSUB_S: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MSUB_S; + goto do_madd; + case MSUB_D: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MSUB_D; + goto do_madd; + case MSUB_PS: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_MSUB_PS; + goto do_madd; + case NMADD_S: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_NMADD_S; + goto do_madd; + case NMADD_D: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_NMADD_D; + goto do_madd; + case NMADD_PS: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_NMADD_PS; + goto do_madd; + case NMSUB_S: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_NMSUB_S; + goto do_madd; + case NMSUB_D: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_NMSUB_D; + goto do_madd; + case NMSUB_PS: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_NMSUB_PS; + do_madd: + gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt); + break; + case CABS_COND_FMT: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + cond =3D (ctx->opcode >> 6) & 0xf; + cc =3D (ctx->opcode >> 13) & 0x7; + fmt =3D (ctx->opcode >> 10) & 0x3; + switch (fmt) { + case 0x0: + gen_cmpabs_s(ctx, cond, rt, rs, cc); + break; + case 0x1: + gen_cmpabs_d(ctx, cond, rt, rs, cc); + break; + case 0x2: + gen_cmpabs_ps(ctx, cond, rt, rs, cc); + break; + default: + goto pool32f_invalid; + } + break; + case C_COND_FMT: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + cond =3D (ctx->opcode >> 6) & 0xf; + cc =3D (ctx->opcode >> 13) & 0x7; + fmt =3D (ctx->opcode >> 10) & 0x3; + switch (fmt) { + case 0x0: + gen_cmp_s(ctx, cond, rt, rs, cc); + break; + case 0x1: + gen_cmp_d(ctx, cond, rt, rs, cc); + break; + case 0x2: + gen_cmp_ps(ctx, cond, rt, rs, cc); + break; + default: + goto pool32f_invalid; + } + break; + case CMP_CONDN_S: + check_insn(ctx, ISA_MIPS32R6); + gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd); + break; + case CMP_CONDN_D: + check_insn(ctx, ISA_MIPS32R6); + gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd); + break; + case POOL32FXF: + gen_pool32fxf(ctx, rt, rs); + break; + case 0x00: + /* PLL foo */ + switch ((ctx->opcode >> 6) & 0x7) { + case PLL_PS: + mips32_op =3D OPC_PLL_PS; + goto do_ps; + case PLU_PS: + mips32_op =3D OPC_PLU_PS; + goto do_ps; + case PUL_PS: + mips32_op =3D OPC_PUL_PS; + goto do_ps; + case PUU_PS: + mips32_op =3D OPC_PUU_PS; + goto do_ps; + case CVT_PS_S: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_CVT_PS_S; + do_ps: + gen_farith(ctx, mips32_op, rt, rs, rd, 0); + break; + default: + goto pool32f_invalid; + } + break; + case MIN_FMT: + check_insn(ctx, ISA_MIPS32R6); + switch ((ctx->opcode >> 9) & 0x3) { + case FMT_SDPS_S: + gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); + break; + case FMT_SDPS_D: + gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0); + break; + default: + goto pool32f_invalid; + } + break; + case 0x08: + /* [LS][WDU]XC1 */ + switch ((ctx->opcode >> 6) & 0x7) { + case LWXC1: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_LWXC1; + goto do_ldst_cp1; + case SWXC1: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_SWXC1; + goto do_ldst_cp1; + case LDXC1: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_LDXC1; + goto do_ldst_cp1; + case SDXC1: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_SDXC1; + goto do_ldst_cp1; + case LUXC1: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_LUXC1; + goto do_ldst_cp1; + case SUXC1: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_SUXC1; + do_ldst_cp1: + gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs); + break; + default: + goto pool32f_invalid; + } + break; + case MAX_FMT: + check_insn(ctx, ISA_MIPS32R6); + switch ((ctx->opcode >> 9) & 0x3) { + case FMT_SDPS_S: + gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); + break; + case FMT_SDPS_D: + gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0); + break; + default: + goto pool32f_invalid; + } + break; + case 0x18: + /* 3D insns */ + check_insn_opc_removed(ctx, ISA_MIPS32R6); + fmt =3D (ctx->opcode >> 9) & 0x3; + switch ((ctx->opcode >> 6) & 0x7) { + case RSQRT2_FMT: + switch (fmt) { + case FMT_SDPS_S: + mips32_op =3D OPC_RSQRT2_S; + goto do_3d; + case FMT_SDPS_D: + mips32_op =3D OPC_RSQRT2_D; + goto do_3d; + case FMT_SDPS_PS: + mips32_op =3D OPC_RSQRT2_PS; + goto do_3d; + default: + goto pool32f_invalid; + } + break; + case RECIP2_FMT: + switch (fmt) { + case FMT_SDPS_S: + mips32_op =3D OPC_RECIP2_S; + goto do_3d; + case FMT_SDPS_D: + mips32_op =3D OPC_RECIP2_D; + goto do_3d; + case FMT_SDPS_PS: + mips32_op =3D OPC_RECIP2_PS; + goto do_3d; + default: + goto pool32f_invalid; + } + break; + case ADDR_PS: + mips32_op =3D OPC_ADDR_PS; + goto do_3d; + case MULR_PS: + mips32_op =3D OPC_MULR_PS; + do_3d: + gen_farith(ctx, mips32_op, rt, rs, rd, 0); + break; + default: + goto pool32f_invalid; + } + break; + case 0x20: + /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/ + cc =3D (ctx->opcode >> 13) & 0x7; + fmt =3D (ctx->opcode >> 9) & 0x3; + switch ((ctx->opcode >> 6) & 0x7) { + case MOVF_FMT: /* RINT_FMT */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* RINT_FMT */ + switch (fmt) { + case FMT_SDPS_S: + gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0); + break; + case FMT_SDPS_D: + gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0); + break; + default: + goto pool32f_invalid; + } + } else { + /* MOVF_FMT */ + switch (fmt) { + case FMT_SDPS_S: + gen_movcf_s(ctx, rs, rt, cc, 0); + break; + case FMT_SDPS_D: + gen_movcf_d(ctx, rs, rt, cc, 0); + break; + case FMT_SDPS_PS: + check_ps(ctx); + gen_movcf_ps(ctx, rs, rt, cc, 0); + break; + default: + goto pool32f_invalid; + } + } + break; + case MOVT_FMT: /* CLASS_FMT */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* CLASS_FMT */ + switch (fmt) { + case FMT_SDPS_S: + gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0); + break; + case FMT_SDPS_D: + gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0); + break; + default: + goto pool32f_invalid; + } + } else { + /* MOVT_FMT */ + switch (fmt) { + case FMT_SDPS_S: + gen_movcf_s(ctx, rs, rt, cc, 1); + break; + case FMT_SDPS_D: + gen_movcf_d(ctx, rs, rt, cc, 1); + break; + case FMT_SDPS_PS: + check_ps(ctx); + gen_movcf_ps(ctx, rs, rt, cc, 1); + break; + default: + goto pool32f_invalid; + } + } + break; + case PREFX: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + break; + default: + goto pool32f_invalid; + } + break; +#define FINSN_3ARG_SDPS(prfx) \ + switch ((ctx->opcode >> 8) & 0x3) { \ + case FMT_SDPS_S: \ + mips32_op =3D OPC_##prfx##_S; \ + goto do_fpop; \ + case FMT_SDPS_D: \ + mips32_op =3D OPC_##prfx##_D; \ + goto do_fpop; \ + case FMT_SDPS_PS: \ + check_ps(ctx); \ + mips32_op =3D OPC_##prfx##_PS; \ + goto do_fpop; \ + default: \ + goto pool32f_invalid; \ + } + case MINA_FMT: + check_insn(ctx, ISA_MIPS32R6); + switch ((ctx->opcode >> 9) & 0x3) { + case FMT_SDPS_S: + gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); + break; + case FMT_SDPS_D: + gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0); + break; + default: + goto pool32f_invalid; + } + break; + case MAXA_FMT: + check_insn(ctx, ISA_MIPS32R6); + switch ((ctx->opcode >> 9) & 0x3) { + case FMT_SDPS_S: + gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); + break; + case FMT_SDPS_D: + gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0); + break; + default: + goto pool32f_invalid; + } + break; + case 0x30: + /* regular FP ops */ + switch ((ctx->opcode >> 6) & 0x3) { + case ADD_FMT: + FINSN_3ARG_SDPS(ADD); + break; + case SUB_FMT: + FINSN_3ARG_SDPS(SUB); + break; + case MUL_FMT: + FINSN_3ARG_SDPS(MUL); + break; + case DIV_FMT: + fmt =3D (ctx->opcode >> 8) & 0x3; + if (fmt =3D=3D 1) { + mips32_op =3D OPC_DIV_D; + } else if (fmt =3D=3D 0) { + mips32_op =3D OPC_DIV_S; + } else { + goto pool32f_invalid; + } + goto do_fpop; + default: + goto pool32f_invalid; + } + break; + case 0x38: + /* cmovs */ + switch ((ctx->opcode >> 6) & 0x7) { + case MOVN_FMT: /* SELEQZ_FMT */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* SELEQZ_FMT */ + switch ((ctx->opcode >> 9) & 0x3) { + case FMT_SDPS_S: + gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs); + break; + case FMT_SDPS_D: + gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs); + break; + default: + goto pool32f_invalid; + } + } else { + /* MOVN_FMT */ + FINSN_3ARG_SDPS(MOVN); + } + break; + case MOVN_FMT_04: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + FINSN_3ARG_SDPS(MOVN); + break; + case MOVZ_FMT: /* SELNEZ_FMT */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* SELNEZ_FMT */ + switch ((ctx->opcode >> 9) & 0x3) { + case FMT_SDPS_S: + gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs); + break; + case FMT_SDPS_D: + gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs); + break; + default: + goto pool32f_invalid; + } + } else { + /* MOVZ_FMT */ + FINSN_3ARG_SDPS(MOVZ); + } + break; + case MOVZ_FMT_05: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + FINSN_3ARG_SDPS(MOVZ); + break; + case SEL_FMT: + check_insn(ctx, ISA_MIPS32R6); + switch ((ctx->opcode >> 9) & 0x3) { + case FMT_SDPS_S: + gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); + break; + case FMT_SDPS_D: + gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs); + break; + default: + goto pool32f_invalid; + } + break; + case MADDF_FMT: + check_insn(ctx, ISA_MIPS32R6); + switch ((ctx->opcode >> 9) & 0x3) { + case FMT_SDPS_S: + mips32_op =3D OPC_MADDF_S; + goto do_fpop; + case FMT_SDPS_D: + mips32_op =3D OPC_MADDF_D; + goto do_fpop; + default: + goto pool32f_invalid; + } + break; + case MSUBF_FMT: + check_insn(ctx, ISA_MIPS32R6); + switch ((ctx->opcode >> 9) & 0x3) { + case FMT_SDPS_S: + mips32_op =3D OPC_MSUBF_S; + goto do_fpop; + case FMT_SDPS_D: + mips32_op =3D OPC_MSUBF_D; + goto do_fpop; + default: + goto pool32f_invalid; + } + break; + default: + goto pool32f_invalid; + } + break; + do_fpop: + gen_farith(ctx, mips32_op, rt, rs, rd, 0); + break; + default: + pool32f_invalid: + MIPS_INVAL("pool32f"); + generate_exception_end(ctx, EXCP_RI); + break; + } + } else { + generate_exception_err(ctx, EXCP_CpU, 1); + } + break; + case POOL32I: + minor =3D (ctx->opcode >> 21) & 0x1f; + switch (minor) { + case BLTZ: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4); + break; + case BLTZAL: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + break; + case BLTZALS: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + break; + case BGEZ: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4); + break; + case BGEZAL: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + break; + case BGEZALS: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + break; + case BLEZ: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4); + break; + case BGTZ: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4); + break; + + /* Traps */ + case TLTI: /* BC1EQZC */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* BC1EQZC */ + check_cp1_enabled(ctx); + gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0); + } else { + /* TLTI */ + mips32_op =3D OPC_TLTI; + goto do_trapi; + } + break; + case TGEI: /* BC1NEZC */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* BC1NEZC */ + check_cp1_enabled(ctx); + gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0); + } else { + /* TGEI */ + mips32_op =3D OPC_TGEI; + goto do_trapi; + } + break; + case TLTIU: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_TLTIU; + goto do_trapi; + case TGEIU: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_TGEIU; + goto do_trapi; + case TNEI: /* SYNCI */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* SYNCI */ + /* + * Break the TB to be able to sync copied instructions + * immediately. + */ + ctx->base.is_jmp =3D DISAS_STOP; + } else { + /* TNEI */ + mips32_op =3D OPC_TNEI; + goto do_trapi; + } + break; + case TEQI: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_TEQI; + do_trapi: + gen_trap(ctx, mips32_op, rs, -1, imm); + break; + + case BNEZC: + case BEQZC: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_compute_branch(ctx, minor =3D=3D BNEZC ? OPC_BNE : OPC_BEQ, + 4, rs, 0, imm << 1, 0); + /* + * Compact branches don't have a delay slot, so just let + * the normal delay slot handling take us to the branch + * target. + */ + break; + case LUI: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + gen_logic_imm(ctx, OPC_LUI, rs, 0, imm); + break; + case SYNCI: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + /* + * Break the TB to be able to sync copied instructions + * immediately. + */ + ctx->base.is_jmp =3D DISAS_STOP; + break; + case BC2F: + case BC2T: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + /* COP2: Not implemented. */ + generate_exception_err(ctx, EXCP_CpU, 2); + break; + case BC1F: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_B= C1F; + goto do_cp1branch; + case BC1T: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_B= C1T; + goto do_cp1branch; + case BC1ANY4F: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_BC1FANY4; + goto do_cp1mips3d; + case BC1ANY4T: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_BC1TANY4; + do_cp1mips3d: + check_cop1x(ctx); + check_insn(ctx, ASE_MIPS3D); + /* Fall through */ + do_cp1branch: + if (env->CP0_Config1 & (1 << CP0C1_FP)) { + check_cp1_enabled(ctx); + gen_compute_branch1(ctx, mips32_op, + (ctx->opcode >> 18) & 0x7, imm << 1); + } else { + generate_exception_err(ctx, EXCP_CpU, 1); + } + break; + case BPOSGE64: + case BPOSGE32: + /* MIPS DSP: not implemented */ + /* Fall through */ + default: + MIPS_INVAL("pool32i"); + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case POOL32C: + minor =3D (ctx->opcode >> 12) & 0xf; + offset =3D sextract32(ctx->opcode, 0, + (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12); + switch (minor) { + case LWL: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_LWL; + goto do_ld_lr; + case SWL: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_SWL; + goto do_st_lr; + case LWR: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_LWR; + goto do_ld_lr; + case SWR: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_SWR; + goto do_st_lr; +#if defined(TARGET_MIPS64) + case LDL: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_LDL; + goto do_ld_lr; + case SDL: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_SDL; + goto do_st_lr; + case LDR: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_LDR; + goto do_ld_lr; + case SDR: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_SDR; + goto do_st_lr; + case LWU: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + mips32_op =3D OPC_LWU; + goto do_ld_lr; + case LLD: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + mips32_op =3D OPC_LLD; + goto do_ld_lr; +#endif + case LL: + mips32_op =3D OPC_LL; + goto do_ld_lr; + do_ld_lr: + gen_ld(ctx, mips32_op, rt, rs, offset); + break; + do_st_lr: + gen_st(ctx, mips32_op, rt, rs, offset); + break; + case SC: + gen_st_cond(ctx, rt, rs, offset, MO_TESL, false); + break; +#if defined(TARGET_MIPS64) + case SCD: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false); + break; +#endif + case LD_EVA: + if (!ctx->eva) { + MIPS_INVAL("pool32c ld-eva"); + generate_exception_end(ctx, EXCP_RI); + break; + } + check_cp0_enabled(ctx); + + minor2 =3D (ctx->opcode >> 9) & 0x7; + offset =3D sextract32(ctx->opcode, 0, 9); + switch (minor2) { + case LBUE: + mips32_op =3D OPC_LBUE; + goto do_ld_lr; + case LHUE: + mips32_op =3D OPC_LHUE; + goto do_ld_lr; + case LWLE: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_LWLE; + goto do_ld_lr; + case LWRE: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_LWRE; + goto do_ld_lr; + case LBE: + mips32_op =3D OPC_LBE; + goto do_ld_lr; + case LHE: + mips32_op =3D OPC_LHE; + goto do_ld_lr; + case LLE: + mips32_op =3D OPC_LLE; + goto do_ld_lr; + case LWE: + mips32_op =3D OPC_LWE; + goto do_ld_lr; + }; + break; + case ST_EVA: + if (!ctx->eva) { + MIPS_INVAL("pool32c st-eva"); + generate_exception_end(ctx, EXCP_RI); + break; + } + check_cp0_enabled(ctx); + + minor2 =3D (ctx->opcode >> 9) & 0x7; + offset =3D sextract32(ctx->opcode, 0, 9); + switch (minor2) { + case SWLE: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_SWLE; + goto do_st_lr; + case SWRE: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + mips32_op =3D OPC_SWRE; + goto do_st_lr; + case PREFE: + /* Treat as no-op */ + if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >=3D 24)) { + /* hint codes 24-31 are reserved and signal RI */ + generate_exception(ctx, EXCP_RI); + } + break; + case CACHEE: + /* Treat as no-op */ + if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { + gen_cache_operation(ctx, rt, rs, offset); + } + break; + case SBE: + mips32_op =3D OPC_SBE; + goto do_st_lr; + case SHE: + mips32_op =3D OPC_SHE; + goto do_st_lr; + case SCE: + gen_st_cond(ctx, rt, rs, offset, MO_TESL, true); + break; + case SWE: + mips32_op =3D OPC_SWE; + goto do_st_lr; + }; + break; + case PREF: + /* Treat as no-op */ + if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >=3D 24)) { + /* hint codes 24-31 are reserved and signal RI */ + generate_exception(ctx, EXCP_RI); + } + break; + default: + MIPS_INVAL("pool32c"); + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case ADDI32: /* AUI, LUI */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* AUI, LUI */ + gen_logic_imm(ctx, OPC_LUI, rt, rs, imm); + } else { + /* ADDI32 */ + mips32_op =3D OPC_ADDI; + goto do_addi; + } + break; + case ADDIU32: + mips32_op =3D OPC_ADDIU; + do_addi: + gen_arith_imm(ctx, mips32_op, rt, rs, imm); + break; + + /* Logical operations */ + case ORI32: + mips32_op =3D OPC_ORI; + goto do_logici; + case XORI32: + mips32_op =3D OPC_XORI; + goto do_logici; + case ANDI32: + mips32_op =3D OPC_ANDI; + do_logici: + gen_logic_imm(ctx, mips32_op, rt, rs, imm); + break; + + /* Set less than immediate */ + case SLTI32: + mips32_op =3D OPC_SLTI; + goto do_slti; + case SLTIU32: + mips32_op =3D OPC_SLTIU; + do_slti: + gen_slt_imm(ctx, mips32_op, rt, rs, imm); + break; + case JALX32: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + offset =3D (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; + gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + break; + case JALS32: /* BOVC, BEQC, BEQZALC */ + if (ctx->insn_flags & ISA_MIPS32R6) { + if (rs >=3D rt) { + /* BOVC */ + mips32_op =3D OPC_BOVC; + } else if (rs < rt && rs =3D=3D 0) { + /* BEQZALC */ + mips32_op =3D OPC_BEQZALC; + } else { + /* BEQC */ + mips32_op =3D OPC_BEQC; + } + gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); + } else { + /* JALS32 */ + offset =3D (int32_t)(ctx->opcode & 0x3FFFFFF) << 1; + gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + } + break; + case BEQ32: /* BC */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* BC */ + gen_compute_compact_branch(ctx, OPC_BC, 0, 0, + sextract32(ctx->opcode << 1, 0, 27)= ); + } else { + /* BEQ32 */ + gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4); + } + break; + case BNE32: /* BALC */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* BALC */ + gen_compute_compact_branch(ctx, OPC_BALC, 0, 0, + sextract32(ctx->opcode << 1, 0, 27)= ); + } else { + /* BNE32 */ + gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4); + } + break; + case J32: /* BGTZC, BLTZC, BLTC */ + if (ctx->insn_flags & ISA_MIPS32R6) { + if (rs =3D=3D 0 && rt !=3D 0) { + /* BGTZC */ + mips32_op =3D OPC_BGTZC; + } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { + /* BLTZC */ + mips32_op =3D OPC_BLTZC; + } else { + /* BLTC */ + mips32_op =3D OPC_BLTC; + } + gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); + } else { + /* J32 */ + gen_compute_branch(ctx, OPC_J, 4, rt, rs, + (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4); + } + break; + case JAL32: /* BLEZC, BGEZC, BGEC */ + if (ctx->insn_flags & ISA_MIPS32R6) { + if (rs =3D=3D 0 && rt !=3D 0) { + /* BLEZC */ + mips32_op =3D OPC_BLEZC; + } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { + /* BGEZC */ + mips32_op =3D OPC_BGEZC; + } else { + /* BGEC */ + mips32_op =3D OPC_BGEC; + } + gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); + } else { + /* JAL32 */ + gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, + (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4); + ctx->hflags |=3D MIPS_HFLAG_BDS_STRICT; + } + break; + /* Floating point (COP1) */ + case LWC132: + mips32_op =3D OPC_LWC1; + goto do_cop1; + case LDC132: + mips32_op =3D OPC_LDC1; + goto do_cop1; + case SWC132: + mips32_op =3D OPC_SWC1; + goto do_cop1; + case SDC132: + mips32_op =3D OPC_SDC1; + do_cop1: + gen_cop1_ldst(ctx, mips32_op, rt, rs, imm); + break; + case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */ + if (ctx->insn_flags & ISA_MIPS32R6) { + /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */ + switch ((ctx->opcode >> 16) & 0x1f) { + case ADDIUPC_00: + case ADDIUPC_01: + case ADDIUPC_02: + case ADDIUPC_03: + case ADDIUPC_04: + case ADDIUPC_05: + case ADDIUPC_06: + case ADDIUPC_07: + gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt); + break; + case AUIPC: + gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt); + break; + case ALUIPC: + gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt); + break; + case LWPC_08: + case LWPC_09: + case LWPC_0A: + case LWPC_0B: + case LWPC_0C: + case LWPC_0D: + case LWPC_0E: + case LWPC_0F: + gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt); + break; + default: + generate_exception(ctx, EXCP_RI); + break; + } + } else { + /* ADDIUPC */ + int reg =3D mmreg(ZIMM(ctx->opcode, 23, 3)); + offset =3D SIMM(ctx->opcode, 0, 23) << 2; + + gen_addiupc(ctx, reg, offset, 0, 0); + } + break; + case BNVC: /* BNEC, BNEZALC */ + check_insn(ctx, ISA_MIPS32R6); + if (rs >=3D rt) { + /* BNVC */ + mips32_op =3D OPC_BNVC; + } else if (rs < rt && rs =3D=3D 0) { + /* BNEZALC */ + mips32_op =3D OPC_BNEZALC; + } else { + /* BNEC */ + mips32_op =3D OPC_BNEC; + } + gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); + break; + case R6_BNEZC: /* JIALC */ + check_insn(ctx, ISA_MIPS32R6); + if (rt !=3D 0) { + /* BNEZC */ + gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0, + sextract32(ctx->opcode << 1, 0, 22)= ); + } else { + /* JIALC */ + gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm); + } + break; + case R6_BEQZC: /* JIC */ + check_insn(ctx, ISA_MIPS32R6); + if (rt !=3D 0) { + /* BEQZC */ + gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0, + sextract32(ctx->opcode << 1, 0, 22)= ); + } else { + /* JIC */ + gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm); + } + break; + case BLEZALC: /* BGEZALC, BGEUC */ + check_insn(ctx, ISA_MIPS32R6); + if (rs =3D=3D 0 && rt !=3D 0) { + /* BLEZALC */ + mips32_op =3D OPC_BLEZALC; + } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { + /* BGEZALC */ + mips32_op =3D OPC_BGEZALC; + } else { + /* BGEUC */ + mips32_op =3D OPC_BGEUC; + } + gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); + break; + case BGTZALC: /* BLTZALC, BLTUC */ + check_insn(ctx, ISA_MIPS32R6); + if (rs =3D=3D 0 && rt !=3D 0) { + /* BGTZALC */ + mips32_op =3D OPC_BGTZALC; + } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { + /* BLTZALC */ + mips32_op =3D OPC_BLTZALC; + } else { + /* BLTUC */ + mips32_op =3D OPC_BLTUC; + } + gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); + break; + /* Loads and stores */ + case LB32: + mips32_op =3D OPC_LB; + goto do_ld; + case LBU32: + mips32_op =3D OPC_LBU; + goto do_ld; + case LH32: + mips32_op =3D OPC_LH; + goto do_ld; + case LHU32: + mips32_op =3D OPC_LHU; + goto do_ld; + case LW32: + mips32_op =3D OPC_LW; + goto do_ld; +#ifdef TARGET_MIPS64 + case LD32: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + mips32_op =3D OPC_LD; + goto do_ld; + case SD32: + check_insn(ctx, ISA_MIPS3); + check_mips_64(ctx); + mips32_op =3D OPC_SD; + goto do_st; +#endif + case SB32: + mips32_op =3D OPC_SB; + goto do_st; + case SH32: + mips32_op =3D OPC_SH; + goto do_st; + case SW32: + mips32_op =3D OPC_SW; + goto do_st; + do_ld: + gen_ld(ctx, mips32_op, rt, rs, imm); + break; + do_st: + gen_st(ctx, mips32_op, rt, rs, imm); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t op; + + /* make sure instructions are on a halfword boundary */ + if (ctx->base.pc_next & 0x1) { + env->CP0_BadVAddr =3D ctx->base.pc_next; + generate_exception_end(ctx, EXCP_AdEL); + return 2; + } + + op =3D (ctx->opcode >> 10) & 0x3f; + /* Enforce properly-sized instructions in a delay slot */ + if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) { + switch (op & 0x7) { /* MSB-3..MSB-5 */ + case 0: + /* POOL32A, POOL32B, POOL32I, POOL32C */ + case 4: + /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32= */ + case 5: + /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */ + case 6: + /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */ + case 7: + /* LB32, LH32, LWC132, LDC132, LW32 */ + if (ctx->hflags & MIPS_HFLAG_BDS16) { + generate_exception_end(ctx, EXCP_RI); + return 2; + } + break; + case 1: + /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */ + case 2: + /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */ + case 3: + /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */ + if (ctx->hflags & MIPS_HFLAG_BDS32) { + generate_exception_end(ctx, EXCP_RI); + return 2; + } + break; + } + } + + switch (op) { + case POOL16A: + { + int rd =3D mmreg(uMIPS_RD(ctx->opcode)); + int rs1 =3D mmreg(uMIPS_RS1(ctx->opcode)); + int rs2 =3D mmreg(uMIPS_RS2(ctx->opcode)); + uint32_t opc =3D 0; + + switch (ctx->opcode & 0x1) { + case ADDU16: + opc =3D OPC_ADDU; + break; + case SUBU16: + opc =3D OPC_SUBU; + break; + } + if (ctx->insn_flags & ISA_MIPS32R6) { + /* + * In the Release 6, the register number location in + * the instruction encoding has changed. + */ + gen_arith(ctx, opc, rs1, rd, rs2); + } else { + gen_arith(ctx, opc, rd, rs1, rs2); + } + } + break; + case POOL16B: + { + int rd =3D mmreg(uMIPS_RD(ctx->opcode)); + int rs =3D mmreg(uMIPS_RS(ctx->opcode)); + int amount =3D (ctx->opcode >> 1) & 0x7; + uint32_t opc =3D 0; + amount =3D amount =3D=3D 0 ? 8 : amount; + + switch (ctx->opcode & 0x1) { + case SLL16: + opc =3D OPC_SLL; + break; + case SRL16: + opc =3D OPC_SRL; + break; + } + + gen_shift_imm(ctx, opc, rd, rs, amount); + } + break; + case POOL16C: + if (ctx->insn_flags & ISA_MIPS32R6) { + gen_pool16c_r6_insn(ctx); + } else { + gen_pool16c_insn(ctx); + } + break; + case LWGP16: + { + int rd =3D mmreg(uMIPS_RD(ctx->opcode)); + int rb =3D 28; /* GP */ + int16_t offset =3D SIMM(ctx->opcode, 0, 7) << 2; + + gen_ld(ctx, OPC_LW, rd, rb, offset); + } + break; + case POOL16F: + check_insn_opc_removed(ctx, ISA_MIPS32R6); + if (ctx->opcode & 1) { + generate_exception_end(ctx, EXCP_RI); + } else { + /* MOVEP */ + int enc_dest =3D uMIPS_RD(ctx->opcode); + int enc_rt =3D uMIPS_RS2(ctx->opcode); + int enc_rs =3D uMIPS_RS1(ctx->opcode); + gen_movep(ctx, enc_dest, enc_rt, enc_rs); + } + break; + case LBU16: + { + int rd =3D mmreg(uMIPS_RD(ctx->opcode)); + int rb =3D mmreg(uMIPS_RS(ctx->opcode)); + int16_t offset =3D ZIMM(ctx->opcode, 0, 4); + offset =3D (offset =3D=3D 0xf ? -1 : offset); + + gen_ld(ctx, OPC_LBU, rd, rb, offset); + } + break; + case LHU16: + { + int rd =3D mmreg(uMIPS_RD(ctx->opcode)); + int rb =3D mmreg(uMIPS_RS(ctx->opcode)); + int16_t offset =3D ZIMM(ctx->opcode, 0, 4) << 1; + + gen_ld(ctx, OPC_LHU, rd, rb, offset); + } + break; + case LWSP16: + { + int rd =3D (ctx->opcode >> 5) & 0x1f; + int rb =3D 29; /* SP */ + int16_t offset =3D ZIMM(ctx->opcode, 0, 5) << 2; + + gen_ld(ctx, OPC_LW, rd, rb, offset); + } + break; + case LW16: + { + int rd =3D mmreg(uMIPS_RD(ctx->opcode)); + int rb =3D mmreg(uMIPS_RS(ctx->opcode)); + int16_t offset =3D ZIMM(ctx->opcode, 0, 4) << 2; + + gen_ld(ctx, OPC_LW, rd, rb, offset); + } + break; + case SB16: + { + int rd =3D mmreg2(uMIPS_RD(ctx->opcode)); + int rb =3D mmreg(uMIPS_RS(ctx->opcode)); + int16_t offset =3D ZIMM(ctx->opcode, 0, 4); + + gen_st(ctx, OPC_SB, rd, rb, offset); + } + break; + case SH16: + { + int rd =3D mmreg2(uMIPS_RD(ctx->opcode)); + int rb =3D mmreg(uMIPS_RS(ctx->opcode)); + int16_t offset =3D ZIMM(ctx->opcode, 0, 4) << 1; + + gen_st(ctx, OPC_SH, rd, rb, offset); + } + break; + case SWSP16: + { + int rd =3D (ctx->opcode >> 5) & 0x1f; + int rb =3D 29; /* SP */ + int16_t offset =3D ZIMM(ctx->opcode, 0, 5) << 2; + + gen_st(ctx, OPC_SW, rd, rb, offset); + } + break; + case SW16: + { + int rd =3D mmreg2(uMIPS_RD(ctx->opcode)); + int rb =3D mmreg(uMIPS_RS(ctx->opcode)); + int16_t offset =3D ZIMM(ctx->opcode, 0, 4) << 2; + + gen_st(ctx, OPC_SW, rd, rb, offset); + } + break; + case MOVE16: + { + int rd =3D uMIPS_RD5(ctx->opcode); + int rs =3D uMIPS_RS5(ctx->opcode); + + gen_arith(ctx, OPC_ADDU, rd, rs, 0); + } + break; + case ANDI16: + gen_andi16(ctx); + break; + case POOL16D: + switch (ctx->opcode & 0x1) { + case ADDIUS5: + gen_addius5(ctx); + break; + case ADDIUSP: + gen_addiusp(ctx); + break; + } + break; + case POOL16E: + switch (ctx->opcode & 0x1) { + case ADDIUR2: + gen_addiur2(ctx); + break; + case ADDIUR1SP: + gen_addiur1sp(ctx); + break; + } + break; + case B16: /* BC16 */ + gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, + sextract32(ctx->opcode, 0, 10) << 1, + (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4); + break; + case BNEZ16: /* BNEZC16 */ + case BEQZ16: /* BEQZC16 */ + gen_compute_branch(ctx, op =3D=3D BNEZ16 ? OPC_BNE : OPC_BEQ, 2, + mmreg(uMIPS_RD(ctx->opcode)), + 0, sextract32(ctx->opcode, 0, 7) << 1, + (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4); + + break; + case LI16: + { + int reg =3D mmreg(uMIPS_RD(ctx->opcode)); + int imm =3D ZIMM(ctx->opcode, 0, 7); + + imm =3D (imm =3D=3D 0x7f ? -1 : imm); + tcg_gen_movi_tl(cpu_gpr[reg], imm); + } + break; + case RES_29: + case RES_31: + case RES_39: + generate_exception_end(ctx, EXCP_RI); + break; + default: + decode_micromips32_opc(env, ctx); + return 4; + } + + return 2; +} --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.51 as permitted sender) client-ip=209.85.221.51; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f51.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.51 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail(p=none dis=none) header.from=amsat.org ARC-Seal: i=1; a=rsa-sha256; t=1605906594; cv=none; d=zohomail.com; s=zohoarc; b=h3gjJ19qaM861oMvdHoHuuhr+z/CPo4q1cLPhZqkYXndOfOTKf2LGsOqcN0nKe+Ylz3TQEM7DyOE1+RhVnCBemulm9KgrZo54jG9XuEKzPeu+tELTE291Rhb3PbWdHzAfNrJ0FXkxDlL3plZuWv1/EvI+9RetwfSWWpwpaO8ndw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906594; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Cs6o/bkXGk4sz+UIA1JTuJtZ61w1fJ/9oPmxIdP9vmE=; b=n2LwNYIjCn68eBeHLpLiQR7qul3Q/LY0w29xm3+omQJ4ePR1PIbUlbI4lKkHQgUEx1HA0nF6V28klJlaJTFACc72Zm6oUKrBq2KvC16QwLnK4QeoLOH+KdOVcSWbjrt5h8dhHamf4CWHD/6D6P+j/Dz35ZNzBi3OdNZKEjuSl1E= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.51 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) by mx.zohomail.com with SMTPS id 16059065941747.592139869409834; Fri, 20 Nov 2020 13:09:54 -0800 (PST) Received: by mail-wr1-f51.google.com with SMTP id d12so11623126wrr.13 for ; Fri, 20 Nov 2020 13:09:52 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id 25sm5336896wmk.19.2020.11.20.13.09.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Cs6o/bkXGk4sz+UIA1JTuJtZ61w1fJ/9oPmxIdP9vmE=; b=qQ5dF8K2SpV0OnB8r6Y1YH00hqo8CJ6kEwWoE43hwLf1hfsa5QIHlrtgCBKbKRAoLf FS5peXZMSR9UWPO4h+4nrlH5VC5JhxXRnmJfd9VIThuloHBEd2p6YT3p6CsoQJ6dO3w7 8HSZBG+Yj1Ldkefgw2CludbV2/C9b4S7DndsS0k26c9xWQ6QkCBaoikEIhL0J9X7WU4D zfE2gc4BNQn0wiVFnFJqHAu90Z91W6VIB2qf2pKzM/C2mJyG9KJj/W1I9kW/D12HT5Wq IT1yJagUjaAo4/Fcsp1VuoqBVQAqwbwdo7gCKe8yHaGD1h+kaGQOLF39lW1XfJ3WabZx iBRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=Cs6o/bkXGk4sz+UIA1JTuJtZ61w1fJ/9oPmxIdP9vmE=; b=XvqO1N0k0YA+vF7+SaD2bpiQB8gCAvn6HQ3PZz3OoRMbuC/GjqeaW3KixSghFEJSyJ OojRfvEKvXVyJ98YlPu2Aq7woWEhj0k7kNzqkiI1wrrsF630K5tJsQ5DlHiM5mXBq80t OEdooYv4fTdwRDOFOl270HHCagOHrp0hGpLIjlcvla7nnyDVpkSnr0XGE0lZYt80s3VD 9i/oKed9hLyXxNnqRBt0y49b/KuV5NZ6nK2m7sEW43qmT5slW9E9VCtr2zqh7LWh+yfV IN1QBr3ocJymkPqA7fNM4rDWs36jZyZ+10DYPqotzWk5pffu3fKkOVn0TWfmCfXfEQ3X AYBg== X-Gm-Message-State: AOAM530hlu4XZGmerJMrhdKm01gZIl53WUcwAZW/aGPPFw5SG4RsRwU5 /hESgJBxPsmp1IpNb2V9Qgc= X-Google-Smtp-Source: ABdhPJxAOGCAwEHdgLD6rUq+jrTC08NUkHobIzLqa2U1ES6dsherdJc78PbyWS2BEhBhyjTa2lI5vg== X-Received: by 2002:adf:d84b:: with SMTP id k11mr17877530wrl.305.1605906591126; Fri, 20 Nov 2020 13:09:51 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 12/26] target/mips: Extract nanoMIPS ISA translation routines Date: Fri, 20 Nov 2020 22:08:30 +0100 Message-Id: <20201120210844.2625602-13-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract 4800 lines from the huge translate.c to a new file, 'isa-nanomips_translate.c.inc'. As there are too many inter- dependencies we don't compile it as another object, but keep including it in the big translate.o. We gain in code maintainability. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/translate.c | 4838 +-------------------- MAINTAINERS | 1 + target/mips/isa-nanomips_translate.c.inc | 4839 ++++++++++++++++++++++ 3 files changed, 4841 insertions(+), 4837 deletions(-) create mode 100644 target/mips/isa-nanomips_translate.c.inc diff --git a/target/mips/translate.c b/target/mips/translate.c index 17dfee12b7d..095ee31ab5f 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -6012,130 +6012,6 @@ static void gen_compute_branch(DisasContext *ctx, u= int32_t opc, tcg_temp_free(t1); } =20 - -/* nanoMIPS Branches */ -static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc, - int insn_bytes, - int rs, int rt, int32_t offset) -{ - target_ulong btgt =3D -1; - int bcond_compute =3D 0; - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - - /* Load needed operands */ - switch (opc) { - case OPC_BEQ: - case OPC_BNE: - /* Compare two registers */ - if (rs !=3D rt) { - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - bcond_compute =3D 1; - } - btgt =3D ctx->base.pc_next + insn_bytes + offset; - break; - case OPC_BGEZAL: - /* Compare to zero */ - if (rs !=3D 0) { - gen_load_gpr(t0, rs); - bcond_compute =3D 1; - } - btgt =3D ctx->base.pc_next + insn_bytes + offset; - break; - case OPC_BPOSGE32: - tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); - bcond_compute =3D 1; - btgt =3D ctx->base.pc_next + insn_bytes + offset; - break; - case OPC_JR: - case OPC_JALR: - /* Jump to register */ - if (offset !=3D 0 && offset !=3D 16) { - /* - * Hint =3D 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the - * others are reserved. - */ - MIPS_INVAL("jump hint"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - gen_load_gpr(btarget, rs); - break; - default: - MIPS_INVAL("branch/jump"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - if (bcond_compute =3D=3D 0) { - /* No condition to be computed */ - switch (opc) { - case OPC_BEQ: /* rx =3D=3D rx */ - /* Always take */ - ctx->hflags |=3D MIPS_HFLAG_B; - break; - case OPC_BGEZAL: /* 0 >=3D 0 */ - /* Always take and link */ - tcg_gen_movi_tl(cpu_gpr[31], - ctx->base.pc_next + insn_bytes); - ctx->hflags |=3D MIPS_HFLAG_B; - break; - case OPC_BNE: /* rx !=3D rx */ - tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); - /* Skip the instruction in the delay slot */ - ctx->base.pc_next +=3D 4; - goto out; - case OPC_JR: - ctx->hflags |=3D MIPS_HFLAG_BR; - break; - case OPC_JALR: - if (rt > 0) { - tcg_gen_movi_tl(cpu_gpr[rt], - ctx->base.pc_next + insn_bytes); - } - ctx->hflags |=3D MIPS_HFLAG_BR; - break; - default: - MIPS_INVAL("branch/jump"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - } else { - switch (opc) { - case OPC_BEQ: - tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); - goto not_likely; - case OPC_BNE: - tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); - goto not_likely; - case OPC_BGEZAL: - tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); - tcg_gen_movi_tl(cpu_gpr[31], - ctx->base.pc_next + insn_bytes); - goto not_likely; - case OPC_BPOSGE32: - tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); - not_likely: - ctx->hflags |=3D MIPS_HFLAG_BC; - break; - default: - MIPS_INVAL("conditional branch/jump"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - } - - ctx->btarget =3D btgt; - - out: - if (insn_bytes =3D=3D 2) { - ctx->hflags |=3D MIPS_HFLAG_B16; - } - tcg_temp_free(t0); - tcg_temp_free(t1); -} - - /* special3 bitfield operations */ static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, int rs, int lsb, int msb) @@ -13134,4719 +13010,7 @@ out: =20 #include "ase-mips16e_translate.c.inc" #include "isa-micromips_translate.c.inc" - -/* - * - * nanoMIPS opcodes - * - */ - -/* MAJOR, P16, and P32 pools opcodes */ -enum { - NM_P_ADDIU =3D 0x00, - NM_ADDIUPC =3D 0x01, - NM_MOVE_BALC =3D 0x02, - NM_P16_MV =3D 0x04, - NM_LW16 =3D 0x05, - NM_BC16 =3D 0x06, - NM_P16_SR =3D 0x07, - - NM_POOL32A =3D 0x08, - NM_P_BAL =3D 0x0a, - NM_P16_SHIFT =3D 0x0c, - NM_LWSP16 =3D 0x0d, - NM_BALC16 =3D 0x0e, - NM_P16_4X4 =3D 0x0f, - - NM_P_GP_W =3D 0x10, - NM_P_GP_BH =3D 0x11, - NM_P_J =3D 0x12, - NM_P16C =3D 0x14, - NM_LWGP16 =3D 0x15, - NM_P16_LB =3D 0x17, - - NM_P48I =3D 0x18, - NM_P16_A1 =3D 0x1c, - NM_LW4X4 =3D 0x1d, - NM_P16_LH =3D 0x1f, - - NM_P_U12 =3D 0x20, - NM_P_LS_U12 =3D 0x21, - NM_P_BR1 =3D 0x22, - NM_P16_A2 =3D 0x24, - NM_SW16 =3D 0x25, - NM_BEQZC16 =3D 0x26, - - NM_POOL32F =3D 0x28, - NM_P_LS_S9 =3D 0x29, - NM_P_BR2 =3D 0x2a, - - NM_P16_ADDU =3D 0x2c, - NM_SWSP16 =3D 0x2d, - NM_BNEZC16 =3D 0x2e, - NM_MOVEP =3D 0x2f, - - NM_POOL32S =3D 0x30, - NM_P_BRI =3D 0x32, - NM_LI16 =3D 0x34, - NM_SWGP16 =3D 0x35, - NM_P16_BR =3D 0x36, - - NM_P_LUI =3D 0x38, - NM_ANDI16 =3D 0x3c, - NM_SW4X4 =3D 0x3d, - NM_MOVEPREV =3D 0x3f, -}; - -/* POOL32A instruction pool */ -enum { - NM_POOL32A0 =3D 0x00, - NM_SPECIAL2 =3D 0x01, - NM_COP2_1 =3D 0x02, - NM_UDI =3D 0x03, - NM_POOL32A5 =3D 0x05, - NM_POOL32A7 =3D 0x07, -}; - -/* P.GP.W instruction pool */ -enum { - NM_ADDIUGP_W =3D 0x00, - NM_LWGP =3D 0x02, - NM_SWGP =3D 0x03, -}; - -/* P48I instruction pool */ -enum { - NM_LI48 =3D 0x00, - NM_ADDIU48 =3D 0x01, - NM_ADDIUGP48 =3D 0x02, - NM_ADDIUPC48 =3D 0x03, - NM_LWPC48 =3D 0x0b, - NM_SWPC48 =3D 0x0f, -}; - -/* P.U12 instruction pool */ -enum { - NM_ORI =3D 0x00, - NM_XORI =3D 0x01, - NM_ANDI =3D 0x02, - NM_P_SR =3D 0x03, - NM_SLTI =3D 0x04, - NM_SLTIU =3D 0x05, - NM_SEQI =3D 0x06, - NM_ADDIUNEG =3D 0x08, - NM_P_SHIFT =3D 0x0c, - NM_P_ROTX =3D 0x0d, - NM_P_INS =3D 0x0e, - NM_P_EXT =3D 0x0f, -}; - -/* POOL32F instruction pool */ -enum { - NM_POOL32F_0 =3D 0x00, - NM_POOL32F_3 =3D 0x03, - NM_POOL32F_5 =3D 0x05, -}; - -/* POOL32S instruction pool */ -enum { - NM_POOL32S_0 =3D 0x00, - NM_POOL32S_4 =3D 0x04, -}; - -/* P.LUI instruction pool */ -enum { - NM_LUI =3D 0x00, - NM_ALUIPC =3D 0x01, -}; - -/* P.GP.BH instruction pool */ -enum { - NM_LBGP =3D 0x00, - NM_SBGP =3D 0x01, - NM_LBUGP =3D 0x02, - NM_ADDIUGP_B =3D 0x03, - NM_P_GP_LH =3D 0x04, - NM_P_GP_SH =3D 0x05, - NM_P_GP_CP1 =3D 0x06, -}; - -/* P.LS.U12 instruction pool */ -enum { - NM_LB =3D 0x00, - NM_SB =3D 0x01, - NM_LBU =3D 0x02, - NM_P_PREFU12 =3D 0x03, - NM_LH =3D 0x04, - NM_SH =3D 0x05, - NM_LHU =3D 0x06, - NM_LWU =3D 0x07, - NM_LW =3D 0x08, - NM_SW =3D 0x09, - NM_LWC1 =3D 0x0a, - NM_SWC1 =3D 0x0b, - NM_LDC1 =3D 0x0e, - NM_SDC1 =3D 0x0f, -}; - -/* P.LS.S9 instruction pool */ -enum { - NM_P_LS_S0 =3D 0x00, - NM_P_LS_S1 =3D 0x01, - NM_P_LS_E0 =3D 0x02, - NM_P_LS_WM =3D 0x04, - NM_P_LS_UAWM =3D 0x05, -}; - -/* P.BAL instruction pool */ -enum { - NM_BC =3D 0x00, - NM_BALC =3D 0x01, -}; - -/* P.J instruction pool */ -enum { - NM_JALRC =3D 0x00, - NM_JALRC_HB =3D 0x01, - NM_P_BALRSC =3D 0x08, -}; - -/* P.BR1 instruction pool */ -enum { - NM_BEQC =3D 0x00, - NM_P_BR3A =3D 0x01, - NM_BGEC =3D 0x02, - NM_BGEUC =3D 0x03, -}; - -/* P.BR2 instruction pool */ -enum { - NM_BNEC =3D 0x00, - NM_BLTC =3D 0x02, - NM_BLTUC =3D 0x03, -}; - -/* P.BRI instruction pool */ -enum { - NM_BEQIC =3D 0x00, - NM_BBEQZC =3D 0x01, - NM_BGEIC =3D 0x02, - NM_BGEIUC =3D 0x03, - NM_BNEIC =3D 0x04, - NM_BBNEZC =3D 0x05, - NM_BLTIC =3D 0x06, - NM_BLTIUC =3D 0x07, -}; - -/* P16.SHIFT instruction pool */ -enum { - NM_SLL16 =3D 0x00, - NM_SRL16 =3D 0x01, -}; - -/* POOL16C instruction pool */ -enum { - NM_POOL16C_0 =3D 0x00, - NM_LWXS16 =3D 0x01, -}; - -/* P16.A1 instruction pool */ -enum { - NM_ADDIUR1SP =3D 0x01, -}; - -/* P16.A2 instruction pool */ -enum { - NM_ADDIUR2 =3D 0x00, - NM_P_ADDIURS5 =3D 0x01, -}; - -/* P16.ADDU instruction pool */ -enum { - NM_ADDU16 =3D 0x00, - NM_SUBU16 =3D 0x01, -}; - -/* P16.SR instruction pool */ -enum { - NM_SAVE16 =3D 0x00, - NM_RESTORE_JRC16 =3D 0x01, -}; - -/* P16.4X4 instruction pool */ -enum { - NM_ADDU4X4 =3D 0x00, - NM_MUL4X4 =3D 0x01, -}; - -/* P16.LB instruction pool */ -enum { - NM_LB16 =3D 0x00, - NM_SB16 =3D 0x01, - NM_LBU16 =3D 0x02, -}; - -/* P16.LH instruction pool */ -enum { - NM_LH16 =3D 0x00, - NM_SH16 =3D 0x01, - NM_LHU16 =3D 0x02, -}; - -/* P.RI instruction pool */ -enum { - NM_SIGRIE =3D 0x00, - NM_P_SYSCALL =3D 0x01, - NM_BREAK =3D 0x02, - NM_SDBBP =3D 0x03, -}; - -/* POOL32A0 instruction pool */ -enum { - NM_P_TRAP =3D 0x00, - NM_SEB =3D 0x01, - NM_SLLV =3D 0x02, - NM_MUL =3D 0x03, - NM_MFC0 =3D 0x06, - NM_MFHC0 =3D 0x07, - NM_SEH =3D 0x09, - NM_SRLV =3D 0x0a, - NM_MUH =3D 0x0b, - NM_MTC0 =3D 0x0e, - NM_MTHC0 =3D 0x0f, - NM_SRAV =3D 0x12, - NM_MULU =3D 0x13, - NM_ROTRV =3D 0x1a, - NM_MUHU =3D 0x1b, - NM_ADD =3D 0x22, - NM_DIV =3D 0x23, - NM_ADDU =3D 0x2a, - NM_MOD =3D 0x2b, - NM_SUB =3D 0x32, - NM_DIVU =3D 0x33, - NM_RDHWR =3D 0x38, - NM_SUBU =3D 0x3a, - NM_MODU =3D 0x3b, - NM_P_CMOVE =3D 0x42, - NM_FORK =3D 0x45, - NM_MFTR =3D 0x46, - NM_MFHTR =3D 0x47, - NM_AND =3D 0x4a, - NM_YIELD =3D 0x4d, - NM_MTTR =3D 0x4e, - NM_MTHTR =3D 0x4f, - NM_OR =3D 0x52, - NM_D_E_MT_VPE =3D 0x56, - NM_NOR =3D 0x5a, - NM_XOR =3D 0x62, - NM_SLT =3D 0x6a, - NM_P_SLTU =3D 0x72, - NM_SOV =3D 0x7a, -}; - -/* CRC32 instruction pool */ -enum { - NM_CRC32B =3D 0x00, - NM_CRC32H =3D 0x01, - NM_CRC32W =3D 0x02, - NM_CRC32CB =3D 0x04, - NM_CRC32CH =3D 0x05, - NM_CRC32CW =3D 0x06, -}; - -/* POOL32A5 instruction pool */ -enum { - NM_CMP_EQ_PH =3D 0x00, - NM_CMP_LT_PH =3D 0x08, - NM_CMP_LE_PH =3D 0x10, - NM_CMPGU_EQ_QB =3D 0x18, - NM_CMPGU_LT_QB =3D 0x20, - NM_CMPGU_LE_QB =3D 0x28, - NM_CMPGDU_EQ_QB =3D 0x30, - NM_CMPGDU_LT_QB =3D 0x38, - NM_CMPGDU_LE_QB =3D 0x40, - NM_CMPU_EQ_QB =3D 0x48, - NM_CMPU_LT_QB =3D 0x50, - NM_CMPU_LE_QB =3D 0x58, - NM_ADDQ_S_W =3D 0x60, - NM_SUBQ_S_W =3D 0x68, - NM_ADDSC =3D 0x70, - NM_ADDWC =3D 0x78, - - NM_ADDQ_S_PH =3D 0x01, - NM_ADDQH_R_PH =3D 0x09, - NM_ADDQH_R_W =3D 0x11, - NM_ADDU_S_QB =3D 0x19, - NM_ADDU_S_PH =3D 0x21, - NM_ADDUH_R_QB =3D 0x29, - NM_SHRAV_R_PH =3D 0x31, - NM_SHRAV_R_QB =3D 0x39, - NM_SUBQ_S_PH =3D 0x41, - NM_SUBQH_R_PH =3D 0x49, - NM_SUBQH_R_W =3D 0x51, - NM_SUBU_S_QB =3D 0x59, - NM_SUBU_S_PH =3D 0x61, - NM_SUBUH_R_QB =3D 0x69, - NM_SHLLV_S_PH =3D 0x71, - NM_PRECR_SRA_R_PH_W =3D 0x79, - - NM_MULEU_S_PH_QBL =3D 0x12, - NM_MULEU_S_PH_QBR =3D 0x1a, - NM_MULQ_RS_PH =3D 0x22, - NM_MULQ_S_PH =3D 0x2a, - NM_MULQ_RS_W =3D 0x32, - NM_MULQ_S_W =3D 0x3a, - NM_APPEND =3D 0x42, - NM_MODSUB =3D 0x52, - NM_SHRAV_R_W =3D 0x5a, - NM_SHRLV_PH =3D 0x62, - NM_SHRLV_QB =3D 0x6a, - NM_SHLLV_QB =3D 0x72, - NM_SHLLV_S_W =3D 0x7a, - - NM_SHILO =3D 0x03, - - NM_MULEQ_S_W_PHL =3D 0x04, - NM_MULEQ_S_W_PHR =3D 0x0c, - - NM_MUL_S_PH =3D 0x05, - NM_PRECR_QB_PH =3D 0x0d, - NM_PRECRQ_QB_PH =3D 0x15, - NM_PRECRQ_PH_W =3D 0x1d, - NM_PRECRQ_RS_PH_W =3D 0x25, - NM_PRECRQU_S_QB_PH =3D 0x2d, - NM_PACKRL_PH =3D 0x35, - NM_PICK_QB =3D 0x3d, - NM_PICK_PH =3D 0x45, - - NM_SHRA_R_W =3D 0x5e, - NM_SHRA_R_PH =3D 0x66, - NM_SHLL_S_PH =3D 0x76, - NM_SHLL_S_W =3D 0x7e, - - NM_REPL_PH =3D 0x07 -}; - -/* POOL32A7 instruction pool */ -enum { - NM_P_LSX =3D 0x00, - NM_LSA =3D 0x01, - NM_EXTW =3D 0x03, - NM_POOL32AXF =3D 0x07, -}; - -/* P.SR instruction pool */ -enum { - NM_PP_SR =3D 0x00, - NM_P_SR_F =3D 0x01, -}; - -/* P.SHIFT instruction pool */ -enum { - NM_P_SLL =3D 0x00, - NM_SRL =3D 0x02, - NM_SRA =3D 0x04, - NM_ROTR =3D 0x06, -}; - -/* P.ROTX instruction pool */ -enum { - NM_ROTX =3D 0x00, -}; - -/* P.INS instruction pool */ -enum { - NM_INS =3D 0x00, -}; - -/* P.EXT instruction pool */ -enum { - NM_EXT =3D 0x00, -}; - -/* POOL32F_0 (fmt) instruction pool */ -enum { - NM_RINT_S =3D 0x04, - NM_RINT_D =3D 0x44, - NM_ADD_S =3D 0x06, - NM_SELEQZ_S =3D 0x07, - NM_SELEQZ_D =3D 0x47, - NM_CLASS_S =3D 0x0c, - NM_CLASS_D =3D 0x4c, - NM_SUB_S =3D 0x0e, - NM_SELNEZ_S =3D 0x0f, - NM_SELNEZ_D =3D 0x4f, - NM_MUL_S =3D 0x16, - NM_SEL_S =3D 0x17, - NM_SEL_D =3D 0x57, - NM_DIV_S =3D 0x1e, - NM_ADD_D =3D 0x26, - NM_SUB_D =3D 0x2e, - NM_MUL_D =3D 0x36, - NM_MADDF_S =3D 0x37, - NM_MADDF_D =3D 0x77, - NM_DIV_D =3D 0x3e, - NM_MSUBF_S =3D 0x3f, - NM_MSUBF_D =3D 0x7f, -}; - -/* POOL32F_3 instruction pool */ -enum { - NM_MIN_FMT =3D 0x00, - NM_MAX_FMT =3D 0x01, - NM_MINA_FMT =3D 0x04, - NM_MAXA_FMT =3D 0x05, - NM_POOL32FXF =3D 0x07, -}; - -/* POOL32F_5 instruction pool */ -enum { - NM_CMP_CONDN_S =3D 0x00, - NM_CMP_CONDN_D =3D 0x02, -}; - -/* P.GP.LH instruction pool */ -enum { - NM_LHGP =3D 0x00, - NM_LHUGP =3D 0x01, -}; - -/* P.GP.SH instruction pool */ -enum { - NM_SHGP =3D 0x00, -}; - -/* P.GP.CP1 instruction pool */ -enum { - NM_LWC1GP =3D 0x00, - NM_SWC1GP =3D 0x01, - NM_LDC1GP =3D 0x02, - NM_SDC1GP =3D 0x03, -}; - -/* P.LS.S0 instruction pool */ -enum { - NM_LBS9 =3D 0x00, - NM_LHS9 =3D 0x04, - NM_LWS9 =3D 0x08, - NM_LDS9 =3D 0x0c, - - NM_SBS9 =3D 0x01, - NM_SHS9 =3D 0x05, - NM_SWS9 =3D 0x09, - NM_SDS9 =3D 0x0d, - - NM_LBUS9 =3D 0x02, - NM_LHUS9 =3D 0x06, - NM_LWC1S9 =3D 0x0a, - NM_LDC1S9 =3D 0x0e, - - NM_P_PREFS9 =3D 0x03, - NM_LWUS9 =3D 0x07, - NM_SWC1S9 =3D 0x0b, - NM_SDC1S9 =3D 0x0f, -}; - -/* P.LS.S1 instruction pool */ -enum { - NM_ASET_ACLR =3D 0x02, - NM_UALH =3D 0x04, - NM_UASH =3D 0x05, - NM_CACHE =3D 0x07, - NM_P_LL =3D 0x0a, - NM_P_SC =3D 0x0b, -}; - -/* P.LS.E0 instruction pool */ -enum { - NM_LBE =3D 0x00, - NM_SBE =3D 0x01, - NM_LBUE =3D 0x02, - NM_P_PREFE =3D 0x03, - NM_LHE =3D 0x04, - NM_SHE =3D 0x05, - NM_LHUE =3D 0x06, - NM_CACHEE =3D 0x07, - NM_LWE =3D 0x08, - NM_SWE =3D 0x09, - NM_P_LLE =3D 0x0a, - NM_P_SCE =3D 0x0b, -}; - -/* P.PREFE instruction pool */ -enum { - NM_SYNCIE =3D 0x00, - NM_PREFE =3D 0x01, -}; - -/* P.LLE instruction pool */ -enum { - NM_LLE =3D 0x00, - NM_LLWPE =3D 0x01, -}; - -/* P.SCE instruction pool */ -enum { - NM_SCE =3D 0x00, - NM_SCWPE =3D 0x01, -}; - -/* P.LS.WM instruction pool */ -enum { - NM_LWM =3D 0x00, - NM_SWM =3D 0x01, -}; - -/* P.LS.UAWM instruction pool */ -enum { - NM_UALWM =3D 0x00, - NM_UASWM =3D 0x01, -}; - -/* P.BR3A instruction pool */ -enum { - NM_BC1EQZC =3D 0x00, - NM_BC1NEZC =3D 0x01, - NM_BC2EQZC =3D 0x02, - NM_BC2NEZC =3D 0x03, - NM_BPOSGE32C =3D 0x04, -}; - -/* P16.RI instruction pool */ -enum { - NM_P16_SYSCALL =3D 0x01, - NM_BREAK16 =3D 0x02, - NM_SDBBP16 =3D 0x03, -}; - -/* POOL16C_0 instruction pool */ -enum { - NM_POOL16C_00 =3D 0x00, -}; - -/* P16.JRC instruction pool */ -enum { - NM_JRC =3D 0x00, - NM_JALRC16 =3D 0x01, -}; - -/* P.SYSCALL instruction pool */ -enum { - NM_SYSCALL =3D 0x00, - NM_HYPCALL =3D 0x01, -}; - -/* P.TRAP instruction pool */ -enum { - NM_TEQ =3D 0x00, - NM_TNE =3D 0x01, -}; - -/* P.CMOVE instruction pool */ -enum { - NM_MOVZ =3D 0x00, - NM_MOVN =3D 0x01, -}; - -/* POOL32Axf instruction pool */ -enum { - NM_POOL32AXF_1 =3D 0x01, - NM_POOL32AXF_2 =3D 0x02, - NM_POOL32AXF_4 =3D 0x04, - NM_POOL32AXF_5 =3D 0x05, - NM_POOL32AXF_7 =3D 0x07, -}; - -/* POOL32Axf_1 instruction pool */ -enum { - NM_POOL32AXF_1_0 =3D 0x00, - NM_POOL32AXF_1_1 =3D 0x01, - NM_POOL32AXF_1_3 =3D 0x03, - NM_POOL32AXF_1_4 =3D 0x04, - NM_POOL32AXF_1_5 =3D 0x05, - NM_POOL32AXF_1_7 =3D 0x07, -}; - -/* POOL32Axf_2 instruction pool */ -enum { - NM_POOL32AXF_2_0_7 =3D 0x00, - NM_POOL32AXF_2_8_15 =3D 0x01, - NM_POOL32AXF_2_16_23 =3D 0x02, - NM_POOL32AXF_2_24_31 =3D 0x03, -}; - -/* POOL32Axf_7 instruction pool */ -enum { - NM_SHRA_R_QB =3D 0x0, - NM_SHRL_PH =3D 0x1, - NM_REPL_QB =3D 0x2, -}; - -/* POOL32Axf_1_0 instruction pool */ -enum { - NM_MFHI =3D 0x0, - NM_MFLO =3D 0x1, - NM_MTHI =3D 0x2, - NM_MTLO =3D 0x3, -}; - -/* POOL32Axf_1_1 instruction pool */ -enum { - NM_MTHLIP =3D 0x0, - NM_SHILOV =3D 0x1, -}; - -/* POOL32Axf_1_3 instruction pool */ -enum { - NM_RDDSP =3D 0x0, - NM_WRDSP =3D 0x1, - NM_EXTP =3D 0x2, - NM_EXTPDP =3D 0x3, -}; - -/* POOL32Axf_1_4 instruction pool */ -enum { - NM_SHLL_QB =3D 0x0, - NM_SHRL_QB =3D 0x1, -}; - -/* POOL32Axf_1_5 instruction pool */ -enum { - NM_MAQ_S_W_PHR =3D 0x0, - NM_MAQ_S_W_PHL =3D 0x1, - NM_MAQ_SA_W_PHR =3D 0x2, - NM_MAQ_SA_W_PHL =3D 0x3, -}; - -/* POOL32Axf_1_7 instruction pool */ -enum { - NM_EXTR_W =3D 0x0, - NM_EXTR_R_W =3D 0x1, - NM_EXTR_RS_W =3D 0x2, - NM_EXTR_S_H =3D 0x3, -}; - -/* POOL32Axf_2_0_7 instruction pool */ -enum { - NM_DPA_W_PH =3D 0x0, - NM_DPAQ_S_W_PH =3D 0x1, - NM_DPS_W_PH =3D 0x2, - NM_DPSQ_S_W_PH =3D 0x3, - NM_BALIGN =3D 0x4, - NM_MADD =3D 0x5, - NM_MULT =3D 0x6, - NM_EXTRV_W =3D 0x7, -}; - -/* POOL32Axf_2_8_15 instruction pool */ -enum { - NM_DPAX_W_PH =3D 0x0, - NM_DPAQ_SA_L_W =3D 0x1, - NM_DPSX_W_PH =3D 0x2, - NM_DPSQ_SA_L_W =3D 0x3, - NM_MADDU =3D 0x5, - NM_MULTU =3D 0x6, - NM_EXTRV_R_W =3D 0x7, -}; - -/* POOL32Axf_2_16_23 instruction pool */ -enum { - NM_DPAU_H_QBL =3D 0x0, - NM_DPAQX_S_W_PH =3D 0x1, - NM_DPSU_H_QBL =3D 0x2, - NM_DPSQX_S_W_PH =3D 0x3, - NM_EXTPV =3D 0x4, - NM_MSUB =3D 0x5, - NM_MULSA_W_PH =3D 0x6, - NM_EXTRV_RS_W =3D 0x7, -}; - -/* POOL32Axf_2_24_31 instruction pool */ -enum { - NM_DPAU_H_QBR =3D 0x0, - NM_DPAQX_SA_W_PH =3D 0x1, - NM_DPSU_H_QBR =3D 0x2, - NM_DPSQX_SA_W_PH =3D 0x3, - NM_EXTPDPV =3D 0x4, - NM_MSUBU =3D 0x5, - NM_MULSAQ_S_W_PH =3D 0x6, - NM_EXTRV_S_H =3D 0x7, -}; - -/* POOL32Axf_{4, 5} instruction pool */ -enum { - NM_CLO =3D 0x25, - NM_CLZ =3D 0x2d, - - NM_TLBP =3D 0x01, - NM_TLBR =3D 0x09, - NM_TLBWI =3D 0x11, - NM_TLBWR =3D 0x19, - NM_TLBINV =3D 0x03, - NM_TLBINVF =3D 0x0b, - NM_DI =3D 0x23, - NM_EI =3D 0x2b, - NM_RDPGPR =3D 0x70, - NM_WRPGPR =3D 0x78, - NM_WAIT =3D 0x61, - NM_DERET =3D 0x71, - NM_ERETX =3D 0x79, - - /* nanoMIPS DSP instructions */ - NM_ABSQ_S_QB =3D 0x00, - NM_ABSQ_S_PH =3D 0x08, - NM_ABSQ_S_W =3D 0x10, - NM_PRECEQ_W_PHL =3D 0x28, - NM_PRECEQ_W_PHR =3D 0x30, - NM_PRECEQU_PH_QBL =3D 0x38, - NM_PRECEQU_PH_QBR =3D 0x48, - NM_PRECEU_PH_QBL =3D 0x58, - NM_PRECEU_PH_QBR =3D 0x68, - NM_PRECEQU_PH_QBLA =3D 0x39, - NM_PRECEQU_PH_QBRA =3D 0x49, - NM_PRECEU_PH_QBLA =3D 0x59, - NM_PRECEU_PH_QBRA =3D 0x69, - NM_REPLV_PH =3D 0x01, - NM_REPLV_QB =3D 0x09, - NM_BITREV =3D 0x18, - NM_INSV =3D 0x20, - NM_RADDU_W_QB =3D 0x78, - - NM_BITSWAP =3D 0x05, - NM_WSBH =3D 0x3d, -}; - -/* PP.SR instruction pool */ -enum { - NM_SAVE =3D 0x00, - NM_RESTORE =3D 0x02, - NM_RESTORE_JRC =3D 0x03, -}; - -/* P.SR.F instruction pool */ -enum { - NM_SAVEF =3D 0x00, - NM_RESTOREF =3D 0x01, -}; - -/* P16.SYSCALL instruction pool */ -enum { - NM_SYSCALL16 =3D 0x00, - NM_HYPCALL16 =3D 0x01, -}; - -/* POOL16C_00 instruction pool */ -enum { - NM_NOT16 =3D 0x00, - NM_XOR16 =3D 0x01, - NM_AND16 =3D 0x02, - NM_OR16 =3D 0x03, -}; - -/* PP.LSX and PP.LSXS instruction pool */ -enum { - NM_LBX =3D 0x00, - NM_LHX =3D 0x04, - NM_LWX =3D 0x08, - NM_LDX =3D 0x0c, - - NM_SBX =3D 0x01, - NM_SHX =3D 0x05, - NM_SWX =3D 0x09, - NM_SDX =3D 0x0d, - - NM_LBUX =3D 0x02, - NM_LHUX =3D 0x06, - NM_LWC1X =3D 0x0a, - NM_LDC1X =3D 0x0e, - - NM_LWUX =3D 0x07, - NM_SWC1X =3D 0x0b, - NM_SDC1X =3D 0x0f, - - NM_LHXS =3D 0x04, - NM_LWXS =3D 0x08, - NM_LDXS =3D 0x0c, - - NM_SHXS =3D 0x05, - NM_SWXS =3D 0x09, - NM_SDXS =3D 0x0d, - - NM_LHUXS =3D 0x06, - NM_LWC1XS =3D 0x0a, - NM_LDC1XS =3D 0x0e, - - NM_LWUXS =3D 0x07, - NM_SWC1XS =3D 0x0b, - NM_SDC1XS =3D 0x0f, -}; - -/* ERETx instruction pool */ -enum { - NM_ERET =3D 0x00, - NM_ERETNC =3D 0x01, -}; - -/* POOL32FxF_{0, 1} insturction pool */ -enum { - NM_CFC1 =3D 0x40, - NM_CTC1 =3D 0x60, - NM_MFC1 =3D 0x80, - NM_MTC1 =3D 0xa0, - NM_MFHC1 =3D 0xc0, - NM_MTHC1 =3D 0xe0, - - NM_CVT_S_PL =3D 0x84, - NM_CVT_S_PU =3D 0xa4, - - NM_CVT_L_S =3D 0x004, - NM_CVT_L_D =3D 0x104, - NM_CVT_W_S =3D 0x024, - NM_CVT_W_D =3D 0x124, - - NM_RSQRT_S =3D 0x008, - NM_RSQRT_D =3D 0x108, - - NM_SQRT_S =3D 0x028, - NM_SQRT_D =3D 0x128, - - NM_RECIP_S =3D 0x048, - NM_RECIP_D =3D 0x148, - - NM_FLOOR_L_S =3D 0x00c, - NM_FLOOR_L_D =3D 0x10c, - - NM_FLOOR_W_S =3D 0x02c, - NM_FLOOR_W_D =3D 0x12c, - - NM_CEIL_L_S =3D 0x04c, - NM_CEIL_L_D =3D 0x14c, - NM_CEIL_W_S =3D 0x06c, - NM_CEIL_W_D =3D 0x16c, - NM_TRUNC_L_S =3D 0x08c, - NM_TRUNC_L_D =3D 0x18c, - NM_TRUNC_W_S =3D 0x0ac, - NM_TRUNC_W_D =3D 0x1ac, - NM_ROUND_L_S =3D 0x0cc, - NM_ROUND_L_D =3D 0x1cc, - NM_ROUND_W_S =3D 0x0ec, - NM_ROUND_W_D =3D 0x1ec, - - NM_MOV_S =3D 0x01, - NM_MOV_D =3D 0x81, - NM_ABS_S =3D 0x0d, - NM_ABS_D =3D 0x8d, - NM_NEG_S =3D 0x2d, - NM_NEG_D =3D 0xad, - NM_CVT_D_S =3D 0x04d, - NM_CVT_D_W =3D 0x0cd, - NM_CVT_D_L =3D 0x14d, - NM_CVT_S_D =3D 0x06d, - NM_CVT_S_W =3D 0x0ed, - NM_CVT_S_L =3D 0x16d, -}; - -/* P.LL instruction pool */ -enum { - NM_LL =3D 0x00, - NM_LLWP =3D 0x01, -}; - -/* P.SC instruction pool */ -enum { - NM_SC =3D 0x00, - NM_SCWP =3D 0x01, -}; - -/* P.DVP instruction pool */ -enum { - NM_DVP =3D 0x00, - NM_EVP =3D 0x01, -}; - - -/* - * - * nanoMIPS decoding engine - * - */ - - -/* extraction utilities */ - -#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7) -#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7) -#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7) -#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f) -#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f) - -/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */ -static inline int decode_gpr_gpr3(int r) -{ - static const int map[] =3D { 16, 17, 18, 19, 4, 5, 6, 7 }; - - return map[r & 0x7]; -} - -/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store')= . */ -static inline int decode_gpr_gpr3_src_store(int r) -{ - static const int map[] =3D { 0, 17, 18, 19, 4, 5, 6, 7 }; - - return map[r & 0x7]; -} - -/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */ -static inline int decode_gpr_gpr4(int r) -{ - static const int map[] =3D { 8, 9, 10, 11, 4, 5, 6, 7, - 16, 17, 18, 19, 20, 21, 22, 23 }; - - return map[r & 0xf]; -} - -/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */ -static inline int decode_gpr_gpr4_zero(int r) -{ - static const int map[] =3D { 8, 9, 10, 0, 4, 5, 6, 7, - 16, 17, 18, 19, 20, 21, 22, 23 }; - - return map[r & 0xf]; -} - - -static void gen_adjust_sp(DisasContext *ctx, int u) -{ - gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u); -} - -static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count, - uint8_t gp, uint16_t u) -{ - int counter =3D 0; - TCGv va =3D tcg_temp_new(); - TCGv t0 =3D tcg_temp_new(); - - while (counter !=3D count) { - bool use_gp =3D gp && (counter =3D=3D count - 1); - int this_rt =3D use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f= ); - int this_offset =3D -((counter + 1) << 2); - gen_base_offset_addr(ctx, va, 29, this_offset); - gen_load_gpr(t0, this_rt); - tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx, - (MO_TEUL | ctx->default_tcg_memop_mask)); - counter++; - } - - /* adjust stack pointer */ - gen_adjust_sp(ctx, -u); - - tcg_temp_free(t0); - tcg_temp_free(va); -} - -static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count, - uint8_t gp, uint16_t u) -{ - int counter =3D 0; - TCGv va =3D tcg_temp_new(); - TCGv t0 =3D tcg_temp_new(); - - while (counter !=3D count) { - bool use_gp =3D gp && (counter =3D=3D count - 1); - int this_rt =3D use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f= ); - int this_offset =3D u - ((counter + 1) << 2); - gen_base_offset_addr(ctx, va, 29, this_offset); - tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL | - ctx->default_tcg_memop_mask); - tcg_gen_ext32s_tl(t0, t0); - gen_store_gpr(t0, this_rt); - counter++; - } - - /* adjust stack pointer */ - gen_adjust_sp(ctx, u); - - tcg_temp_free(t0); - tcg_temp_free(va); -} - -static void gen_pool16c_nanomips_insn(DisasContext *ctx) -{ - int rt =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode)); - int rs =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); - - switch (extract32(ctx->opcode, 2, 2)) { - case NM_NOT16: - gen_logic(ctx, OPC_NOR, rt, rs, 0); - break; - case NM_AND16: - gen_logic(ctx, OPC_AND, rt, rt, rs); - break; - case NM_XOR16: - gen_logic(ctx, OPC_XOR, rt, rt, rs); - break; - case NM_OR16: - gen_logic(ctx, OPC_OR, rt, rt, rs); - break; - } -} - -static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ct= x) -{ - int rt =3D extract32(ctx->opcode, 21, 5); - int rs =3D extract32(ctx->opcode, 16, 5); - int rd =3D extract32(ctx->opcode, 11, 5); - - switch (extract32(ctx->opcode, 3, 7)) { - case NM_P_TRAP: - switch (extract32(ctx->opcode, 10, 1)) { - case NM_TEQ: - check_nms(ctx); - gen_trap(ctx, OPC_TEQ, rs, rt, -1); - break; - case NM_TNE: - check_nms(ctx); - gen_trap(ctx, OPC_TNE, rs, rt, -1); - break; - } - break; - case NM_RDHWR: - check_nms(ctx); - gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3)); - break; - case NM_SEB: - check_nms(ctx); - gen_bshfl(ctx, OPC_SEB, rs, rt); - break; - case NM_SEH: - gen_bshfl(ctx, OPC_SEH, rs, rt); - break; - case NM_SLLV: - gen_shift(ctx, OPC_SLLV, rd, rt, rs); - break; - case NM_SRLV: - gen_shift(ctx, OPC_SRLV, rd, rt, rs); - break; - case NM_SRAV: - gen_shift(ctx, OPC_SRAV, rd, rt, rs); - break; - case NM_ROTRV: - gen_shift(ctx, OPC_ROTRV, rd, rt, rs); - break; - case NM_ADD: - gen_arith(ctx, OPC_ADD, rd, rs, rt); - break; - case NM_ADDU: - gen_arith(ctx, OPC_ADDU, rd, rs, rt); - break; - case NM_SUB: - check_nms(ctx); - gen_arith(ctx, OPC_SUB, rd, rs, rt); - break; - case NM_SUBU: - gen_arith(ctx, OPC_SUBU, rd, rs, rt); - break; - case NM_P_CMOVE: - switch (extract32(ctx->opcode, 10, 1)) { - case NM_MOVZ: - gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt); - break; - case NM_MOVN: - gen_cond_move(ctx, OPC_MOVN, rd, rs, rt); - break; - } - break; - case NM_AND: - gen_logic(ctx, OPC_AND, rd, rs, rt); - break; - case NM_OR: - gen_logic(ctx, OPC_OR, rd, rs, rt); - break; - case NM_NOR: - gen_logic(ctx, OPC_NOR, rd, rs, rt); - break; - case NM_XOR: - gen_logic(ctx, OPC_XOR, rd, rs, rt); - break; - case NM_SLT: - gen_slt(ctx, OPC_SLT, rd, rs, rt); - break; - case NM_P_SLTU: - if (rd =3D=3D 0) { - /* P_DVP */ -#ifndef CONFIG_USER_ONLY - TCGv t0 =3D tcg_temp_new(); - switch (extract32(ctx->opcode, 10, 1)) { - case NM_DVP: - if (ctx->vp) { - check_cp0_enabled(ctx); - gen_helper_dvp(t0, cpu_env); - gen_store_gpr(t0, rt); - } - break; - case NM_EVP: - if (ctx->vp) { - check_cp0_enabled(ctx); - gen_helper_evp(t0, cpu_env); - gen_store_gpr(t0, rt); - } - break; - } - tcg_temp_free(t0); -#endif - } else { - gen_slt(ctx, OPC_SLTU, rd, rs, rt); - } - break; - case NM_SOV: - { - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - TCGv t2 =3D tcg_temp_new(); - - gen_load_gpr(t1, rs); - gen_load_gpr(t2, rt); - tcg_gen_add_tl(t0, t1, t2); - tcg_gen_ext32s_tl(t0, t0); - tcg_gen_xor_tl(t1, t1, t2); - tcg_gen_xor_tl(t2, t0, t2); - tcg_gen_andc_tl(t1, t2, t1); - - /* operands of same sign, result different sign */ - tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0); - gen_store_gpr(t0, rd); - - tcg_temp_free(t0); - tcg_temp_free(t1); - tcg_temp_free(t2); - } - break; - case NM_MUL: - gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt); - break; - case NM_MUH: - gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt); - break; - case NM_MULU: - gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt); - break; - case NM_MUHU: - gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt); - break; - case NM_DIV: - gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt); - break; - case NM_MOD: - gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt); - break; - case NM_DIVU: - gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt); - break; - case NM_MODU: - gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt); - break; -#ifndef CONFIG_USER_ONLY - case NM_MFC0: - check_cp0_enabled(ctx); - if (rt =3D=3D 0) { - /* Treat as NOP. */ - break; - } - gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3)); - break; - case NM_MTC0: - check_cp0_enabled(ctx); - { - TCGv t0 =3D tcg_temp_new(); - - gen_load_gpr(t0, rt); - gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3)); - tcg_temp_free(t0); - } - break; - case NM_D_E_MT_VPE: - { - uint8_t sc =3D extract32(ctx->opcode, 10, 1); - TCGv t0 =3D tcg_temp_new(); - - switch (sc) { - case 0: - if (rs =3D=3D 1) { - /* DMT */ - check_cp0_mt(ctx); - gen_helper_dmt(t0); - gen_store_gpr(t0, rt); - } else if (rs =3D=3D 0) { - /* DVPE */ - check_cp0_mt(ctx); - gen_helper_dvpe(t0, cpu_env); - gen_store_gpr(t0, rt); - } else { - generate_exception_end(ctx, EXCP_RI); - } - break; - case 1: - if (rs =3D=3D 1) { - /* EMT */ - check_cp0_mt(ctx); - gen_helper_emt(t0); - gen_store_gpr(t0, rt); - } else if (rs =3D=3D 0) { - /* EVPE */ - check_cp0_mt(ctx); - gen_helper_evpe(t0, cpu_env); - gen_store_gpr(t0, rt); - } else { - generate_exception_end(ctx, EXCP_RI); - } - break; - } - - tcg_temp_free(t0); - } - break; - case NM_FORK: - check_mt(ctx); - { - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - - gen_load_gpr(t0, rt); - gen_load_gpr(t1, rs); - gen_helper_fork(t0, t1); - tcg_temp_free(t0); - tcg_temp_free(t1); - } - break; - case NM_MFTR: - case NM_MFHTR: - check_cp0_enabled(ctx); - if (rd =3D=3D 0) { - /* Treat as NOP. */ - return; - } - gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1), - extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, = 1)); - break; - case NM_MTTR: - case NM_MTHTR: - check_cp0_enabled(ctx); - gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1), - extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, = 1)); - break; - case NM_YIELD: - check_mt(ctx); - { - TCGv t0 =3D tcg_temp_new(); - - gen_load_gpr(t0, rs); - gen_helper_yield(t0, cpu_env, t0); - gen_store_gpr(t0, rt); - tcg_temp_free(t0); - } - break; -#endif - default: - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* dsp */ -static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t op= c, - int ret, int v1, int v2) -{ - TCGv_i32 t0; - TCGv v0_t; - TCGv v1_t; - - t0 =3D tcg_temp_new_i32(); - - v0_t =3D tcg_temp_new(); - v1_t =3D tcg_temp_new(); - - tcg_gen_movi_i32(t0, v2 >> 3); - - gen_load_gpr(v0_t, ret); - gen_load_gpr(v1_t, v1); - - switch (opc) { - case NM_MAQ_S_W_PHR: - check_dsp(ctx); - gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env); - break; - case NM_MAQ_S_W_PHL: - check_dsp(ctx); - gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env); - break; - case NM_MAQ_SA_W_PHR: - check_dsp(ctx); - gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env); - break; - case NM_MAQ_SA_W_PHL: - check_dsp(ctx); - gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free_i32(t0); - - tcg_temp_free(v0_t); - tcg_temp_free(v1_t); -} - - -static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc, - int ret, int v1, int v2) -{ - int16_t imm; - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - TCGv v0_t =3D tcg_temp_new(); - - gen_load_gpr(v0_t, v1); - - switch (opc) { - case NM_POOL32AXF_1_0: - check_dsp(ctx); - switch (extract32(ctx->opcode, 12, 2)) { - case NM_MFHI: - gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret); - break; - case NM_MFLO: - gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret); - break; - case NM_MTHI: - gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1); - break; - case NM_MTLO: - gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1); - break; - } - break; - case NM_POOL32AXF_1_1: - check_dsp(ctx); - switch (extract32(ctx->opcode, 12, 2)) { - case NM_MTHLIP: - tcg_gen_movi_tl(t0, v2); - gen_helper_mthlip(t0, v0_t, cpu_env); - break; - case NM_SHILOV: - tcg_gen_movi_tl(t0, v2 >> 3); - gen_helper_shilo(t0, v0_t, cpu_env); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_POOL32AXF_1_3: - check_dsp(ctx); - imm =3D extract32(ctx->opcode, 14, 7); - switch (extract32(ctx->opcode, 12, 2)) { - case NM_RDDSP: - tcg_gen_movi_tl(t0, imm); - gen_helper_rddsp(t0, t0, cpu_env); - gen_store_gpr(t0, ret); - break; - case NM_WRDSP: - gen_load_gpr(t0, ret); - tcg_gen_movi_tl(t1, imm); - gen_helper_wrdsp(t0, t1, cpu_env); - break; - case NM_EXTP: - tcg_gen_movi_tl(t0, v2 >> 3); - tcg_gen_movi_tl(t1, v1); - gen_helper_extp(t0, t0, t1, cpu_env); - gen_store_gpr(t0, ret); - break; - case NM_EXTPDP: - tcg_gen_movi_tl(t0, v2 >> 3); - tcg_gen_movi_tl(t1, v1); - gen_helper_extpdp(t0, t0, t1, cpu_env); - gen_store_gpr(t0, ret); - break; - } - break; - case NM_POOL32AXF_1_4: - check_dsp(ctx); - tcg_gen_movi_tl(t0, v2 >> 2); - switch (extract32(ctx->opcode, 12, 1)) { - case NM_SHLL_QB: - gen_helper_shll_qb(t0, t0, v0_t, cpu_env); - gen_store_gpr(t0, ret); - break; - case NM_SHRL_QB: - gen_helper_shrl_qb(t0, t0, v0_t); - gen_store_gpr(t0, ret); - break; - } - break; - case NM_POOL32AXF_1_5: - opc =3D extract32(ctx->opcode, 12, 2); - gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2); - break; - case NM_POOL32AXF_1_7: - check_dsp(ctx); - tcg_gen_movi_tl(t0, v2 >> 3); - tcg_gen_movi_tl(t1, v1); - switch (extract32(ctx->opcode, 12, 2)) { - case NM_EXTR_W: - gen_helper_extr_w(t0, t0, t1, cpu_env); - gen_store_gpr(t0, ret); - break; - case NM_EXTR_R_W: - gen_helper_extr_r_w(t0, t0, t1, cpu_env); - gen_store_gpr(t0, ret); - break; - case NM_EXTR_RS_W: - gen_helper_extr_rs_w(t0, t0, t1, cpu_env); - gen_store_gpr(t0, ret); - break; - case NM_EXTR_S_H: - gen_helper_extr_s_h(t0, t0, t1, cpu_env); - gen_store_gpr(t0, ret); - break; - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free(t0); - tcg_temp_free(t1); - tcg_temp_free(v0_t); -} - -static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc, - TCGv v0, TCGv v1, int rd) -{ - TCGv_i32 t0; - - t0 =3D tcg_temp_new_i32(); - - tcg_gen_movi_i32(t0, rd >> 3); - - switch (opc) { - case NM_POOL32AXF_2_0_7: - switch (extract32(ctx->opcode, 9, 3)) { - case NM_DPA_W_PH: - check_dsp_r2(ctx); - gen_helper_dpa_w_ph(t0, v1, v0, cpu_env); - break; - case NM_DPAQ_S_W_PH: - check_dsp(ctx); - gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env); - break; - case NM_DPS_W_PH: - check_dsp_r2(ctx); - gen_helper_dps_w_ph(t0, v1, v0, cpu_env); - break; - case NM_DPSQ_S_W_PH: - check_dsp(ctx); - gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_POOL32AXF_2_8_15: - switch (extract32(ctx->opcode, 9, 3)) { - case NM_DPAX_W_PH: - check_dsp_r2(ctx); - gen_helper_dpax_w_ph(t0, v0, v1, cpu_env); - break; - case NM_DPAQ_SA_L_W: - check_dsp(ctx); - gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env); - break; - case NM_DPSX_W_PH: - check_dsp_r2(ctx); - gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env); - break; - case NM_DPSQ_SA_L_W: - check_dsp(ctx); - gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_POOL32AXF_2_16_23: - switch (extract32(ctx->opcode, 9, 3)) { - case NM_DPAU_H_QBL: - check_dsp(ctx); - gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env); - break; - case NM_DPAQX_S_W_PH: - check_dsp_r2(ctx); - gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env); - break; - case NM_DPSU_H_QBL: - check_dsp(ctx); - gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env); - break; - case NM_DPSQX_S_W_PH: - check_dsp_r2(ctx); - gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env); - break; - case NM_MULSA_W_PH: - check_dsp_r2(ctx); - gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_POOL32AXF_2_24_31: - switch (extract32(ctx->opcode, 9, 3)) { - case NM_DPAU_H_QBR: - check_dsp(ctx); - gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env); - break; - case NM_DPAQX_SA_W_PH: - check_dsp_r2(ctx); - gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env); - break; - case NM_DPSU_H_QBR: - check_dsp(ctx); - gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env); - break; - case NM_DPSQX_SA_W_PH: - check_dsp_r2(ctx); - gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env); - break; - case NM_MULSAQ_S_W_PH: - check_dsp(ctx); - gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free_i32(t0); -} - -static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc, - int rt, int rs, int rd) -{ - int ret =3D rt; - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - TCGv v0_t =3D tcg_temp_new(); - TCGv v1_t =3D tcg_temp_new(); - - gen_load_gpr(v0_t, rt); - gen_load_gpr(v1_t, rs); - - switch (opc) { - case NM_POOL32AXF_2_0_7: - switch (extract32(ctx->opcode, 9, 3)) { - case NM_DPA_W_PH: - case NM_DPAQ_S_W_PH: - case NM_DPS_W_PH: - case NM_DPSQ_S_W_PH: - gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); - break; - case NM_BALIGN: - check_dsp_r2(ctx); - if (rt !=3D 0) { - gen_load_gpr(t0, rs); - rd &=3D 3; - if (rd !=3D 0 && rd !=3D 2) { - tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd); - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_shri_tl(t0, t0, 8 * (4 - rd)); - tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); - } - tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); - } - break; - case NM_MADD: - check_dsp(ctx); - { - int acc =3D extract32(ctx->opcode, 14, 2); - TCGv_i64 t2 =3D tcg_temp_new_i64(); - TCGv_i64 t3 =3D tcg_temp_new_i64(); - - gen_load_gpr(t0, rt); - gen_load_gpr(t1, rs); - tcg_gen_ext_tl_i64(t2, t0); - tcg_gen_ext_tl_i64(t3, t1); - tcg_gen_mul_i64(t2, t2, t3); - tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); - tcg_gen_add_i64(t2, t2, t3); - tcg_temp_free_i64(t3); - gen_move_low32(cpu_LO[acc], t2); - gen_move_high32(cpu_HI[acc], t2); - tcg_temp_free_i64(t2); - } - break; - case NM_MULT: - check_dsp(ctx); - { - int acc =3D extract32(ctx->opcode, 14, 2); - TCGv_i32 t2 =3D tcg_temp_new_i32(); - TCGv_i32 t3 =3D tcg_temp_new_i32(); - - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - tcg_gen_trunc_tl_i32(t2, t0); - tcg_gen_trunc_tl_i32(t3, t1); - tcg_gen_muls2_i32(t2, t3, t2, t3); - tcg_gen_ext_i32_tl(cpu_LO[acc], t2); - tcg_gen_ext_i32_tl(cpu_HI[acc], t3); - tcg_temp_free_i32(t2); - tcg_temp_free_i32(t3); - } - break; - case NM_EXTRV_W: - check_dsp(ctx); - gen_load_gpr(v1_t, rs); - tcg_gen_movi_tl(t0, rd >> 3); - gen_helper_extr_w(t0, t0, v1_t, cpu_env); - gen_store_gpr(t0, ret); - break; - } - break; - case NM_POOL32AXF_2_8_15: - switch (extract32(ctx->opcode, 9, 3)) { - case NM_DPAX_W_PH: - case NM_DPAQ_SA_L_W: - case NM_DPSX_W_PH: - case NM_DPSQ_SA_L_W: - gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); - break; - case NM_MADDU: - check_dsp(ctx); - { - int acc =3D extract32(ctx->opcode, 14, 2); - TCGv_i64 t2 =3D tcg_temp_new_i64(); - TCGv_i64 t3 =3D tcg_temp_new_i64(); - - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_ext32u_tl(t1, t1); - tcg_gen_extu_tl_i64(t2, t0); - tcg_gen_extu_tl_i64(t3, t1); - tcg_gen_mul_i64(t2, t2, t3); - tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); - tcg_gen_add_i64(t2, t2, t3); - tcg_temp_free_i64(t3); - gen_move_low32(cpu_LO[acc], t2); - gen_move_high32(cpu_HI[acc], t2); - tcg_temp_free_i64(t2); - } - break; - case NM_MULTU: - check_dsp(ctx); - { - int acc =3D extract32(ctx->opcode, 14, 2); - TCGv_i32 t2 =3D tcg_temp_new_i32(); - TCGv_i32 t3 =3D tcg_temp_new_i32(); - - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - tcg_gen_trunc_tl_i32(t2, t0); - tcg_gen_trunc_tl_i32(t3, t1); - tcg_gen_mulu2_i32(t2, t3, t2, t3); - tcg_gen_ext_i32_tl(cpu_LO[acc], t2); - tcg_gen_ext_i32_tl(cpu_HI[acc], t3); - tcg_temp_free_i32(t2); - tcg_temp_free_i32(t3); - } - break; - case NM_EXTRV_R_W: - check_dsp(ctx); - tcg_gen_movi_tl(t0, rd >> 3); - gen_helper_extr_r_w(t0, t0, v1_t, cpu_env); - gen_store_gpr(t0, ret); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_POOL32AXF_2_16_23: - switch (extract32(ctx->opcode, 9, 3)) { - case NM_DPAU_H_QBL: - case NM_DPAQX_S_W_PH: - case NM_DPSU_H_QBL: - case NM_DPSQX_S_W_PH: - case NM_MULSA_W_PH: - gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); - break; - case NM_EXTPV: - check_dsp(ctx); - tcg_gen_movi_tl(t0, rd >> 3); - gen_helper_extp(t0, t0, v1_t, cpu_env); - gen_store_gpr(t0, ret); - break; - case NM_MSUB: - check_dsp(ctx); - { - int acc =3D extract32(ctx->opcode, 14, 2); - TCGv_i64 t2 =3D tcg_temp_new_i64(); - TCGv_i64 t3 =3D tcg_temp_new_i64(); - - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - tcg_gen_ext_tl_i64(t2, t0); - tcg_gen_ext_tl_i64(t3, t1); - tcg_gen_mul_i64(t2, t2, t3); - tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); - tcg_gen_sub_i64(t2, t3, t2); - tcg_temp_free_i64(t3); - gen_move_low32(cpu_LO[acc], t2); - gen_move_high32(cpu_HI[acc], t2); - tcg_temp_free_i64(t2); - } - break; - case NM_EXTRV_RS_W: - check_dsp(ctx); - tcg_gen_movi_tl(t0, rd >> 3); - gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env); - gen_store_gpr(t0, ret); - break; - } - break; - case NM_POOL32AXF_2_24_31: - switch (extract32(ctx->opcode, 9, 3)) { - case NM_DPAU_H_QBR: - case NM_DPAQX_SA_W_PH: - case NM_DPSU_H_QBR: - case NM_DPSQX_SA_W_PH: - case NM_MULSAQ_S_W_PH: - gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); - break; - case NM_EXTPDPV: - check_dsp(ctx); - tcg_gen_movi_tl(t0, rd >> 3); - gen_helper_extpdp(t0, t0, v1_t, cpu_env); - gen_store_gpr(t0, ret); - break; - case NM_MSUBU: - check_dsp(ctx); - { - int acc =3D extract32(ctx->opcode, 14, 2); - TCGv_i64 t2 =3D tcg_temp_new_i64(); - TCGv_i64 t3 =3D tcg_temp_new_i64(); - - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_ext32u_tl(t1, t1); - tcg_gen_extu_tl_i64(t2, t0); - tcg_gen_extu_tl_i64(t3, t1); - tcg_gen_mul_i64(t2, t2, t3); - tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); - tcg_gen_sub_i64(t2, t3, t2); - tcg_temp_free_i64(t3); - gen_move_low32(cpu_LO[acc], t2); - gen_move_high32(cpu_HI[acc], t2); - tcg_temp_free_i64(t2); - } - break; - case NM_EXTRV_S_H: - check_dsp(ctx); - tcg_gen_movi_tl(t0, rd >> 3); - gen_helper_extr_s_h(t0, t0, v0_t, cpu_env); - gen_store_gpr(t0, ret); - break; - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free(t0); - tcg_temp_free(t1); - - tcg_temp_free(v0_t); - tcg_temp_free(v1_t); -} - -static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc, - int rt, int rs) -{ - int ret =3D rt; - TCGv t0 =3D tcg_temp_new(); - TCGv v0_t =3D tcg_temp_new(); - - gen_load_gpr(v0_t, rs); - - switch (opc) { - case NM_ABSQ_S_QB: - check_dsp_r2(ctx); - gen_helper_absq_s_qb(v0_t, v0_t, cpu_env); - gen_store_gpr(v0_t, ret); - break; - case NM_ABSQ_S_PH: - check_dsp(ctx); - gen_helper_absq_s_ph(v0_t, v0_t, cpu_env); - gen_store_gpr(v0_t, ret); - break; - case NM_ABSQ_S_W: - check_dsp(ctx); - gen_helper_absq_s_w(v0_t, v0_t, cpu_env); - gen_store_gpr(v0_t, ret); - break; - case NM_PRECEQ_W_PHL: - check_dsp(ctx); - tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000); - tcg_gen_ext32s_tl(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_PRECEQ_W_PHR: - check_dsp(ctx); - tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF); - tcg_gen_shli_tl(v0_t, v0_t, 16); - tcg_gen_ext32s_tl(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_PRECEQU_PH_QBL: - check_dsp(ctx); - gen_helper_precequ_ph_qbl(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_PRECEQU_PH_QBR: - check_dsp(ctx); - gen_helper_precequ_ph_qbr(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_PRECEQU_PH_QBLA: - check_dsp(ctx); - gen_helper_precequ_ph_qbla(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_PRECEQU_PH_QBRA: - check_dsp(ctx); - gen_helper_precequ_ph_qbra(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_PRECEU_PH_QBL: - check_dsp(ctx); - gen_helper_preceu_ph_qbl(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_PRECEU_PH_QBR: - check_dsp(ctx); - gen_helper_preceu_ph_qbr(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_PRECEU_PH_QBLA: - check_dsp(ctx); - gen_helper_preceu_ph_qbla(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_PRECEU_PH_QBRA: - check_dsp(ctx); - gen_helper_preceu_ph_qbra(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_REPLV_PH: - check_dsp(ctx); - tcg_gen_ext16u_tl(v0_t, v0_t); - tcg_gen_shli_tl(t0, v0_t, 16); - tcg_gen_or_tl(v0_t, v0_t, t0); - tcg_gen_ext32s_tl(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_REPLV_QB: - check_dsp(ctx); - tcg_gen_ext8u_tl(v0_t, v0_t); - tcg_gen_shli_tl(t0, v0_t, 8); - tcg_gen_or_tl(v0_t, v0_t, t0); - tcg_gen_shli_tl(t0, v0_t, 16); - tcg_gen_or_tl(v0_t, v0_t, t0); - tcg_gen_ext32s_tl(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_BITREV: - check_dsp(ctx); - gen_helper_bitrev(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_INSV: - check_dsp(ctx); - { - TCGv tv0 =3D tcg_temp_new(); - - gen_load_gpr(tv0, rt); - gen_helper_insv(v0_t, cpu_env, v0_t, tv0); - gen_store_gpr(v0_t, ret); - tcg_temp_free(tv0); - } - break; - case NM_RADDU_W_QB: - check_dsp(ctx); - gen_helper_raddu_w_qb(v0_t, v0_t); - gen_store_gpr(v0_t, ret); - break; - case NM_BITSWAP: - gen_bitswap(ctx, OPC_BITSWAP, ret, rs); - break; - case NM_CLO: - check_nms(ctx); - gen_cl(ctx, OPC_CLO, ret, rs); - break; - case NM_CLZ: - check_nms(ctx); - gen_cl(ctx, OPC_CLZ, ret, rs); - break; - case NM_WSBH: - gen_bshfl(ctx, OPC_WSBH, ret, rs); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free(v0_t); - tcg_temp_free(t0); -} - -static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc, - int rt, int rs, int rd) -{ - TCGv t0 =3D tcg_temp_new(); - TCGv rs_t =3D tcg_temp_new(); - - gen_load_gpr(rs_t, rs); - - switch (opc) { - case NM_SHRA_R_QB: - check_dsp_r2(ctx); - tcg_gen_movi_tl(t0, rd >> 2); - switch (extract32(ctx->opcode, 12, 1)) { - case 0: - /* NM_SHRA_QB */ - gen_helper_shra_qb(t0, t0, rs_t); - gen_store_gpr(t0, rt); - break; - case 1: - /* NM_SHRA_R_QB */ - gen_helper_shra_r_qb(t0, t0, rs_t); - gen_store_gpr(t0, rt); - break; - } - break; - case NM_SHRL_PH: - check_dsp_r2(ctx); - tcg_gen_movi_tl(t0, rd >> 1); - gen_helper_shrl_ph(t0, t0, rs_t); - gen_store_gpr(t0, rt); - break; - case NM_REPL_QB: - check_dsp(ctx); - { - int16_t imm; - target_long result; - imm =3D extract32(ctx->opcode, 13, 8); - result =3D (uint32_t)imm << 24 | - (uint32_t)imm << 16 | - (uint32_t)imm << 8 | - (uint32_t)imm; - result =3D (int32_t)result; - tcg_gen_movi_tl(t0, result); - gen_store_gpr(t0, rt); - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - tcg_temp_free(t0); - tcg_temp_free(rs_t); -} - - -static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *c= tx) -{ - int rt =3D extract32(ctx->opcode, 21, 5); - int rs =3D extract32(ctx->opcode, 16, 5); - int rd =3D extract32(ctx->opcode, 11, 5); - - switch (extract32(ctx->opcode, 6, 3)) { - case NM_POOL32AXF_1: - { - int32_t op1 =3D extract32(ctx->opcode, 9, 3); - gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd); - } - break; - case NM_POOL32AXF_2: - { - int32_t op1 =3D extract32(ctx->opcode, 12, 2); - gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd); - } - break; - case NM_POOL32AXF_4: - { - int32_t op1 =3D extract32(ctx->opcode, 9, 7); - gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs); - } - break; - case NM_POOL32AXF_5: - switch (extract32(ctx->opcode, 9, 7)) { -#ifndef CONFIG_USER_ONLY - case NM_TLBP: - gen_cp0(env, ctx, OPC_TLBP, 0, 0); - break; - case NM_TLBR: - gen_cp0(env, ctx, OPC_TLBR, 0, 0); - break; - case NM_TLBWI: - gen_cp0(env, ctx, OPC_TLBWI, 0, 0); - break; - case NM_TLBWR: - gen_cp0(env, ctx, OPC_TLBWR, 0, 0); - break; - case NM_TLBINV: - gen_cp0(env, ctx, OPC_TLBINV, 0, 0); - break; - case NM_TLBINVF: - gen_cp0(env, ctx, OPC_TLBINVF, 0, 0); - break; - case NM_DI: - check_cp0_enabled(ctx); - { - TCGv t0 =3D tcg_temp_new(); - - save_cpu_state(ctx, 1); - gen_helper_di(t0, cpu_env); - gen_store_gpr(t0, rt); - /* Stop translation as we may have switched the execution mode= */ - ctx->base.is_jmp =3D DISAS_STOP; - tcg_temp_free(t0); - } - break; - case NM_EI: - check_cp0_enabled(ctx); - { - TCGv t0 =3D tcg_temp_new(); - - save_cpu_state(ctx, 1); - gen_helper_ei(t0, cpu_env); - gen_store_gpr(t0, rt); - /* Stop translation as we may have switched the execution mode= */ - ctx->base.is_jmp =3D DISAS_STOP; - tcg_temp_free(t0); - } - break; - case NM_RDPGPR: - gen_load_srsgpr(rs, rt); - break; - case NM_WRPGPR: - gen_store_srsgpr(rs, rt); - break; - case NM_WAIT: - gen_cp0(env, ctx, OPC_WAIT, 0, 0); - break; - case NM_DERET: - gen_cp0(env, ctx, OPC_DERET, 0, 0); - break; - case NM_ERETX: - gen_cp0(env, ctx, OPC_ERET, 0, 0); - break; -#endif - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_POOL32AXF_7: - { - int32_t op1 =3D extract32(ctx->opcode, 9, 3); - gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd); - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* Immediate Value Compact Branches */ -static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc, - int rt, int32_t imm, int32_t offset) -{ - TCGCond cond =3D TCG_COND_ALWAYS; - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - - gen_load_gpr(t0, rt); - tcg_gen_movi_tl(t1, imm); - ctx->btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); - - /* Load needed operands and calculate btarget */ - switch (opc) { - case NM_BEQIC: - if (rt =3D=3D 0 && imm =3D=3D 0) { - /* Unconditional branch */ - } else if (rt =3D=3D 0 && imm !=3D 0) { - /* Treat as NOP */ - goto out; - } else { - cond =3D TCG_COND_EQ; - } - break; - case NM_BBEQZC: - case NM_BBNEZC: - check_nms(ctx); - if (imm >=3D 32 && !(ctx->hflags & MIPS_HFLAG_64)) { - generate_exception_end(ctx, EXCP_RI); - goto out; - } else if (rt =3D=3D 0 && opc =3D=3D NM_BBEQZC) { - /* Unconditional branch */ - } else if (rt =3D=3D 0 && opc =3D=3D NM_BBNEZC) { - /* Treat as NOP */ - goto out; - } else { - tcg_gen_shri_tl(t0, t0, imm); - tcg_gen_andi_tl(t0, t0, 1); - tcg_gen_movi_tl(t1, 0); - if (opc =3D=3D NM_BBEQZC) { - cond =3D TCG_COND_EQ; - } else { - cond =3D TCG_COND_NE; - } - } - break; - case NM_BNEIC: - if (rt =3D=3D 0 && imm =3D=3D 0) { - /* Treat as NOP */ - goto out; - } else if (rt =3D=3D 0 && imm !=3D 0) { - /* Unconditional branch */ - } else { - cond =3D TCG_COND_NE; - } - break; - case NM_BGEIC: - if (rt =3D=3D 0 && imm =3D=3D 0) { - /* Unconditional branch */ - } else { - cond =3D TCG_COND_GE; - } - break; - case NM_BLTIC: - cond =3D TCG_COND_LT; - break; - case NM_BGEIUC: - if (rt =3D=3D 0 && imm =3D=3D 0) { - /* Unconditional branch */ - } else { - cond =3D TCG_COND_GEU; - } - break; - case NM_BLTIUC: - cond =3D TCG_COND_LTU; - break; - default: - MIPS_INVAL("Immediate Value Compact branch"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - - /* branch completion */ - clear_branch_hflags(ctx); - ctx->base.is_jmp =3D DISAS_NORETURN; - - if (cond =3D=3D TCG_COND_ALWAYS) { - /* Uncoditional compact branch */ - gen_goto_tb(ctx, 0, ctx->btarget); - } else { - /* Conditional compact branch */ - TCGLabel *fs =3D gen_new_label(); - - tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs); - - gen_goto_tb(ctx, 1, ctx->btarget); - gen_set_label(fs); - - gen_goto_tb(ctx, 0, ctx->base.pc_next + 4); - } - -out: - tcg_temp_free(t0); - tcg_temp_free(t1); -} - -/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */ -static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs, - int rt) -{ - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - - /* load rs */ - gen_load_gpr(t0, rs); - - /* link */ - if (rt !=3D 0) { - tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4); - } - - /* calculate btarget */ - tcg_gen_shli_tl(t0, t0, 1); - tcg_gen_movi_tl(t1, ctx->base.pc_next + 4); - gen_op_addr_add(ctx, btarget, t1, t0); - - /* branch completion */ - clear_branch_hflags(ctx); - ctx->base.is_jmp =3D DISAS_NORETURN; - - /* unconditional branch to register */ - tcg_gen_mov_tl(cpu_PC, btarget); - tcg_gen_lookup_and_goto_ptr(); - - tcg_temp_free(t0); - tcg_temp_free(t1); -} - -/* nanoMIPS Branches */ -static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc, - int rs, int rt, int32_t offset) -{ - int bcond_compute =3D 0; - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - - /* Load needed operands and calculate btarget */ - switch (opc) { - /* compact branch */ - case OPC_BGEC: - case OPC_BLTC: - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - bcond_compute =3D 1; - ctx->btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); - break; - case OPC_BGEUC: - case OPC_BLTUC: - if (rs =3D=3D 0 || rs =3D=3D rt) { - /* OPC_BLEZALC, OPC_BGEZALC */ - /* OPC_BGTZALC, OPC_BLTZALC */ - tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4); - } - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - bcond_compute =3D 1; - ctx->btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); - break; - case OPC_BC: - ctx->btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); - break; - case OPC_BEQZC: - if (rs !=3D 0) { - /* OPC_BEQZC, OPC_BNEZC */ - gen_load_gpr(t0, rs); - bcond_compute =3D 1; - ctx->btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); - } else { - /* OPC_JIC, OPC_JIALC */ - TCGv tbase =3D tcg_temp_new(); - TCGv toffset =3D tcg_temp_new(); - - gen_load_gpr(tbase, rt); - tcg_gen_movi_tl(toffset, offset); - gen_op_addr_add(ctx, btarget, tbase, toffset); - tcg_temp_free(tbase); - tcg_temp_free(toffset); - } - break; - default: - MIPS_INVAL("Compact branch/jump"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - - if (bcond_compute =3D=3D 0) { - /* Uncoditional compact branch */ - switch (opc) { - case OPC_BC: - gen_goto_tb(ctx, 0, ctx->btarget); - break; - default: - MIPS_INVAL("Compact branch/jump"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - } else { - /* Conditional compact branch */ - TCGLabel *fs =3D gen_new_label(); - - switch (opc) { - case OPC_BGEUC: - if (rs =3D=3D 0 && rt !=3D 0) { - /* OPC_BLEZALC */ - tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs= ); - } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { - /* OPC_BGEZALC */ - tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs= ); - } else { - /* OPC_BGEUC */ - tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, f= s); - } - break; - case OPC_BLTUC: - if (rs =3D=3D 0 && rt !=3D 0) { - /* OPC_BGTZALC */ - tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs= ); - } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { - /* OPC_BLTZALC */ - tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs= ); - } else { - /* OPC_BLTUC */ - tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, f= s); - } - break; - case OPC_BGEC: - if (rs =3D=3D 0 && rt !=3D 0) { - /* OPC_BLEZC */ - tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs= ); - } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { - /* OPC_BGEZC */ - tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs= ); - } else { - /* OPC_BGEC */ - tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs= ); - } - break; - case OPC_BLTC: - if (rs =3D=3D 0 && rt !=3D 0) { - /* OPC_BGTZC */ - tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs= ); - } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { - /* OPC_BLTZC */ - tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs= ); - } else { - /* OPC_BLTC */ - tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs= ); - } - break; - case OPC_BEQZC: - tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); - break; - default: - MIPS_INVAL("Compact conditional branch/jump"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - - /* branch completion */ - clear_branch_hflags(ctx); - ctx->base.is_jmp =3D DISAS_NORETURN; - - /* Generating branch here as compact branches don't have delay slo= t */ - gen_goto_tb(ctx, 1, ctx->btarget); - gen_set_label(fs); - - gen_goto_tb(ctx, 0, ctx->base.pc_next + 4); - } - -out: - tcg_temp_free(t0); - tcg_temp_free(t1); -} - - -/* nanoMIPS CP1 Branches */ -static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op, - int32_t ft, int32_t offset) -{ - target_ulong btarget; - TCGv_i64 t0 =3D tcg_temp_new_i64(); - - gen_load_fpr64(ctx, t0, ft); - tcg_gen_andi_i64(t0, t0, 1); - - btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); - - switch (op) { - case NM_BC1EQZC: - tcg_gen_xori_i64(t0, t0, 1); - ctx->hflags |=3D MIPS_HFLAG_BC; - break; - case NM_BC1NEZC: - /* t0 already set */ - ctx->hflags |=3D MIPS_HFLAG_BC; - break; - default: - MIPS_INVAL("cp1 cond branch"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - - tcg_gen_trunc_i64_tl(bcond, t0); - - ctx->btarget =3D btarget; - -out: - tcg_temp_free_i64(t0); -} - - -static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt) -{ - TCGv t0, t1; - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - - if ((extract32(ctx->opcode, 6, 1)) =3D=3D 1) { - /* PP.LSXS instructions require shifting */ - switch (extract32(ctx->opcode, 7, 4)) { - case NM_SHXS: - check_nms(ctx); - /* fall through */ - case NM_LHXS: - case NM_LHUXS: - tcg_gen_shli_tl(t0, t0, 1); - break; - case NM_SWXS: - check_nms(ctx); - /* fall through */ - case NM_LWXS: - case NM_LWC1XS: - case NM_SWC1XS: - tcg_gen_shli_tl(t0, t0, 2); - break; - case NM_LDC1XS: - case NM_SDC1XS: - tcg_gen_shli_tl(t0, t0, 3); - break; - } - } - gen_op_addr_add(ctx, t0, t0, t1); - - switch (extract32(ctx->opcode, 7, 4)) { - case NM_LBX: - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, - MO_SB); - gen_store_gpr(t0, rd); - break; - case NM_LHX: - /*case NM_LHXS:*/ - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, - MO_TESW); - gen_store_gpr(t0, rd); - break; - case NM_LWX: - /*case NM_LWXS:*/ - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, - MO_TESL); - gen_store_gpr(t0, rd); - break; - case NM_LBUX: - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, - MO_UB); - gen_store_gpr(t0, rd); - break; - case NM_LHUX: - /*case NM_LHUXS:*/ - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, - MO_TEUW); - gen_store_gpr(t0, rd); - break; - case NM_SBX: - check_nms(ctx); - gen_load_gpr(t1, rd); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, - MO_8); - break; - case NM_SHX: - /*case NM_SHXS:*/ - check_nms(ctx); - gen_load_gpr(t1, rd); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, - MO_TEUW); - break; - case NM_SWX: - /*case NM_SWXS:*/ - check_nms(ctx); - gen_load_gpr(t1, rd); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, - MO_TEUL); - break; - case NM_LWC1X: - /*case NM_LWC1XS:*/ - case NM_LDC1X: - /*case NM_LDC1XS:*/ - case NM_SWC1X: - /*case NM_SWC1XS:*/ - case NM_SDC1X: - /*case NM_SDC1XS:*/ - if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { - check_cp1_enabled(ctx); - switch (extract32(ctx->opcode, 7, 4)) { - case NM_LWC1X: - /*case NM_LWC1XS:*/ - gen_flt_ldst(ctx, OPC_LWC1, rd, t0); - break; - case NM_LDC1X: - /*case NM_LDC1XS:*/ - gen_flt_ldst(ctx, OPC_LDC1, rd, t0); - break; - case NM_SWC1X: - /*case NM_SWC1XS:*/ - gen_flt_ldst(ctx, OPC_SWC1, rd, t0); - break; - case NM_SDC1X: - /*case NM_SDC1XS:*/ - gen_flt_ldst(ctx, OPC_SDC1, rd, t0); - break; - } - } else { - generate_exception_err(ctx, EXCP_CpU, 1); - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - - tcg_temp_free(t0); - tcg_temp_free(t1); -} - -static void gen_pool32f_nanomips_insn(DisasContext *ctx) -{ - int rt, rs, rd; - - rt =3D extract32(ctx->opcode, 21, 5); - rs =3D extract32(ctx->opcode, 16, 5); - rd =3D extract32(ctx->opcode, 11, 5); - - if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) { - generate_exception_end(ctx, EXCP_RI); - return; - } - check_cp1_enabled(ctx); - switch (extract32(ctx->opcode, 0, 3)) { - case NM_POOL32F_0: - switch (extract32(ctx->opcode, 3, 7)) { - case NM_RINT_S: - gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0); - break; - case NM_RINT_D: - gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0); - break; - case NM_CLASS_S: - gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0); - break; - case NM_CLASS_D: - gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0); - break; - case NM_ADD_S: - gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0); - break; - case NM_ADD_D: - gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0); - break; - case NM_SUB_S: - gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0); - break; - case NM_SUB_D: - gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0); - break; - case NM_MUL_S: - gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0); - break; - case NM_MUL_D: - gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0); - break; - case NM_DIV_S: - gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0); - break; - case NM_DIV_D: - gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0); - break; - case NM_SELEQZ_S: - gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs); - break; - case NM_SELEQZ_D: - gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs); - break; - case NM_SELNEZ_S: - gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs); - break; - case NM_SELNEZ_D: - gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs); - break; - case NM_SEL_S: - gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); - break; - case NM_SEL_D: - gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs); - break; - case NM_MADDF_S: - gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0); - break; - case NM_MADDF_D: - gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0); - break; - case NM_MSUBF_S: - gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0); - break; - case NM_MSUBF_D: - gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_POOL32F_3: - switch (extract32(ctx->opcode, 3, 3)) { - case NM_MIN_FMT: - switch (extract32(ctx->opcode, 9, 1)) { - case FMT_SDPS_S: - gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); - break; - case FMT_SDPS_D: - gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0); - break; - } - break; - case NM_MAX_FMT: - switch (extract32(ctx->opcode, 9, 1)) { - case FMT_SDPS_S: - gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); - break; - case FMT_SDPS_D: - gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0); - break; - } - break; - case NM_MINA_FMT: - switch (extract32(ctx->opcode, 9, 1)) { - case FMT_SDPS_S: - gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); - break; - case FMT_SDPS_D: - gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0); - break; - } - break; - case NM_MAXA_FMT: - switch (extract32(ctx->opcode, 9, 1)) { - case FMT_SDPS_S: - gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); - break; - case FMT_SDPS_D: - gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0); - break; - } - break; - case NM_POOL32FXF: - switch (extract32(ctx->opcode, 6, 8)) { - case NM_CFC1: - gen_cp1(ctx, OPC_CFC1, rt, rs); - break; - case NM_CTC1: - gen_cp1(ctx, OPC_CTC1, rt, rs); - break; - case NM_MFC1: - gen_cp1(ctx, OPC_MFC1, rt, rs); - break; - case NM_MTC1: - gen_cp1(ctx, OPC_MTC1, rt, rs); - break; - case NM_MFHC1: - gen_cp1(ctx, OPC_MFHC1, rt, rs); - break; - case NM_MTHC1: - gen_cp1(ctx, OPC_MTHC1, rt, rs); - break; - case NM_CVT_S_PL: - gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0); - break; - case NM_CVT_S_PU: - gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0); - break; - default: - switch (extract32(ctx->opcode, 6, 9)) { - case NM_CVT_L_S: - gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0); - break; - case NM_CVT_L_D: - gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0); - break; - case NM_CVT_W_S: - gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0); - break; - case NM_CVT_W_D: - gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0); - break; - case NM_RSQRT_S: - gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0); - break; - case NM_RSQRT_D: - gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0); - break; - case NM_SQRT_S: - gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0); - break; - case NM_SQRT_D: - gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0); - break; - case NM_RECIP_S: - gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0); - break; - case NM_RECIP_D: - gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0); - break; - case NM_FLOOR_L_S: - gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0); - break; - case NM_FLOOR_L_D: - gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0); - break; - case NM_FLOOR_W_S: - gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0); - break; - case NM_FLOOR_W_D: - gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0); - break; - case NM_CEIL_L_S: - gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0); - break; - case NM_CEIL_L_D: - gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0); - break; - case NM_CEIL_W_S: - gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0); - break; - case NM_CEIL_W_D: - gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0); - break; - case NM_TRUNC_L_S: - gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0); - break; - case NM_TRUNC_L_D: - gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0); - break; - case NM_TRUNC_W_S: - gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0); - break; - case NM_TRUNC_W_D: - gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0); - break; - case NM_ROUND_L_S: - gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0); - break; - case NM_ROUND_L_D: - gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0); - break; - case NM_ROUND_W_S: - gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0); - break; - case NM_ROUND_W_D: - gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0); - break; - case NM_MOV_S: - gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0); - break; - case NM_MOV_D: - gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0); - break; - case NM_ABS_S: - gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0); - break; - case NM_ABS_D: - gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0); - break; - case NM_NEG_S: - gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0); - break; - case NM_NEG_D: - gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0); - break; - case NM_CVT_D_S: - gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0); - break; - case NM_CVT_D_W: - gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0); - break; - case NM_CVT_D_L: - gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0); - break; - case NM_CVT_S_D: - gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0); - break; - case NM_CVT_S_W: - gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0); - break; - case NM_CVT_S_L: - gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - } - break; - } - break; - case NM_POOL32F_5: - switch (extract32(ctx->opcode, 3, 3)) { - case NM_CMP_CONDN_S: - gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); - break; - case NM_CMP_CONDN_D: - gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc, - int rd, int rs, int rt) -{ - int ret =3D rd; - TCGv t0 =3D tcg_temp_new(); - TCGv v1_t =3D tcg_temp_new(); - TCGv v2_t =3D tcg_temp_new(); - - gen_load_gpr(v1_t, rs); - gen_load_gpr(v2_t, rt); - - switch (opc) { - case NM_CMP_EQ_PH: - check_dsp(ctx); - gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); - break; - case NM_CMP_LT_PH: - check_dsp(ctx); - gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); - break; - case NM_CMP_LE_PH: - check_dsp(ctx); - gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); - break; - case NM_CMPU_EQ_QB: - check_dsp(ctx); - gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); - break; - case NM_CMPU_LT_QB: - check_dsp(ctx); - gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); - break; - case NM_CMPU_LE_QB: - check_dsp(ctx); - gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); - break; - case NM_CMPGU_EQ_QB: - check_dsp(ctx); - gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_CMPGU_LT_QB: - check_dsp(ctx); - gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_CMPGU_LE_QB: - check_dsp(ctx); - gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_CMPGDU_EQ_QB: - check_dsp_r2(ctx); - gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); - tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); - gen_store_gpr(v1_t, ret); - break; - case NM_CMPGDU_LT_QB: - check_dsp_r2(ctx); - gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); - tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); - gen_store_gpr(v1_t, ret); - break; - case NM_CMPGDU_LE_QB: - check_dsp_r2(ctx); - gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); - tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); - gen_store_gpr(v1_t, ret); - break; - case NM_PACKRL_PH: - check_dsp(ctx); - gen_helper_packrl_ph(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_PICK_QB: - check_dsp(ctx); - gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_PICK_PH: - check_dsp(ctx); - gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_ADDQ_S_W: - check_dsp(ctx); - gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_SUBQ_S_W: - check_dsp(ctx); - gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_ADDSC: - check_dsp(ctx); - gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_ADDWC: - check_dsp(ctx); - gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_ADDQ_S_PH: - check_dsp(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* ADDQ_PH */ - gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* ADDQ_S_PH */ - gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_ADDQH_R_PH: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* ADDQH_PH */ - gen_helper_addqh_ph(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* ADDQH_R_PH */ - gen_helper_addqh_r_ph(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_ADDQH_R_W: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* ADDQH_W */ - gen_helper_addqh_w(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* ADDQH_R_W */ - gen_helper_addqh_r_w(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_ADDU_S_QB: - check_dsp(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* ADDU_QB */ - gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* ADDU_S_QB */ - gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_ADDU_S_PH: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* ADDU_PH */ - gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* ADDU_S_PH */ - gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_ADDUH_R_QB: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* ADDUH_QB */ - gen_helper_adduh_qb(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* ADDUH_R_QB */ - gen_helper_adduh_r_qb(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_SHRAV_R_PH: - check_dsp(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* SHRAV_PH */ - gen_helper_shra_ph(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* SHRAV_R_PH */ - gen_helper_shra_r_ph(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_SHRAV_R_QB: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* SHRAV_QB */ - gen_helper_shra_qb(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* SHRAV_R_QB */ - gen_helper_shra_r_qb(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_SUBQ_S_PH: - check_dsp(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* SUBQ_PH */ - gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* SUBQ_S_PH */ - gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_SUBQH_R_PH: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* SUBQH_PH */ - gen_helper_subqh_ph(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* SUBQH_R_PH */ - gen_helper_subqh_r_ph(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_SUBQH_R_W: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* SUBQH_W */ - gen_helper_subqh_w(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* SUBQH_R_W */ - gen_helper_subqh_r_w(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_SUBU_S_QB: - check_dsp(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* SUBU_QB */ - gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* SUBU_S_QB */ - gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_SUBU_S_PH: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* SUBU_PH */ - gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* SUBU_S_PH */ - gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_SUBUH_R_QB: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* SUBUH_QB */ - gen_helper_subuh_qb(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* SUBUH_R_QB */ - gen_helper_subuh_r_qb(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_SHLLV_S_PH: - check_dsp(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* SHLLV_PH */ - gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* SHLLV_S_PH */ - gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_PRECR_SRA_R_PH_W: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* PRECR_SRA_PH_W */ - { - TCGv_i32 sa_t =3D tcg_const_i32(rd); - gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t, - cpu_gpr[rt]); - gen_store_gpr(v1_t, rt); - tcg_temp_free_i32(sa_t); - } - break; - case 1: - /* PRECR_SRA_R_PH_W */ - { - TCGv_i32 sa_t =3D tcg_const_i32(rd); - gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t, - cpu_gpr[rt]); - gen_store_gpr(v1_t, rt); - tcg_temp_free_i32(sa_t); - } - break; - } - break; - case NM_MULEU_S_PH_QBL: - check_dsp(ctx); - gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_MULEU_S_PH_QBR: - check_dsp(ctx); - gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_MULQ_RS_PH: - check_dsp(ctx); - gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_MULQ_S_PH: - check_dsp_r2(ctx); - gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_MULQ_RS_W: - check_dsp_r2(ctx); - gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_MULQ_S_W: - check_dsp_r2(ctx); - gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_APPEND: - check_dsp_r2(ctx); - gen_load_gpr(t0, rs); - if (rd !=3D 0) { - tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd); - } - tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); - break; - case NM_MODSUB: - check_dsp(ctx); - gen_helper_modsub(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_SHRAV_R_W: - check_dsp(ctx); - gen_helper_shra_r_w(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_SHRLV_PH: - check_dsp_r2(ctx); - gen_helper_shrl_ph(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_SHRLV_QB: - check_dsp(ctx); - gen_helper_shrl_qb(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_SHLLV_QB: - check_dsp(ctx); - gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_SHLLV_S_W: - check_dsp(ctx); - gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_SHILO: - check_dsp(ctx); - { - TCGv tv0 =3D tcg_temp_new(); - TCGv tv1 =3D tcg_temp_new(); - int16_t imm =3D extract32(ctx->opcode, 16, 7); - - tcg_gen_movi_tl(tv0, rd >> 3); - tcg_gen_movi_tl(tv1, imm); - gen_helper_shilo(tv0, tv1, cpu_env); - } - break; - case NM_MULEQ_S_W_PHL: - check_dsp(ctx); - gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_MULEQ_S_W_PHR: - check_dsp(ctx); - gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_MUL_S_PH: - check_dsp_r2(ctx); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* MUL_PH */ - gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case 1: - /* MUL_S_PH */ - gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - } - break; - case NM_PRECR_QB_PH: - check_dsp_r2(ctx); - gen_helper_precr_qb_ph(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_PRECRQ_QB_PH: - check_dsp(ctx); - gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_PRECRQ_PH_W: - check_dsp(ctx); - gen_helper_precrq_ph_w(v1_t, v1_t, v2_t); - gen_store_gpr(v1_t, ret); - break; - case NM_PRECRQ_RS_PH_W: - check_dsp(ctx); - gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_PRECRQU_S_QB_PH: - check_dsp(ctx); - gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env); - gen_store_gpr(v1_t, ret); - break; - case NM_SHRA_R_W: - check_dsp(ctx); - tcg_gen_movi_tl(t0, rd); - gen_helper_shra_r_w(v1_t, t0, v1_t); - gen_store_gpr(v1_t, rt); - break; - case NM_SHRA_R_PH: - check_dsp(ctx); - tcg_gen_movi_tl(t0, rd >> 1); - switch (extract32(ctx->opcode, 10, 1)) { - case 0: - /* SHRA_PH */ - gen_helper_shra_ph(v1_t, t0, v1_t); - gen_store_gpr(v1_t, rt); - break; - case 1: - /* SHRA_R_PH */ - gen_helper_shra_r_ph(v1_t, t0, v1_t); - gen_store_gpr(v1_t, rt); - break; - } - break; - case NM_SHLL_S_PH: - check_dsp(ctx); - tcg_gen_movi_tl(t0, rd >> 1); - switch (extract32(ctx->opcode, 10, 2)) { - case 0: - /* SHLL_PH */ - gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env); - gen_store_gpr(v1_t, rt); - break; - case 2: - /* SHLL_S_PH */ - gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env); - gen_store_gpr(v1_t, rt); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_SHLL_S_W: - check_dsp(ctx); - tcg_gen_movi_tl(t0, rd); - gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env); - gen_store_gpr(v1_t, rt); - break; - case NM_REPL_PH: - check_dsp(ctx); - { - int16_t imm; - imm =3D sextract32(ctx->opcode, 11, 11); - imm =3D (int16_t)(imm << 6) >> 6; - if (rt !=3D 0) { - tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm)); - } - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) -{ - uint16_t insn; - uint32_t op; - int rt, rs, rd; - int offset; - int imm; - - insn =3D cpu_lduw_code(env, ctx->base.pc_next + 2); - ctx->opcode =3D (ctx->opcode << 16) | insn; - - rt =3D extract32(ctx->opcode, 21, 5); - rs =3D extract32(ctx->opcode, 16, 5); - rd =3D extract32(ctx->opcode, 11, 5); - - op =3D extract32(ctx->opcode, 26, 6); - switch (op) { - case NM_P_ADDIU: - if (rt =3D=3D 0) { - /* P.RI */ - switch (extract32(ctx->opcode, 19, 2)) { - case NM_SIGRIE: - default: - generate_exception_end(ctx, EXCP_RI); - break; - case NM_P_SYSCALL: - if ((extract32(ctx->opcode, 18, 1)) =3D=3D NM_SYSCALL) { - generate_exception_end(ctx, EXCP_SYSCALL); - } else { - generate_exception_end(ctx, EXCP_RI); - } - break; - case NM_BREAK: - generate_exception_end(ctx, EXCP_BREAK); - break; - case NM_SDBBP: - if (is_uhi(extract32(ctx->opcode, 0, 19))) { - gen_helper_do_semihosting(cpu_env); - } else { - if (ctx->hflags & MIPS_HFLAG_SBRI) { - generate_exception_end(ctx, EXCP_RI); - } else { - generate_exception_end(ctx, EXCP_DBp); - } - } - break; - } - } else { - /* NM_ADDIU */ - imm =3D extract32(ctx->opcode, 0, 16); - if (rs !=3D 0) { - tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm); - } else { - tcg_gen_movi_tl(cpu_gpr[rt], imm); - } - tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); - } - break; - case NM_ADDIUPC: - if (rt !=3D 0) { - offset =3D sextract32(ctx->opcode, 0, 1) << 21 | - extract32(ctx->opcode, 1, 20) << 1; - target_long addr =3D addr_add(ctx, ctx->base.pc_next + 4, offs= et); - tcg_gen_movi_tl(cpu_gpr[rt], addr); - } - break; - case NM_POOL32A: - switch (ctx->opcode & 0x07) { - case NM_POOL32A0: - gen_pool32a0_nanomips_insn(env, ctx); - break; - case NM_POOL32A5: - { - int32_t op1 =3D extract32(ctx->opcode, 3, 7); - gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt); - } - break; - case NM_POOL32A7: - switch (extract32(ctx->opcode, 3, 3)) { - case NM_P_LSX: - gen_p_lsx(ctx, rd, rs, rt); - break; - case NM_LSA: - /* - * In nanoMIPS, the shift field directly encodes the shift - * amount, meaning that the supported shift values are in - * the range 0 to 3 (instead of 1 to 4 in MIPSR6). - */ - gen_lsa(ctx, OPC_LSA, rd, rs, rt, - extract32(ctx->opcode, 9, 2) - 1); - break; - case NM_EXTW: - gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5)); - break; - case NM_POOL32AXF: - gen_pool32axf_nanomips_insn(env, ctx); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_P_GP_W: - switch (ctx->opcode & 0x03) { - case NM_ADDIUGP_W: - if (rt !=3D 0) { - offset =3D extract32(ctx->opcode, 0, 21); - gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset); - } - break; - case NM_LWGP: - gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2= ); - break; - case NM_SWGP: - gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2= ); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_P48I: - { - insn =3D cpu_lduw_code(env, ctx->base.pc_next + 4); - target_long addr_off =3D extract32(ctx->opcode, 0, 16) | insn = << 16; - switch (extract32(ctx->opcode, 16, 5)) { - case NM_LI48: - check_nms(ctx); - if (rt !=3D 0) { - tcg_gen_movi_tl(cpu_gpr[rt], addr_off); - } - break; - case NM_ADDIU48: - check_nms(ctx); - if (rt !=3D 0) { - tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off); - tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); - } - break; - case NM_ADDIUGP48: - check_nms(ctx); - if (rt !=3D 0) { - gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_o= ff); - } - break; - case NM_ADDIUPC48: - check_nms(ctx); - if (rt !=3D 0) { - target_long addr =3D addr_add(ctx, ctx->base.pc_next += 6, - addr_off); - - tcg_gen_movi_tl(cpu_gpr[rt], addr); - } - break; - case NM_LWPC48: - check_nms(ctx); - if (rt !=3D 0) { - TCGv t0; - t0 =3D tcg_temp_new(); - - target_long addr =3D addr_add(ctx, ctx->base.pc_next += 6, - addr_off); - - tcg_gen_movi_tl(t0, addr); - tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_T= ESL); - tcg_temp_free(t0); - } - break; - case NM_SWPC48: - check_nms(ctx); - { - TCGv t0, t1; - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - - target_long addr =3D addr_add(ctx, ctx->base.pc_next += 6, - addr_off); - - tcg_gen_movi_tl(t0, addr); - gen_load_gpr(t1, rt); - - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); - - tcg_temp_free(t0); - tcg_temp_free(t1); - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - return 6; - } - case NM_P_U12: - switch (extract32(ctx->opcode, 12, 4)) { - case NM_ORI: - gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, = 12)); - break; - case NM_XORI: - gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0,= 12)); - break; - case NM_ANDI: - gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0,= 12)); - break; - case NM_P_SR: - switch (extract32(ctx->opcode, 20, 1)) { - case NM_PP_SR: - switch (ctx->opcode & 3) { - case NM_SAVE: - gen_save(ctx, rt, extract32(ctx->opcode, 16, 4), - extract32(ctx->opcode, 2, 1), - extract32(ctx->opcode, 3, 9) << 3); - break; - case NM_RESTORE: - case NM_RESTORE_JRC: - gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4), - extract32(ctx->opcode, 2, 1), - extract32(ctx->opcode, 3, 9) << 3); - if ((ctx->opcode & 3) =3D=3D NM_RESTORE_JRC) { - gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0); - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_P_SR_F: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_SLTI: - gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 1= 2)); - break; - case NM_SLTIU: - gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, = 12)); - break; - case NM_SEQI: - { - TCGv t0 =3D tcg_temp_new(); - - imm =3D extract32(ctx->opcode, 0, 12); - gen_load_gpr(t0, rs); - tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm); - gen_store_gpr(t0, rt); - - tcg_temp_free(t0); - } - break; - case NM_ADDIUNEG: - imm =3D (int16_t) extract32(ctx->opcode, 0, 12); - gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm); - break; - case NM_P_SHIFT: - { - int shift =3D extract32(ctx->opcode, 0, 5); - switch (extract32(ctx->opcode, 5, 4)) { - case NM_P_SLL: - if (rt =3D=3D 0 && shift =3D=3D 0) { - /* NOP */ - } else if (rt =3D=3D 0 && shift =3D=3D 3) { - /* EHB - treat as NOP */ - } else if (rt =3D=3D 0 && shift =3D=3D 5) { - /* PAUSE - treat as NOP */ - } else if (rt =3D=3D 0 && shift =3D=3D 6) { - /* SYNC */ - gen_sync(extract32(ctx->opcode, 16, 5)); - } else { - /* SLL */ - gen_shift_imm(ctx, OPC_SLL, rt, rs, - extract32(ctx->opcode, 0, 5)); - } - break; - case NM_SRL: - gen_shift_imm(ctx, OPC_SRL, rt, rs, - extract32(ctx->opcode, 0, 5)); - break; - case NM_SRA: - gen_shift_imm(ctx, OPC_SRA, rt, rs, - extract32(ctx->opcode, 0, 5)); - break; - case NM_ROTR: - gen_shift_imm(ctx, OPC_ROTR, rt, rs, - extract32(ctx->opcode, 0, 5)); - break; - } - } - break; - case NM_P_ROTX: - check_nms(ctx); - if (rt !=3D 0) { - TCGv t0 =3D tcg_temp_new(); - TCGv_i32 shift =3D tcg_const_i32(extract32(ctx->opcode, 0,= 5)); - TCGv_i32 shiftx =3D tcg_const_i32(extract32(ctx->opcode, 7= , 4) - << 1); - TCGv_i32 stripe =3D tcg_const_i32(extract32(ctx->opcode, 6= , 1)); - - gen_load_gpr(t0, rs); - gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe); - tcg_temp_free(t0); - - tcg_temp_free_i32(shift); - tcg_temp_free_i32(shiftx); - tcg_temp_free_i32(stripe); - } - break; - case NM_P_INS: - switch (((ctx->opcode >> 10) & 2) | - (extract32(ctx->opcode, 5, 1))) { - case NM_INS: - check_nms(ctx); - gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0,= 5), - extract32(ctx->opcode, 6, 5)); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_P_EXT: - switch (((ctx->opcode >> 10) & 2) | - (extract32(ctx->opcode, 5, 1))) { - case NM_EXT: - check_nms(ctx); - gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0,= 5), - extract32(ctx->opcode, 6, 5)); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_POOL32F: - gen_pool32f_nanomips_insn(ctx); - break; - case NM_POOL32S: - break; - case NM_P_LUI: - switch (extract32(ctx->opcode, 1, 1)) { - case NM_LUI: - if (rt !=3D 0) { - tcg_gen_movi_tl(cpu_gpr[rt], - sextract32(ctx->opcode, 0, 1) << 31 | - extract32(ctx->opcode, 2, 10) << 21 | - extract32(ctx->opcode, 12, 9) << 12); - } - break; - case NM_ALUIPC: - if (rt !=3D 0) { - offset =3D sextract32(ctx->opcode, 0, 1) << 31 | - extract32(ctx->opcode, 2, 10) << 21 | - extract32(ctx->opcode, 12, 9) << 12; - target_long addr; - addr =3D ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, off= set); - tcg_gen_movi_tl(cpu_gpr[rt], addr); - } - break; - } - break; - case NM_P_GP_BH: - { - uint32_t u =3D extract32(ctx->opcode, 0, 18); - - switch (extract32(ctx->opcode, 18, 3)) { - case NM_LBGP: - gen_ld(ctx, OPC_LB, rt, 28, u); - break; - case NM_SBGP: - gen_st(ctx, OPC_SB, rt, 28, u); - break; - case NM_LBUGP: - gen_ld(ctx, OPC_LBU, rt, 28, u); - break; - case NM_ADDIUGP_B: - if (rt !=3D 0) { - gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u); - } - break; - case NM_P_GP_LH: - u &=3D ~1; - switch (ctx->opcode & 1) { - case NM_LHGP: - gen_ld(ctx, OPC_LH, rt, 28, u); - break; - case NM_LHUGP: - gen_ld(ctx, OPC_LHU, rt, 28, u); - break; - } - break; - case NM_P_GP_SH: - u &=3D ~1; - switch (ctx->opcode & 1) { - case NM_SHGP: - gen_st(ctx, OPC_SH, rt, 28, u); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_P_GP_CP1: - u &=3D ~0x3; - switch (ctx->opcode & 0x3) { - case NM_LWC1GP: - gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u); - break; - case NM_LDC1GP: - gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u); - break; - case NM_SWC1GP: - gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u); - break; - case NM_SDC1GP: - gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u); - break; - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - } - break; - case NM_P_LS_U12: - { - uint32_t u =3D extract32(ctx->opcode, 0, 12); - - switch (extract32(ctx->opcode, 12, 4)) { - case NM_P_PREFU12: - if (rt =3D=3D 31) { - /* SYNCI */ - /* - * Break the TB to be able to sync copied instructions - * immediately. - */ - ctx->base.is_jmp =3D DISAS_STOP; - } else { - /* PREF */ - /* Treat as NOP. */ - } - break; - case NM_LB: - gen_ld(ctx, OPC_LB, rt, rs, u); - break; - case NM_LH: - gen_ld(ctx, OPC_LH, rt, rs, u); - break; - case NM_LW: - gen_ld(ctx, OPC_LW, rt, rs, u); - break; - case NM_LBU: - gen_ld(ctx, OPC_LBU, rt, rs, u); - break; - case NM_LHU: - gen_ld(ctx, OPC_LHU, rt, rs, u); - break; - case NM_SB: - gen_st(ctx, OPC_SB, rt, rs, u); - break; - case NM_SH: - gen_st(ctx, OPC_SH, rt, rs, u); - break; - case NM_SW: - gen_st(ctx, OPC_SW, rt, rs, u); - break; - case NM_LWC1: - gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u); - break; - case NM_LDC1: - gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u); - break; - case NM_SWC1: - gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u); - break; - case NM_SDC1: - gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - } - break; - case NM_P_LS_S9: - { - int32_t s =3D (sextract32(ctx->opcode, 15, 1) << 8) | - extract32(ctx->opcode, 0, 8); - - switch (extract32(ctx->opcode, 8, 3)) { - case NM_P_LS_S0: - switch (extract32(ctx->opcode, 11, 4)) { - case NM_LBS9: - gen_ld(ctx, OPC_LB, rt, rs, s); - break; - case NM_LHS9: - gen_ld(ctx, OPC_LH, rt, rs, s); - break; - case NM_LWS9: - gen_ld(ctx, OPC_LW, rt, rs, s); - break; - case NM_LBUS9: - gen_ld(ctx, OPC_LBU, rt, rs, s); - break; - case NM_LHUS9: - gen_ld(ctx, OPC_LHU, rt, rs, s); - break; - case NM_SBS9: - gen_st(ctx, OPC_SB, rt, rs, s); - break; - case NM_SHS9: - gen_st(ctx, OPC_SH, rt, rs, s); - break; - case NM_SWS9: - gen_st(ctx, OPC_SW, rt, rs, s); - break; - case NM_LWC1S9: - gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s); - break; - case NM_LDC1S9: - gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s); - break; - case NM_SWC1S9: - gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s); - break; - case NM_SDC1S9: - gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s); - break; - case NM_P_PREFS9: - if (rt =3D=3D 31) { - /* SYNCI */ - /* - * Break the TB to be able to sync copied instruct= ions - * immediately. - */ - ctx->base.is_jmp =3D DISAS_STOP; - } else { - /* PREF */ - /* Treat as NOP. */ - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_P_LS_S1: - switch (extract32(ctx->opcode, 11, 4)) { - case NM_UALH: - case NM_UASH: - check_nms(ctx); - { - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - - gen_base_offset_addr(ctx, t0, rs, s); - - switch (extract32(ctx->opcode, 11, 4)) { - case NM_UALH: - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TE= SW | - MO_UNALN); - gen_store_gpr(t0, rt); - break; - case NM_UASH: - gen_load_gpr(t1, rt); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TE= UW | - MO_UNALN); - break; - } - tcg_temp_free(t0); - tcg_temp_free(t1); - } - break; - case NM_P_LL: - switch (ctx->opcode & 0x03) { - case NM_LL: - gen_ld(ctx, OPC_LL, rt, rs, s); - break; - case NM_LLWP: - check_xnp(ctx); - gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3,= 5)); - break; - } - break; - case NM_P_SC: - switch (ctx->opcode & 0x03) { - case NM_SC: - gen_st_cond(ctx, rt, rs, s, MO_TESL, false); - break; - case NM_SCWP: - check_xnp(ctx); - gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3,= 5), - false); - break; - } - break; - case NM_CACHE: - check_cp0_enabled(ctx); - if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { - gen_cache_operation(ctx, rt, rs, s); - } - break; - } - break; - case NM_P_LS_E0: - switch (extract32(ctx->opcode, 11, 4)) { - case NM_LBE: - check_eva(ctx); - check_cp0_enabled(ctx); - gen_ld(ctx, OPC_LBE, rt, rs, s); - break; - case NM_SBE: - check_eva(ctx); - check_cp0_enabled(ctx); - gen_st(ctx, OPC_SBE, rt, rs, s); - break; - case NM_LBUE: - check_eva(ctx); - check_cp0_enabled(ctx); - gen_ld(ctx, OPC_LBUE, rt, rs, s); - break; - case NM_P_PREFE: - if (rt =3D=3D 31) { - /* case NM_SYNCIE */ - check_eva(ctx); - check_cp0_enabled(ctx); - /* - * Break the TB to be able to sync copied instruct= ions - * immediately. - */ - ctx->base.is_jmp =3D DISAS_STOP; - } else { - /* case NM_PREFE */ - check_eva(ctx); - check_cp0_enabled(ctx); - /* Treat as NOP. */ - } - break; - case NM_LHE: - check_eva(ctx); - check_cp0_enabled(ctx); - gen_ld(ctx, OPC_LHE, rt, rs, s); - break; - case NM_SHE: - check_eva(ctx); - check_cp0_enabled(ctx); - gen_st(ctx, OPC_SHE, rt, rs, s); - break; - case NM_LHUE: - check_eva(ctx); - check_cp0_enabled(ctx); - gen_ld(ctx, OPC_LHUE, rt, rs, s); - break; - case NM_CACHEE: - check_nms_dl_il_sl_tl_l2c(ctx); - gen_cache_operation(ctx, rt, rs, s); - break; - case NM_LWE: - check_eva(ctx); - check_cp0_enabled(ctx); - gen_ld(ctx, OPC_LWE, rt, rs, s); - break; - case NM_SWE: - check_eva(ctx); - check_cp0_enabled(ctx); - gen_st(ctx, OPC_SWE, rt, rs, s); - break; - case NM_P_LLE: - switch (extract32(ctx->opcode, 2, 2)) { - case NM_LLE: - check_xnp(ctx); - check_eva(ctx); - check_cp0_enabled(ctx); - gen_ld(ctx, OPC_LLE, rt, rs, s); - break; - case NM_LLWPE: - check_xnp(ctx); - check_eva(ctx); - check_cp0_enabled(ctx); - gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3,= 5)); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_P_SCE: - switch (extract32(ctx->opcode, 2, 2)) { - case NM_SCE: - check_xnp(ctx); - check_eva(ctx); - check_cp0_enabled(ctx); - gen_st_cond(ctx, rt, rs, s, MO_TESL, true); - break; - case NM_SCWPE: - check_xnp(ctx); - check_eva(ctx); - check_cp0_enabled(ctx); - gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3,= 5), - true); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - } - break; - case NM_P_LS_WM: - case NM_P_LS_UAWM: - check_nms(ctx); - { - int count =3D extract32(ctx->opcode, 12, 3); - int counter =3D 0; - - offset =3D sextract32(ctx->opcode, 15, 1) << 8 | - extract32(ctx->opcode, 0, 8); - TCGv va =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - MemOp memop =3D (extract32(ctx->opcode, 8, 3)) =3D=3D - NM_P_LS_UAWM ? MO_UNALN : 0; - - count =3D (count =3D=3D 0) ? 8 : count; - while (counter !=3D count) { - int this_rt =3D ((rt + counter) & 0x1f) | (rt & 0x= 10); - int this_offset =3D offset + (counter << 2); - - gen_base_offset_addr(ctx, va, rs, this_offset); - - switch (extract32(ctx->opcode, 11, 1)) { - case NM_LWM: - tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx, - memop | MO_TESL); - gen_store_gpr(t1, this_rt); - if ((this_rt =3D=3D rs) && - (counter !=3D (count - 1))) { - /* UNPREDICTABLE */ - } - break; - case NM_SWM: - this_rt =3D (rt =3D=3D 0) ? 0 : this_rt; - gen_load_gpr(t1, this_rt); - tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx, - memop | MO_TEUL); - break; - } - counter++; - } - tcg_temp_free(va); - tcg_temp_free(t1); - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - } - break; - case NM_MOVE_BALC: - check_nms(ctx); - { - TCGv t0 =3D tcg_temp_new(); - int32_t s =3D sextract32(ctx->opcode, 0, 1) << 21 | - extract32(ctx->opcode, 1, 20) << 1; - rd =3D (extract32(ctx->opcode, 24, 1)) =3D=3D 0 ? 4 : 5; - rt =3D decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3= | - extract32(ctx->opcode, 21, 3)); - gen_load_gpr(t0, rt); - tcg_gen_mov_tl(cpu_gpr[rd], t0); - gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s); - tcg_temp_free(t0); - } - break; - case NM_P_BAL: - { - int32_t s =3D sextract32(ctx->opcode, 0, 1) << 25 | - extract32(ctx->opcode, 1, 24) << 1; - - if ((extract32(ctx->opcode, 25, 1)) =3D=3D 0) { - /* BC */ - gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s); - } else { - /* BALC */ - gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s); - } - } - break; - case NM_P_J: - switch (extract32(ctx->opcode, 12, 4)) { - case NM_JALRC: - case NM_JALRC_HB: - gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0); - break; - case NM_P_BALRSC: - gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_P_BR1: - { - int32_t s =3D sextract32(ctx->opcode, 0, 1) << 14 | - extract32(ctx->opcode, 1, 13) << 1; - switch (extract32(ctx->opcode, 14, 2)) { - case NM_BEQC: - check_nms(ctx); - gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s); - break; - case NM_P_BR3A: - s =3D sextract32(ctx->opcode, 0, 1) << 14 | - extract32(ctx->opcode, 1, 13) << 1; - check_cp1_enabled(ctx); - switch (extract32(ctx->opcode, 16, 5)) { - case NM_BC1EQZC: - gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s); - break; - case NM_BC1NEZC: - gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s); - break; - case NM_BPOSGE32C: - check_dsp_r3(ctx); - { - int32_t imm =3D extract32(ctx->opcode, 1, 13) | - extract32(ctx->opcode, 0, 1) << 13; - - gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2, - imm); - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_BGEC: - if (rs =3D=3D rt) { - gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s); - } else { - gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s= ); - } - break; - case NM_BGEUC: - if (rs =3D=3D rt || rt =3D=3D 0) { - gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s); - } else if (rs =3D=3D 0) { - gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s= ); - } else { - gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, = s); - } - break; - } - } - break; - case NM_P_BR2: - { - int32_t s =3D sextract32(ctx->opcode, 0, 1) << 14 | - extract32(ctx->opcode, 1, 13) << 1; - switch (extract32(ctx->opcode, 14, 2)) { - case NM_BNEC: - check_nms(ctx); - gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s); - break; - case NM_BLTC: - if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { - /* NOP */ - ctx->hflags |=3D MIPS_HFLAG_FBNSLOT; - } else { - gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s= ); - } - break; - case NM_BLTUC: - if (rs =3D=3D 0 || rs =3D=3D rt) { - /* NOP */ - ctx->hflags |=3D MIPS_HFLAG_FBNSLOT; - } else { - gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, = s); - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - } - break; - case NM_P_BRI: - { - int32_t s =3D sextract32(ctx->opcode, 0, 1) << 11 | - extract32(ctx->opcode, 1, 10) << 1; - uint32_t u =3D extract32(ctx->opcode, 11, 7); - - gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3), - rt, u, s); - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - return 4; -} - -static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t op; - int rt =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode)); - int rs =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); - int rd =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode)); - int offset; - int imm; - - /* make sure instructions are on a halfword boundary */ - if (ctx->base.pc_next & 0x1) { - TCGv tmp =3D tcg_const_tl(ctx->base.pc_next); - tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); - tcg_temp_free(tmp); - generate_exception_end(ctx, EXCP_AdEL); - return 2; - } - - op =3D extract32(ctx->opcode, 10, 6); - switch (op) { - case NM_P16_MV: - rt =3D NANOMIPS_EXTRACT_RD5(ctx->opcode); - if (rt !=3D 0) { - /* MOVE */ - rs =3D NANOMIPS_EXTRACT_RS5(ctx->opcode); - gen_arith(ctx, OPC_ADDU, rt, rs, 0); - } else { - /* P16.RI */ - switch (extract32(ctx->opcode, 3, 2)) { - case NM_P16_SYSCALL: - if (extract32(ctx->opcode, 2, 1) =3D=3D 0) { - generate_exception_end(ctx, EXCP_SYSCALL); - } else { - generate_exception_end(ctx, EXCP_RI); - } - break; - case NM_BREAK16: - generate_exception_end(ctx, EXCP_BREAK); - break; - case NM_SDBBP16: - if (is_uhi(extract32(ctx->opcode, 0, 3))) { - gen_helper_do_semihosting(cpu_env); - } else { - if (ctx->hflags & MIPS_HFLAG_SBRI) { - generate_exception_end(ctx, EXCP_RI); - } else { - generate_exception_end(ctx, EXCP_DBp); - } - } - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - } - break; - case NM_P16_SHIFT: - { - int shift =3D extract32(ctx->opcode, 0, 3); - uint32_t opc =3D 0; - shift =3D (shift =3D=3D 0) ? 8 : shift; - - switch (extract32(ctx->opcode, 3, 1)) { - case NM_SLL16: - opc =3D OPC_SLL; - break; - case NM_SRL16: - opc =3D OPC_SRL; - break; - } - gen_shift_imm(ctx, opc, rt, rs, shift); - } - break; - case NM_P16C: - switch (ctx->opcode & 1) { - case NM_POOL16C_0: - gen_pool16c_nanomips_insn(ctx); - break; - case NM_LWXS16: - gen_ldxs(ctx, rt, rs, rd); - break; - } - break; - case NM_P16_A1: - switch (extract32(ctx->opcode, 6, 1)) { - case NM_ADDIUR1SP: - imm =3D extract32(ctx->opcode, 0, 6) << 2; - gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_P16_A2: - switch (extract32(ctx->opcode, 3, 1)) { - case NM_ADDIUR2: - imm =3D extract32(ctx->opcode, 0, 3) << 2; - gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm); - break; - case NM_P_ADDIURS5: - rt =3D extract32(ctx->opcode, 5, 5); - if (rt !=3D 0) { - /* imm =3D sign_extend(s[3] . s[2:0] , from_nbits =3D 4) */ - imm =3D (sextract32(ctx->opcode, 4, 1) << 3) | - (extract32(ctx->opcode, 0, 3)); - gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm); - } - break; - } - break; - case NM_P16_ADDU: - switch (ctx->opcode & 0x1) { - case NM_ADDU16: - gen_arith(ctx, OPC_ADDU, rd, rs, rt); - break; - case NM_SUBU16: - gen_arith(ctx, OPC_SUBU, rd, rs, rt); - break; - } - break; - case NM_P16_4X4: - rt =3D (extract32(ctx->opcode, 9, 1) << 3) | - extract32(ctx->opcode, 5, 3); - rs =3D (extract32(ctx->opcode, 4, 1) << 3) | - extract32(ctx->opcode, 0, 3); - rt =3D decode_gpr_gpr4(rt); - rs =3D decode_gpr_gpr4(rs); - switch ((extract32(ctx->opcode, 7, 2) & 0x2) | - (extract32(ctx->opcode, 3, 1))) { - case NM_ADDU4X4: - check_nms(ctx); - gen_arith(ctx, OPC_ADDU, rt, rs, rt); - break; - case NM_MUL4X4: - check_nms(ctx); - gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_LI16: - { - int imm =3D extract32(ctx->opcode, 0, 7); - imm =3D (imm =3D=3D 0x7f ? -1 : imm); - if (rt !=3D 0) { - tcg_gen_movi_tl(cpu_gpr[rt], imm); - } - } - break; - case NM_ANDI16: - { - uint32_t u =3D extract32(ctx->opcode, 0, 4); - u =3D (u =3D=3D 12) ? 0xff : - (u =3D=3D 13) ? 0xffff : u; - gen_logic_imm(ctx, OPC_ANDI, rt, rs, u); - } - break; - case NM_P16_LB: - offset =3D extract32(ctx->opcode, 0, 2); - switch (extract32(ctx->opcode, 2, 2)) { - case NM_LB16: - gen_ld(ctx, OPC_LB, rt, rs, offset); - break; - case NM_SB16: - rt =3D decode_gpr_gpr3_src_store( - NANOMIPS_EXTRACT_RT3(ctx->opcode)); - gen_st(ctx, OPC_SB, rt, rs, offset); - break; - case NM_LBU16: - gen_ld(ctx, OPC_LBU, rt, rs, offset); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_P16_LH: - offset =3D extract32(ctx->opcode, 1, 2) << 1; - switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) { - case NM_LH16: - gen_ld(ctx, OPC_LH, rt, rs, offset); - break; - case NM_SH16: - rt =3D decode_gpr_gpr3_src_store( - NANOMIPS_EXTRACT_RT3(ctx->opcode)); - gen_st(ctx, OPC_SH, rt, rs, offset); - break; - case NM_LHU16: - gen_ld(ctx, OPC_LHU, rt, rs, offset); - break; - default: - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case NM_LW16: - offset =3D extract32(ctx->opcode, 0, 4) << 2; - gen_ld(ctx, OPC_LW, rt, rs, offset); - break; - case NM_LWSP16: - rt =3D NANOMIPS_EXTRACT_RD5(ctx->opcode); - offset =3D extract32(ctx->opcode, 0, 5) << 2; - gen_ld(ctx, OPC_LW, rt, 29, offset); - break; - case NM_LW4X4: - check_nms(ctx); - rt =3D (extract32(ctx->opcode, 9, 1) << 3) | - extract32(ctx->opcode, 5, 3); - rs =3D (extract32(ctx->opcode, 4, 1) << 3) | - extract32(ctx->opcode, 0, 3); - offset =3D (extract32(ctx->opcode, 3, 1) << 3) | - (extract32(ctx->opcode, 8, 1) << 2); - rt =3D decode_gpr_gpr4(rt); - rs =3D decode_gpr_gpr4(rs); - gen_ld(ctx, OPC_LW, rt, rs, offset); - break; - case NM_SW4X4: - check_nms(ctx); - rt =3D (extract32(ctx->opcode, 9, 1) << 3) | - extract32(ctx->opcode, 5, 3); - rs =3D (extract32(ctx->opcode, 4, 1) << 3) | - extract32(ctx->opcode, 0, 3); - offset =3D (extract32(ctx->opcode, 3, 1) << 3) | - (extract32(ctx->opcode, 8, 1) << 2); - rt =3D decode_gpr_gpr4_zero(rt); - rs =3D decode_gpr_gpr4(rs); - gen_st(ctx, OPC_SW, rt, rs, offset); - break; - case NM_LWGP16: - offset =3D extract32(ctx->opcode, 0, 7) << 2; - gen_ld(ctx, OPC_LW, rt, 28, offset); - break; - case NM_SWSP16: - rt =3D NANOMIPS_EXTRACT_RD5(ctx->opcode); - offset =3D extract32(ctx->opcode, 0, 5) << 2; - gen_st(ctx, OPC_SW, rt, 29, offset); - break; - case NM_SW16: - rt =3D decode_gpr_gpr3_src_store( - NANOMIPS_EXTRACT_RT3(ctx->opcode)); - rs =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); - offset =3D extract32(ctx->opcode, 0, 4) << 2; - gen_st(ctx, OPC_SW, rt, rs, offset); - break; - case NM_SWGP16: - rt =3D decode_gpr_gpr3_src_store( - NANOMIPS_EXTRACT_RT3(ctx->opcode)); - offset =3D extract32(ctx->opcode, 0, 7) << 2; - gen_st(ctx, OPC_SW, rt, 28, offset); - break; - case NM_BC16: - gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0, - (sextract32(ctx->opcode, 0, 1) << 10) | - (extract32(ctx->opcode, 1, 9) << 1)); - break; - case NM_BALC16: - gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0, - (sextract32(ctx->opcode, 0, 1) << 10) | - (extract32(ctx->opcode, 1, 9) << 1)); - break; - case NM_BEQZC16: - gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0, - (sextract32(ctx->opcode, 0, 1) << 7) | - (extract32(ctx->opcode, 1, 6) << 1)); - break; - case NM_BNEZC16: - gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0, - (sextract32(ctx->opcode, 0, 1) << 7) | - (extract32(ctx->opcode, 1, 6) << 1)); - break; - case NM_P16_BR: - switch (ctx->opcode & 0xf) { - case 0: - /* P16.JRC */ - switch (extract32(ctx->opcode, 4, 1)) { - case NM_JRC: - gen_compute_branch_nm(ctx, OPC_JR, 2, - extract32(ctx->opcode, 5, 5), 0, 0); - break; - case NM_JALRC16: - gen_compute_branch_nm(ctx, OPC_JALR, 2, - extract32(ctx->opcode, 5, 5), 31, 0); - break; - } - break; - default: - { - /* P16.BRI */ - uint32_t opc =3D extract32(ctx->opcode, 4, 3) < - extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OP= C_BNE; - gen_compute_branch_nm(ctx, opc, 2, rs, rt, - extract32(ctx->opcode, 0, 4) << 1); - } - break; - } - break; - case NM_P16_SR: - { - int count =3D extract32(ctx->opcode, 0, 4); - int u =3D extract32(ctx->opcode, 4, 4) << 4; - - rt =3D 30 + extract32(ctx->opcode, 9, 1); - switch (extract32(ctx->opcode, 8, 1)) { - case NM_SAVE16: - gen_save(ctx, rt, count, 0, u); - break; - case NM_RESTORE_JRC16: - gen_restore(ctx, rt, count, 0, u); - gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0); - break; - } - } - break; - case NM_MOVEP: - case NM_MOVEPREV: - check_nms(ctx); - { - static const int gpr2reg1[] =3D {4, 5, 6, 7}; - static const int gpr2reg2[] =3D {5, 6, 7, 8}; - int re; - int rd2 =3D extract32(ctx->opcode, 3, 1) << 1 | - extract32(ctx->opcode, 8, 1); - int r1 =3D gpr2reg1[rd2]; - int r2 =3D gpr2reg2[rd2]; - int r3 =3D extract32(ctx->opcode, 4, 1) << 3 | - extract32(ctx->opcode, 0, 3); - int r4 =3D extract32(ctx->opcode, 9, 1) << 3 | - extract32(ctx->opcode, 5, 3); - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - if (op =3D=3D NM_MOVEP) { - rd =3D r1; - re =3D r2; - rs =3D decode_gpr_gpr4_zero(r3); - rt =3D decode_gpr_gpr4_zero(r4); - } else { - rd =3D decode_gpr_gpr4(r3); - re =3D decode_gpr_gpr4(r4); - rs =3D r1; - rt =3D r2; - } - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - tcg_gen_mov_tl(cpu_gpr[rd], t0); - tcg_gen_mov_tl(cpu_gpr[re], t1); - tcg_temp_free(t0); - tcg_temp_free(t1); - } - break; - default: - return decode_nanomips_32_48_opc(env, ctx); - } - - return 2; -} - +#include "isa-nanomips_translate.c.inc" =20 /* SmartMIPS extension to MIPS32 */ =20 diff --git a/MAINTAINERS b/MAINTAINERS index 2e018a0c1da..ce7fe949036 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -243,6 +243,7 @@ K: ^Subject:.*(?i)mips MIPS TCG CPUs (nanoMIPS ISA) S: Orphan F: disas/nanomips.* +F: target/mips/isa-nanomips* =20 Moxie TCG CPUs M: Anthony Green diff --git a/target/mips/isa-nanomips_translate.c.inc b/target/mips/isa-nan= omips_translate.c.inc new file mode 100644 index 00000000000..d59a2bea9b6 --- /dev/null +++ b/target/mips/isa-nanomips_translate.c.inc @@ -0,0 +1,4839 @@ +/* + * MIPS emulation for QEMU - nanoMIPS translation routines + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +/* MAJOR, P16, and P32 pools opcodes */ +enum { + NM_P_ADDIU =3D 0x00, + NM_ADDIUPC =3D 0x01, + NM_MOVE_BALC =3D 0x02, + NM_P16_MV =3D 0x04, + NM_LW16 =3D 0x05, + NM_BC16 =3D 0x06, + NM_P16_SR =3D 0x07, + + NM_POOL32A =3D 0x08, + NM_P_BAL =3D 0x0a, + NM_P16_SHIFT =3D 0x0c, + NM_LWSP16 =3D 0x0d, + NM_BALC16 =3D 0x0e, + NM_P16_4X4 =3D 0x0f, + + NM_P_GP_W =3D 0x10, + NM_P_GP_BH =3D 0x11, + NM_P_J =3D 0x12, + NM_P16C =3D 0x14, + NM_LWGP16 =3D 0x15, + NM_P16_LB =3D 0x17, + + NM_P48I =3D 0x18, + NM_P16_A1 =3D 0x1c, + NM_LW4X4 =3D 0x1d, + NM_P16_LH =3D 0x1f, + + NM_P_U12 =3D 0x20, + NM_P_LS_U12 =3D 0x21, + NM_P_BR1 =3D 0x22, + NM_P16_A2 =3D 0x24, + NM_SW16 =3D 0x25, + NM_BEQZC16 =3D 0x26, + + NM_POOL32F =3D 0x28, + NM_P_LS_S9 =3D 0x29, + NM_P_BR2 =3D 0x2a, + + NM_P16_ADDU =3D 0x2c, + NM_SWSP16 =3D 0x2d, + NM_BNEZC16 =3D 0x2e, + NM_MOVEP =3D 0x2f, + + NM_POOL32S =3D 0x30, + NM_P_BRI =3D 0x32, + NM_LI16 =3D 0x34, + NM_SWGP16 =3D 0x35, + NM_P16_BR =3D 0x36, + + NM_P_LUI =3D 0x38, + NM_ANDI16 =3D 0x3c, + NM_SW4X4 =3D 0x3d, + NM_MOVEPREV =3D 0x3f, +}; + +/* POOL32A instruction pool */ +enum { + NM_POOL32A0 =3D 0x00, + NM_SPECIAL2 =3D 0x01, + NM_COP2_1 =3D 0x02, + NM_UDI =3D 0x03, + NM_POOL32A5 =3D 0x05, + NM_POOL32A7 =3D 0x07, +}; + +/* P.GP.W instruction pool */ +enum { + NM_ADDIUGP_W =3D 0x00, + NM_LWGP =3D 0x02, + NM_SWGP =3D 0x03, +}; + +/* P48I instruction pool */ +enum { + NM_LI48 =3D 0x00, + NM_ADDIU48 =3D 0x01, + NM_ADDIUGP48 =3D 0x02, + NM_ADDIUPC48 =3D 0x03, + NM_LWPC48 =3D 0x0b, + NM_SWPC48 =3D 0x0f, +}; + +/* P.U12 instruction pool */ +enum { + NM_ORI =3D 0x00, + NM_XORI =3D 0x01, + NM_ANDI =3D 0x02, + NM_P_SR =3D 0x03, + NM_SLTI =3D 0x04, + NM_SLTIU =3D 0x05, + NM_SEQI =3D 0x06, + NM_ADDIUNEG =3D 0x08, + NM_P_SHIFT =3D 0x0c, + NM_P_ROTX =3D 0x0d, + NM_P_INS =3D 0x0e, + NM_P_EXT =3D 0x0f, +}; + +/* POOL32F instruction pool */ +enum { + NM_POOL32F_0 =3D 0x00, + NM_POOL32F_3 =3D 0x03, + NM_POOL32F_5 =3D 0x05, +}; + +/* POOL32S instruction pool */ +enum { + NM_POOL32S_0 =3D 0x00, + NM_POOL32S_4 =3D 0x04, +}; + +/* P.LUI instruction pool */ +enum { + NM_LUI =3D 0x00, + NM_ALUIPC =3D 0x01, +}; + +/* P.GP.BH instruction pool */ +enum { + NM_LBGP =3D 0x00, + NM_SBGP =3D 0x01, + NM_LBUGP =3D 0x02, + NM_ADDIUGP_B =3D 0x03, + NM_P_GP_LH =3D 0x04, + NM_P_GP_SH =3D 0x05, + NM_P_GP_CP1 =3D 0x06, +}; + +/* P.LS.U12 instruction pool */ +enum { + NM_LB =3D 0x00, + NM_SB =3D 0x01, + NM_LBU =3D 0x02, + NM_P_PREFU12 =3D 0x03, + NM_LH =3D 0x04, + NM_SH =3D 0x05, + NM_LHU =3D 0x06, + NM_LWU =3D 0x07, + NM_LW =3D 0x08, + NM_SW =3D 0x09, + NM_LWC1 =3D 0x0a, + NM_SWC1 =3D 0x0b, + NM_LDC1 =3D 0x0e, + NM_SDC1 =3D 0x0f, +}; + +/* P.LS.S9 instruction pool */ +enum { + NM_P_LS_S0 =3D 0x00, + NM_P_LS_S1 =3D 0x01, + NM_P_LS_E0 =3D 0x02, + NM_P_LS_WM =3D 0x04, + NM_P_LS_UAWM =3D 0x05, +}; + +/* P.BAL instruction pool */ +enum { + NM_BC =3D 0x00, + NM_BALC =3D 0x01, +}; + +/* P.J instruction pool */ +enum { + NM_JALRC =3D 0x00, + NM_JALRC_HB =3D 0x01, + NM_P_BALRSC =3D 0x08, +}; + +/* P.BR1 instruction pool */ +enum { + NM_BEQC =3D 0x00, + NM_P_BR3A =3D 0x01, + NM_BGEC =3D 0x02, + NM_BGEUC =3D 0x03, +}; + +/* P.BR2 instruction pool */ +enum { + NM_BNEC =3D 0x00, + NM_BLTC =3D 0x02, + NM_BLTUC =3D 0x03, +}; + +/* P.BRI instruction pool */ +enum { + NM_BEQIC =3D 0x00, + NM_BBEQZC =3D 0x01, + NM_BGEIC =3D 0x02, + NM_BGEIUC =3D 0x03, + NM_BNEIC =3D 0x04, + NM_BBNEZC =3D 0x05, + NM_BLTIC =3D 0x06, + NM_BLTIUC =3D 0x07, +}; + +/* P16.SHIFT instruction pool */ +enum { + NM_SLL16 =3D 0x00, + NM_SRL16 =3D 0x01, +}; + +/* POOL16C instruction pool */ +enum { + NM_POOL16C_0 =3D 0x00, + NM_LWXS16 =3D 0x01, +}; + +/* P16.A1 instruction pool */ +enum { + NM_ADDIUR1SP =3D 0x01, +}; + +/* P16.A2 instruction pool */ +enum { + NM_ADDIUR2 =3D 0x00, + NM_P_ADDIURS5 =3D 0x01, +}; + +/* P16.ADDU instruction pool */ +enum { + NM_ADDU16 =3D 0x00, + NM_SUBU16 =3D 0x01, +}; + +/* P16.SR instruction pool */ +enum { + NM_SAVE16 =3D 0x00, + NM_RESTORE_JRC16 =3D 0x01, +}; + +/* P16.4X4 instruction pool */ +enum { + NM_ADDU4X4 =3D 0x00, + NM_MUL4X4 =3D 0x01, +}; + +/* P16.LB instruction pool */ +enum { + NM_LB16 =3D 0x00, + NM_SB16 =3D 0x01, + NM_LBU16 =3D 0x02, +}; + +/* P16.LH instruction pool */ +enum { + NM_LH16 =3D 0x00, + NM_SH16 =3D 0x01, + NM_LHU16 =3D 0x02, +}; + +/* P.RI instruction pool */ +enum { + NM_SIGRIE =3D 0x00, + NM_P_SYSCALL =3D 0x01, + NM_BREAK =3D 0x02, + NM_SDBBP =3D 0x03, +}; + +/* POOL32A0 instruction pool */ +enum { + NM_P_TRAP =3D 0x00, + NM_SEB =3D 0x01, + NM_SLLV =3D 0x02, + NM_MUL =3D 0x03, + NM_MFC0 =3D 0x06, + NM_MFHC0 =3D 0x07, + NM_SEH =3D 0x09, + NM_SRLV =3D 0x0a, + NM_MUH =3D 0x0b, + NM_MTC0 =3D 0x0e, + NM_MTHC0 =3D 0x0f, + NM_SRAV =3D 0x12, + NM_MULU =3D 0x13, + NM_ROTRV =3D 0x1a, + NM_MUHU =3D 0x1b, + NM_ADD =3D 0x22, + NM_DIV =3D 0x23, + NM_ADDU =3D 0x2a, + NM_MOD =3D 0x2b, + NM_SUB =3D 0x32, + NM_DIVU =3D 0x33, + NM_RDHWR =3D 0x38, + NM_SUBU =3D 0x3a, + NM_MODU =3D 0x3b, + NM_P_CMOVE =3D 0x42, + NM_FORK =3D 0x45, + NM_MFTR =3D 0x46, + NM_MFHTR =3D 0x47, + NM_AND =3D 0x4a, + NM_YIELD =3D 0x4d, + NM_MTTR =3D 0x4e, + NM_MTHTR =3D 0x4f, + NM_OR =3D 0x52, + NM_D_E_MT_VPE =3D 0x56, + NM_NOR =3D 0x5a, + NM_XOR =3D 0x62, + NM_SLT =3D 0x6a, + NM_P_SLTU =3D 0x72, + NM_SOV =3D 0x7a, +}; + +/* CRC32 instruction pool */ +enum { + NM_CRC32B =3D 0x00, + NM_CRC32H =3D 0x01, + NM_CRC32W =3D 0x02, + NM_CRC32CB =3D 0x04, + NM_CRC32CH =3D 0x05, + NM_CRC32CW =3D 0x06, +}; + +/* POOL32A5 instruction pool */ +enum { + NM_CMP_EQ_PH =3D 0x00, + NM_CMP_LT_PH =3D 0x08, + NM_CMP_LE_PH =3D 0x10, + NM_CMPGU_EQ_QB =3D 0x18, + NM_CMPGU_LT_QB =3D 0x20, + NM_CMPGU_LE_QB =3D 0x28, + NM_CMPGDU_EQ_QB =3D 0x30, + NM_CMPGDU_LT_QB =3D 0x38, + NM_CMPGDU_LE_QB =3D 0x40, + NM_CMPU_EQ_QB =3D 0x48, + NM_CMPU_LT_QB =3D 0x50, + NM_CMPU_LE_QB =3D 0x58, + NM_ADDQ_S_W =3D 0x60, + NM_SUBQ_S_W =3D 0x68, + NM_ADDSC =3D 0x70, + NM_ADDWC =3D 0x78, + + NM_ADDQ_S_PH =3D 0x01, + NM_ADDQH_R_PH =3D 0x09, + NM_ADDQH_R_W =3D 0x11, + NM_ADDU_S_QB =3D 0x19, + NM_ADDU_S_PH =3D 0x21, + NM_ADDUH_R_QB =3D 0x29, + NM_SHRAV_R_PH =3D 0x31, + NM_SHRAV_R_QB =3D 0x39, + NM_SUBQ_S_PH =3D 0x41, + NM_SUBQH_R_PH =3D 0x49, + NM_SUBQH_R_W =3D 0x51, + NM_SUBU_S_QB =3D 0x59, + NM_SUBU_S_PH =3D 0x61, + NM_SUBUH_R_QB =3D 0x69, + NM_SHLLV_S_PH =3D 0x71, + NM_PRECR_SRA_R_PH_W =3D 0x79, + + NM_MULEU_S_PH_QBL =3D 0x12, + NM_MULEU_S_PH_QBR =3D 0x1a, + NM_MULQ_RS_PH =3D 0x22, + NM_MULQ_S_PH =3D 0x2a, + NM_MULQ_RS_W =3D 0x32, + NM_MULQ_S_W =3D 0x3a, + NM_APPEND =3D 0x42, + NM_MODSUB =3D 0x52, + NM_SHRAV_R_W =3D 0x5a, + NM_SHRLV_PH =3D 0x62, + NM_SHRLV_QB =3D 0x6a, + NM_SHLLV_QB =3D 0x72, + NM_SHLLV_S_W =3D 0x7a, + + NM_SHILO =3D 0x03, + + NM_MULEQ_S_W_PHL =3D 0x04, + NM_MULEQ_S_W_PHR =3D 0x0c, + + NM_MUL_S_PH =3D 0x05, + NM_PRECR_QB_PH =3D 0x0d, + NM_PRECRQ_QB_PH =3D 0x15, + NM_PRECRQ_PH_W =3D 0x1d, + NM_PRECRQ_RS_PH_W =3D 0x25, + NM_PRECRQU_S_QB_PH =3D 0x2d, + NM_PACKRL_PH =3D 0x35, + NM_PICK_QB =3D 0x3d, + NM_PICK_PH =3D 0x45, + + NM_SHRA_R_W =3D 0x5e, + NM_SHRA_R_PH =3D 0x66, + NM_SHLL_S_PH =3D 0x76, + NM_SHLL_S_W =3D 0x7e, + + NM_REPL_PH =3D 0x07 +}; + +/* POOL32A7 instruction pool */ +enum { + NM_P_LSX =3D 0x00, + NM_LSA =3D 0x01, + NM_EXTW =3D 0x03, + NM_POOL32AXF =3D 0x07, +}; + +/* P.SR instruction pool */ +enum { + NM_PP_SR =3D 0x00, + NM_P_SR_F =3D 0x01, +}; + +/* P.SHIFT instruction pool */ +enum { + NM_P_SLL =3D 0x00, + NM_SRL =3D 0x02, + NM_SRA =3D 0x04, + NM_ROTR =3D 0x06, +}; + +/* P.ROTX instruction pool */ +enum { + NM_ROTX =3D 0x00, +}; + +/* P.INS instruction pool */ +enum { + NM_INS =3D 0x00, +}; + +/* P.EXT instruction pool */ +enum { + NM_EXT =3D 0x00, +}; + +/* POOL32F_0 (fmt) instruction pool */ +enum { + NM_RINT_S =3D 0x04, + NM_RINT_D =3D 0x44, + NM_ADD_S =3D 0x06, + NM_SELEQZ_S =3D 0x07, + NM_SELEQZ_D =3D 0x47, + NM_CLASS_S =3D 0x0c, + NM_CLASS_D =3D 0x4c, + NM_SUB_S =3D 0x0e, + NM_SELNEZ_S =3D 0x0f, + NM_SELNEZ_D =3D 0x4f, + NM_MUL_S =3D 0x16, + NM_SEL_S =3D 0x17, + NM_SEL_D =3D 0x57, + NM_DIV_S =3D 0x1e, + NM_ADD_D =3D 0x26, + NM_SUB_D =3D 0x2e, + NM_MUL_D =3D 0x36, + NM_MADDF_S =3D 0x37, + NM_MADDF_D =3D 0x77, + NM_DIV_D =3D 0x3e, + NM_MSUBF_S =3D 0x3f, + NM_MSUBF_D =3D 0x7f, +}; + +/* POOL32F_3 instruction pool */ +enum { + NM_MIN_FMT =3D 0x00, + NM_MAX_FMT =3D 0x01, + NM_MINA_FMT =3D 0x04, + NM_MAXA_FMT =3D 0x05, + NM_POOL32FXF =3D 0x07, +}; + +/* POOL32F_5 instruction pool */ +enum { + NM_CMP_CONDN_S =3D 0x00, + NM_CMP_CONDN_D =3D 0x02, +}; + +/* P.GP.LH instruction pool */ +enum { + NM_LHGP =3D 0x00, + NM_LHUGP =3D 0x01, +}; + +/* P.GP.SH instruction pool */ +enum { + NM_SHGP =3D 0x00, +}; + +/* P.GP.CP1 instruction pool */ +enum { + NM_LWC1GP =3D 0x00, + NM_SWC1GP =3D 0x01, + NM_LDC1GP =3D 0x02, + NM_SDC1GP =3D 0x03, +}; + +/* P.LS.S0 instruction pool */ +enum { + NM_LBS9 =3D 0x00, + NM_LHS9 =3D 0x04, + NM_LWS9 =3D 0x08, + NM_LDS9 =3D 0x0c, + + NM_SBS9 =3D 0x01, + NM_SHS9 =3D 0x05, + NM_SWS9 =3D 0x09, + NM_SDS9 =3D 0x0d, + + NM_LBUS9 =3D 0x02, + NM_LHUS9 =3D 0x06, + NM_LWC1S9 =3D 0x0a, + NM_LDC1S9 =3D 0x0e, + + NM_P_PREFS9 =3D 0x03, + NM_LWUS9 =3D 0x07, + NM_SWC1S9 =3D 0x0b, + NM_SDC1S9 =3D 0x0f, +}; + +/* P.LS.S1 instruction pool */ +enum { + NM_ASET_ACLR =3D 0x02, + NM_UALH =3D 0x04, + NM_UASH =3D 0x05, + NM_CACHE =3D 0x07, + NM_P_LL =3D 0x0a, + NM_P_SC =3D 0x0b, +}; + +/* P.LS.E0 instruction pool */ +enum { + NM_LBE =3D 0x00, + NM_SBE =3D 0x01, + NM_LBUE =3D 0x02, + NM_P_PREFE =3D 0x03, + NM_LHE =3D 0x04, + NM_SHE =3D 0x05, + NM_LHUE =3D 0x06, + NM_CACHEE =3D 0x07, + NM_LWE =3D 0x08, + NM_SWE =3D 0x09, + NM_P_LLE =3D 0x0a, + NM_P_SCE =3D 0x0b, +}; + +/* P.PREFE instruction pool */ +enum { + NM_SYNCIE =3D 0x00, + NM_PREFE =3D 0x01, +}; + +/* P.LLE instruction pool */ +enum { + NM_LLE =3D 0x00, + NM_LLWPE =3D 0x01, +}; + +/* P.SCE instruction pool */ +enum { + NM_SCE =3D 0x00, + NM_SCWPE =3D 0x01, +}; + +/* P.LS.WM instruction pool */ +enum { + NM_LWM =3D 0x00, + NM_SWM =3D 0x01, +}; + +/* P.LS.UAWM instruction pool */ +enum { + NM_UALWM =3D 0x00, + NM_UASWM =3D 0x01, +}; + +/* P.BR3A instruction pool */ +enum { + NM_BC1EQZC =3D 0x00, + NM_BC1NEZC =3D 0x01, + NM_BC2EQZC =3D 0x02, + NM_BC2NEZC =3D 0x03, + NM_BPOSGE32C =3D 0x04, +}; + +/* P16.RI instruction pool */ +enum { + NM_P16_SYSCALL =3D 0x01, + NM_BREAK16 =3D 0x02, + NM_SDBBP16 =3D 0x03, +}; + +/* POOL16C_0 instruction pool */ +enum { + NM_POOL16C_00 =3D 0x00, +}; + +/* P16.JRC instruction pool */ +enum { + NM_JRC =3D 0x00, + NM_JALRC16 =3D 0x01, +}; + +/* P.SYSCALL instruction pool */ +enum { + NM_SYSCALL =3D 0x00, + NM_HYPCALL =3D 0x01, +}; + +/* P.TRAP instruction pool */ +enum { + NM_TEQ =3D 0x00, + NM_TNE =3D 0x01, +}; + +/* P.CMOVE instruction pool */ +enum { + NM_MOVZ =3D 0x00, + NM_MOVN =3D 0x01, +}; + +/* POOL32Axf instruction pool */ +enum { + NM_POOL32AXF_1 =3D 0x01, + NM_POOL32AXF_2 =3D 0x02, + NM_POOL32AXF_4 =3D 0x04, + NM_POOL32AXF_5 =3D 0x05, + NM_POOL32AXF_7 =3D 0x07, +}; + +/* POOL32Axf_1 instruction pool */ +enum { + NM_POOL32AXF_1_0 =3D 0x00, + NM_POOL32AXF_1_1 =3D 0x01, + NM_POOL32AXF_1_3 =3D 0x03, + NM_POOL32AXF_1_4 =3D 0x04, + NM_POOL32AXF_1_5 =3D 0x05, + NM_POOL32AXF_1_7 =3D 0x07, +}; + +/* POOL32Axf_2 instruction pool */ +enum { + NM_POOL32AXF_2_0_7 =3D 0x00, + NM_POOL32AXF_2_8_15 =3D 0x01, + NM_POOL32AXF_2_16_23 =3D 0x02, + NM_POOL32AXF_2_24_31 =3D 0x03, +}; + +/* POOL32Axf_7 instruction pool */ +enum { + NM_SHRA_R_QB =3D 0x0, + NM_SHRL_PH =3D 0x1, + NM_REPL_QB =3D 0x2, +}; + +/* POOL32Axf_1_0 instruction pool */ +enum { + NM_MFHI =3D 0x0, + NM_MFLO =3D 0x1, + NM_MTHI =3D 0x2, + NM_MTLO =3D 0x3, +}; + +/* POOL32Axf_1_1 instruction pool */ +enum { + NM_MTHLIP =3D 0x0, + NM_SHILOV =3D 0x1, +}; + +/* POOL32Axf_1_3 instruction pool */ +enum { + NM_RDDSP =3D 0x0, + NM_WRDSP =3D 0x1, + NM_EXTP =3D 0x2, + NM_EXTPDP =3D 0x3, +}; + +/* POOL32Axf_1_4 instruction pool */ +enum { + NM_SHLL_QB =3D 0x0, + NM_SHRL_QB =3D 0x1, +}; + +/* POOL32Axf_1_5 instruction pool */ +enum { + NM_MAQ_S_W_PHR =3D 0x0, + NM_MAQ_S_W_PHL =3D 0x1, + NM_MAQ_SA_W_PHR =3D 0x2, + NM_MAQ_SA_W_PHL =3D 0x3, +}; + +/* POOL32Axf_1_7 instruction pool */ +enum { + NM_EXTR_W =3D 0x0, + NM_EXTR_R_W =3D 0x1, + NM_EXTR_RS_W =3D 0x2, + NM_EXTR_S_H =3D 0x3, +}; + +/* POOL32Axf_2_0_7 instruction pool */ +enum { + NM_DPA_W_PH =3D 0x0, + NM_DPAQ_S_W_PH =3D 0x1, + NM_DPS_W_PH =3D 0x2, + NM_DPSQ_S_W_PH =3D 0x3, + NM_BALIGN =3D 0x4, + NM_MADD =3D 0x5, + NM_MULT =3D 0x6, + NM_EXTRV_W =3D 0x7, +}; + +/* POOL32Axf_2_8_15 instruction pool */ +enum { + NM_DPAX_W_PH =3D 0x0, + NM_DPAQ_SA_L_W =3D 0x1, + NM_DPSX_W_PH =3D 0x2, + NM_DPSQ_SA_L_W =3D 0x3, + NM_MADDU =3D 0x5, + NM_MULTU =3D 0x6, + NM_EXTRV_R_W =3D 0x7, +}; + +/* POOL32Axf_2_16_23 instruction pool */ +enum { + NM_DPAU_H_QBL =3D 0x0, + NM_DPAQX_S_W_PH =3D 0x1, + NM_DPSU_H_QBL =3D 0x2, + NM_DPSQX_S_W_PH =3D 0x3, + NM_EXTPV =3D 0x4, + NM_MSUB =3D 0x5, + NM_MULSA_W_PH =3D 0x6, + NM_EXTRV_RS_W =3D 0x7, +}; + +/* POOL32Axf_2_24_31 instruction pool */ +enum { + NM_DPAU_H_QBR =3D 0x0, + NM_DPAQX_SA_W_PH =3D 0x1, + NM_DPSU_H_QBR =3D 0x2, + NM_DPSQX_SA_W_PH =3D 0x3, + NM_EXTPDPV =3D 0x4, + NM_MSUBU =3D 0x5, + NM_MULSAQ_S_W_PH =3D 0x6, + NM_EXTRV_S_H =3D 0x7, +}; + +/* POOL32Axf_{4, 5} instruction pool */ +enum { + NM_CLO =3D 0x25, + NM_CLZ =3D 0x2d, + + NM_TLBP =3D 0x01, + NM_TLBR =3D 0x09, + NM_TLBWI =3D 0x11, + NM_TLBWR =3D 0x19, + NM_TLBINV =3D 0x03, + NM_TLBINVF =3D 0x0b, + NM_DI =3D 0x23, + NM_EI =3D 0x2b, + NM_RDPGPR =3D 0x70, + NM_WRPGPR =3D 0x78, + NM_WAIT =3D 0x61, + NM_DERET =3D 0x71, + NM_ERETX =3D 0x79, + + /* nanoMIPS DSP instructions */ + NM_ABSQ_S_QB =3D 0x00, + NM_ABSQ_S_PH =3D 0x08, + NM_ABSQ_S_W =3D 0x10, + NM_PRECEQ_W_PHL =3D 0x28, + NM_PRECEQ_W_PHR =3D 0x30, + NM_PRECEQU_PH_QBL =3D 0x38, + NM_PRECEQU_PH_QBR =3D 0x48, + NM_PRECEU_PH_QBL =3D 0x58, + NM_PRECEU_PH_QBR =3D 0x68, + NM_PRECEQU_PH_QBLA =3D 0x39, + NM_PRECEQU_PH_QBRA =3D 0x49, + NM_PRECEU_PH_QBLA =3D 0x59, + NM_PRECEU_PH_QBRA =3D 0x69, + NM_REPLV_PH =3D 0x01, + NM_REPLV_QB =3D 0x09, + NM_BITREV =3D 0x18, + NM_INSV =3D 0x20, + NM_RADDU_W_QB =3D 0x78, + + NM_BITSWAP =3D 0x05, + NM_WSBH =3D 0x3d, +}; + +/* PP.SR instruction pool */ +enum { + NM_SAVE =3D 0x00, + NM_RESTORE =3D 0x02, + NM_RESTORE_JRC =3D 0x03, +}; + +/* P.SR.F instruction pool */ +enum { + NM_SAVEF =3D 0x00, + NM_RESTOREF =3D 0x01, +}; + +/* P16.SYSCALL instruction pool */ +enum { + NM_SYSCALL16 =3D 0x00, + NM_HYPCALL16 =3D 0x01, +}; + +/* POOL16C_00 instruction pool */ +enum { + NM_NOT16 =3D 0x00, + NM_XOR16 =3D 0x01, + NM_AND16 =3D 0x02, + NM_OR16 =3D 0x03, +}; + +/* PP.LSX and PP.LSXS instruction pool */ +enum { + NM_LBX =3D 0x00, + NM_LHX =3D 0x04, + NM_LWX =3D 0x08, + NM_LDX =3D 0x0c, + + NM_SBX =3D 0x01, + NM_SHX =3D 0x05, + NM_SWX =3D 0x09, + NM_SDX =3D 0x0d, + + NM_LBUX =3D 0x02, + NM_LHUX =3D 0x06, + NM_LWC1X =3D 0x0a, + NM_LDC1X =3D 0x0e, + + NM_LWUX =3D 0x07, + NM_SWC1X =3D 0x0b, + NM_SDC1X =3D 0x0f, + + NM_LHXS =3D 0x04, + NM_LWXS =3D 0x08, + NM_LDXS =3D 0x0c, + + NM_SHXS =3D 0x05, + NM_SWXS =3D 0x09, + NM_SDXS =3D 0x0d, + + NM_LHUXS =3D 0x06, + NM_LWC1XS =3D 0x0a, + NM_LDC1XS =3D 0x0e, + + NM_LWUXS =3D 0x07, + NM_SWC1XS =3D 0x0b, + NM_SDC1XS =3D 0x0f, +}; + +/* ERETx instruction pool */ +enum { + NM_ERET =3D 0x00, + NM_ERETNC =3D 0x01, +}; + +/* POOL32FxF_{0, 1} insturction pool */ +enum { + NM_CFC1 =3D 0x40, + NM_CTC1 =3D 0x60, + NM_MFC1 =3D 0x80, + NM_MTC1 =3D 0xa0, + NM_MFHC1 =3D 0xc0, + NM_MTHC1 =3D 0xe0, + + NM_CVT_S_PL =3D 0x84, + NM_CVT_S_PU =3D 0xa4, + + NM_CVT_L_S =3D 0x004, + NM_CVT_L_D =3D 0x104, + NM_CVT_W_S =3D 0x024, + NM_CVT_W_D =3D 0x124, + + NM_RSQRT_S =3D 0x008, + NM_RSQRT_D =3D 0x108, + + NM_SQRT_S =3D 0x028, + NM_SQRT_D =3D 0x128, + + NM_RECIP_S =3D 0x048, + NM_RECIP_D =3D 0x148, + + NM_FLOOR_L_S =3D 0x00c, + NM_FLOOR_L_D =3D 0x10c, + + NM_FLOOR_W_S =3D 0x02c, + NM_FLOOR_W_D =3D 0x12c, + + NM_CEIL_L_S =3D 0x04c, + NM_CEIL_L_D =3D 0x14c, + NM_CEIL_W_S =3D 0x06c, + NM_CEIL_W_D =3D 0x16c, + NM_TRUNC_L_S =3D 0x08c, + NM_TRUNC_L_D =3D 0x18c, + NM_TRUNC_W_S =3D 0x0ac, + NM_TRUNC_W_D =3D 0x1ac, + NM_ROUND_L_S =3D 0x0cc, + NM_ROUND_L_D =3D 0x1cc, + NM_ROUND_W_S =3D 0x0ec, + NM_ROUND_W_D =3D 0x1ec, + + NM_MOV_S =3D 0x01, + NM_MOV_D =3D 0x81, + NM_ABS_S =3D 0x0d, + NM_ABS_D =3D 0x8d, + NM_NEG_S =3D 0x2d, + NM_NEG_D =3D 0xad, + NM_CVT_D_S =3D 0x04d, + NM_CVT_D_W =3D 0x0cd, + NM_CVT_D_L =3D 0x14d, + NM_CVT_S_D =3D 0x06d, + NM_CVT_S_W =3D 0x0ed, + NM_CVT_S_L =3D 0x16d, +}; + +/* P.LL instruction pool */ +enum { + NM_LL =3D 0x00, + NM_LLWP =3D 0x01, +}; + +/* P.SC instruction pool */ +enum { + NM_SC =3D 0x00, + NM_SCWP =3D 0x01, +}; + +/* P.DVP instruction pool */ +enum { + NM_DVP =3D 0x00, + NM_EVP =3D 0x01, +}; + + +/* + * + * nanoMIPS decoding engine + * + */ + + +/* extraction utilities */ + +#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7) +#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7) +#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7) +#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f) +#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f) + +/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */ +static inline int decode_gpr_gpr3(int r) +{ + static const int map[] =3D { 16, 17, 18, 19, 4, 5, 6, 7 }; + + return map[r & 0x7]; +} + +/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store')= . */ +static inline int decode_gpr_gpr3_src_store(int r) +{ + static const int map[] =3D { 0, 17, 18, 19, 4, 5, 6, 7 }; + + return map[r & 0x7]; +} + +/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */ +static inline int decode_gpr_gpr4(int r) +{ + static const int map[] =3D { 8, 9, 10, 11, 4, 5, 6, 7, + 16, 17, 18, 19, 20, 21, 22, 23 }; + + return map[r & 0xf]; +} + +/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */ +static inline int decode_gpr_gpr4_zero(int r) +{ + static const int map[] =3D { 8, 9, 10, 0, 4, 5, 6, 7, + 16, 17, 18, 19, 20, 21, 22, 23 }; + + return map[r & 0xf]; +} + + +static void gen_adjust_sp(DisasContext *ctx, int u) +{ + gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u); +} + +static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count, + uint8_t gp, uint16_t u) +{ + int counter =3D 0; + TCGv va =3D tcg_temp_new(); + TCGv t0 =3D tcg_temp_new(); + + while (counter !=3D count) { + bool use_gp =3D gp && (counter =3D=3D count - 1); + int this_rt =3D use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f= ); + int this_offset =3D -((counter + 1) << 2); + gen_base_offset_addr(ctx, va, 29, this_offset); + gen_load_gpr(t0, this_rt); + tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx, + (MO_TEUL | ctx->default_tcg_memop_mask)); + counter++; + } + + /* adjust stack pointer */ + gen_adjust_sp(ctx, -u); + + tcg_temp_free(t0); + tcg_temp_free(va); +} + +static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count, + uint8_t gp, uint16_t u) +{ + int counter =3D 0; + TCGv va =3D tcg_temp_new(); + TCGv t0 =3D tcg_temp_new(); + + while (counter !=3D count) { + bool use_gp =3D gp && (counter =3D=3D count - 1); + int this_rt =3D use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f= ); + int this_offset =3D u - ((counter + 1) << 2); + gen_base_offset_addr(ctx, va, 29, this_offset); + tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL | + ctx->default_tcg_memop_mask); + tcg_gen_ext32s_tl(t0, t0); + gen_store_gpr(t0, this_rt); + counter++; + } + + /* adjust stack pointer */ + gen_adjust_sp(ctx, u); + + tcg_temp_free(t0); + tcg_temp_free(va); +} + +static void gen_pool16c_nanomips_insn(DisasContext *ctx) +{ + int rt =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode)); + int rs =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); + + switch (extract32(ctx->opcode, 2, 2)) { + case NM_NOT16: + gen_logic(ctx, OPC_NOR, rt, rs, 0); + break; + case NM_AND16: + gen_logic(ctx, OPC_AND, rt, rt, rs); + break; + case NM_XOR16: + gen_logic(ctx, OPC_XOR, rt, rt, rs); + break; + case NM_OR16: + gen_logic(ctx, OPC_OR, rt, rt, rs); + break; + } +} + +static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ct= x) +{ + int rt =3D extract32(ctx->opcode, 21, 5); + int rs =3D extract32(ctx->opcode, 16, 5); + int rd =3D extract32(ctx->opcode, 11, 5); + + switch (extract32(ctx->opcode, 3, 7)) { + case NM_P_TRAP: + switch (extract32(ctx->opcode, 10, 1)) { + case NM_TEQ: + check_nms(ctx); + gen_trap(ctx, OPC_TEQ, rs, rt, -1); + break; + case NM_TNE: + check_nms(ctx); + gen_trap(ctx, OPC_TNE, rs, rt, -1); + break; + } + break; + case NM_RDHWR: + check_nms(ctx); + gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3)); + break; + case NM_SEB: + check_nms(ctx); + gen_bshfl(ctx, OPC_SEB, rs, rt); + break; + case NM_SEH: + gen_bshfl(ctx, OPC_SEH, rs, rt); + break; + case NM_SLLV: + gen_shift(ctx, OPC_SLLV, rd, rt, rs); + break; + case NM_SRLV: + gen_shift(ctx, OPC_SRLV, rd, rt, rs); + break; + case NM_SRAV: + gen_shift(ctx, OPC_SRAV, rd, rt, rs); + break; + case NM_ROTRV: + gen_shift(ctx, OPC_ROTRV, rd, rt, rs); + break; + case NM_ADD: + gen_arith(ctx, OPC_ADD, rd, rs, rt); + break; + case NM_ADDU: + gen_arith(ctx, OPC_ADDU, rd, rs, rt); + break; + case NM_SUB: + check_nms(ctx); + gen_arith(ctx, OPC_SUB, rd, rs, rt); + break; + case NM_SUBU: + gen_arith(ctx, OPC_SUBU, rd, rs, rt); + break; + case NM_P_CMOVE: + switch (extract32(ctx->opcode, 10, 1)) { + case NM_MOVZ: + gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt); + break; + case NM_MOVN: + gen_cond_move(ctx, OPC_MOVN, rd, rs, rt); + break; + } + break; + case NM_AND: + gen_logic(ctx, OPC_AND, rd, rs, rt); + break; + case NM_OR: + gen_logic(ctx, OPC_OR, rd, rs, rt); + break; + case NM_NOR: + gen_logic(ctx, OPC_NOR, rd, rs, rt); + break; + case NM_XOR: + gen_logic(ctx, OPC_XOR, rd, rs, rt); + break; + case NM_SLT: + gen_slt(ctx, OPC_SLT, rd, rs, rt); + break; + case NM_P_SLTU: + if (rd =3D=3D 0) { + /* P_DVP */ +#ifndef CONFIG_USER_ONLY + TCGv t0 =3D tcg_temp_new(); + switch (extract32(ctx->opcode, 10, 1)) { + case NM_DVP: + if (ctx->vp) { + check_cp0_enabled(ctx); + gen_helper_dvp(t0, cpu_env); + gen_store_gpr(t0, rt); + } + break; + case NM_EVP: + if (ctx->vp) { + check_cp0_enabled(ctx); + gen_helper_evp(t0, cpu_env); + gen_store_gpr(t0, rt); + } + break; + } + tcg_temp_free(t0); +#endif + } else { + gen_slt(ctx, OPC_SLTU, rd, rs, rt); + } + break; + case NM_SOV: + { + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + TCGv t2 =3D tcg_temp_new(); + + gen_load_gpr(t1, rs); + gen_load_gpr(t2, rt); + tcg_gen_add_tl(t0, t1, t2); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_xor_tl(t1, t1, t2); + tcg_gen_xor_tl(t2, t0, t2); + tcg_gen_andc_tl(t1, t2, t1); + + /* operands of same sign, result different sign */ + tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0); + gen_store_gpr(t0, rd); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); + } + break; + case NM_MUL: + gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt); + break; + case NM_MUH: + gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt); + break; + case NM_MULU: + gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt); + break; + case NM_MUHU: + gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt); + break; + case NM_DIV: + gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt); + break; + case NM_MOD: + gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt); + break; + case NM_DIVU: + gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt); + break; + case NM_MODU: + gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt); + break; +#ifndef CONFIG_USER_ONLY + case NM_MFC0: + check_cp0_enabled(ctx); + if (rt =3D=3D 0) { + /* Treat as NOP. */ + break; + } + gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3)); + break; + case NM_MTC0: + check_cp0_enabled(ctx); + { + TCGv t0 =3D tcg_temp_new(); + + gen_load_gpr(t0, rt); + gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3)); + tcg_temp_free(t0); + } + break; + case NM_D_E_MT_VPE: + { + uint8_t sc =3D extract32(ctx->opcode, 10, 1); + TCGv t0 =3D tcg_temp_new(); + + switch (sc) { + case 0: + if (rs =3D=3D 1) { + /* DMT */ + check_cp0_mt(ctx); + gen_helper_dmt(t0); + gen_store_gpr(t0, rt); + } else if (rs =3D=3D 0) { + /* DVPE */ + check_cp0_mt(ctx); + gen_helper_dvpe(t0, cpu_env); + gen_store_gpr(t0, rt); + } else { + generate_exception_end(ctx, EXCP_RI); + } + break; + case 1: + if (rs =3D=3D 1) { + /* EMT */ + check_cp0_mt(ctx); + gen_helper_emt(t0); + gen_store_gpr(t0, rt); + } else if (rs =3D=3D 0) { + /* EVPE */ + check_cp0_mt(ctx); + gen_helper_evpe(t0, cpu_env); + gen_store_gpr(t0, rt); + } else { + generate_exception_end(ctx, EXCP_RI); + } + break; + } + + tcg_temp_free(t0); + } + break; + case NM_FORK: + check_mt(ctx); + { + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + + gen_load_gpr(t0, rt); + gen_load_gpr(t1, rs); + gen_helper_fork(t0, t1); + tcg_temp_free(t0); + tcg_temp_free(t1); + } + break; + case NM_MFTR: + case NM_MFHTR: + check_cp0_enabled(ctx); + if (rd =3D=3D 0) { + /* Treat as NOP. */ + return; + } + gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1), + extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, = 1)); + break; + case NM_MTTR: + case NM_MTHTR: + check_cp0_enabled(ctx); + gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1), + extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, = 1)); + break; + case NM_YIELD: + check_mt(ctx); + { + TCGv t0 =3D tcg_temp_new(); + + gen_load_gpr(t0, rs); + gen_helper_yield(t0, cpu_env, t0); + gen_store_gpr(t0, rt); + tcg_temp_free(t0); + } + break; +#endif + default: + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* dsp */ +static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t op= c, + int ret, int v1, int v2) +{ + TCGv_i32 t0; + TCGv v0_t; + TCGv v1_t; + + t0 =3D tcg_temp_new_i32(); + + v0_t =3D tcg_temp_new(); + v1_t =3D tcg_temp_new(); + + tcg_gen_movi_i32(t0, v2 >> 3); + + gen_load_gpr(v0_t, ret); + gen_load_gpr(v1_t, v1); + + switch (opc) { + case NM_MAQ_S_W_PHR: + check_dsp(ctx); + gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env); + break; + case NM_MAQ_S_W_PHL: + check_dsp(ctx); + gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env); + break; + case NM_MAQ_SA_W_PHR: + check_dsp(ctx); + gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env); + break; + case NM_MAQ_SA_W_PHL: + check_dsp(ctx); + gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free_i32(t0); + + tcg_temp_free(v0_t); + tcg_temp_free(v1_t); +} + + +static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc, + int ret, int v1, int v2) +{ + int16_t imm; + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + TCGv v0_t =3D tcg_temp_new(); + + gen_load_gpr(v0_t, v1); + + switch (opc) { + case NM_POOL32AXF_1_0: + check_dsp(ctx); + switch (extract32(ctx->opcode, 12, 2)) { + case NM_MFHI: + gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret); + break; + case NM_MFLO: + gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret); + break; + case NM_MTHI: + gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1); + break; + case NM_MTLO: + gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1); + break; + } + break; + case NM_POOL32AXF_1_1: + check_dsp(ctx); + switch (extract32(ctx->opcode, 12, 2)) { + case NM_MTHLIP: + tcg_gen_movi_tl(t0, v2); + gen_helper_mthlip(t0, v0_t, cpu_env); + break; + case NM_SHILOV: + tcg_gen_movi_tl(t0, v2 >> 3); + gen_helper_shilo(t0, v0_t, cpu_env); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_POOL32AXF_1_3: + check_dsp(ctx); + imm =3D extract32(ctx->opcode, 14, 7); + switch (extract32(ctx->opcode, 12, 2)) { + case NM_RDDSP: + tcg_gen_movi_tl(t0, imm); + gen_helper_rddsp(t0, t0, cpu_env); + gen_store_gpr(t0, ret); + break; + case NM_WRDSP: + gen_load_gpr(t0, ret); + tcg_gen_movi_tl(t1, imm); + gen_helper_wrdsp(t0, t1, cpu_env); + break; + case NM_EXTP: + tcg_gen_movi_tl(t0, v2 >> 3); + tcg_gen_movi_tl(t1, v1); + gen_helper_extp(t0, t0, t1, cpu_env); + gen_store_gpr(t0, ret); + break; + case NM_EXTPDP: + tcg_gen_movi_tl(t0, v2 >> 3); + tcg_gen_movi_tl(t1, v1); + gen_helper_extpdp(t0, t0, t1, cpu_env); + gen_store_gpr(t0, ret); + break; + } + break; + case NM_POOL32AXF_1_4: + check_dsp(ctx); + tcg_gen_movi_tl(t0, v2 >> 2); + switch (extract32(ctx->opcode, 12, 1)) { + case NM_SHLL_QB: + gen_helper_shll_qb(t0, t0, v0_t, cpu_env); + gen_store_gpr(t0, ret); + break; + case NM_SHRL_QB: + gen_helper_shrl_qb(t0, t0, v0_t); + gen_store_gpr(t0, ret); + break; + } + break; + case NM_POOL32AXF_1_5: + opc =3D extract32(ctx->opcode, 12, 2); + gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2); + break; + case NM_POOL32AXF_1_7: + check_dsp(ctx); + tcg_gen_movi_tl(t0, v2 >> 3); + tcg_gen_movi_tl(t1, v1); + switch (extract32(ctx->opcode, 12, 2)) { + case NM_EXTR_W: + gen_helper_extr_w(t0, t0, t1, cpu_env); + gen_store_gpr(t0, ret); + break; + case NM_EXTR_R_W: + gen_helper_extr_r_w(t0, t0, t1, cpu_env); + gen_store_gpr(t0, ret); + break; + case NM_EXTR_RS_W: + gen_helper_extr_rs_w(t0, t0, t1, cpu_env); + gen_store_gpr(t0, ret); + break; + case NM_EXTR_S_H: + gen_helper_extr_s_h(t0, t0, t1, cpu_env); + gen_store_gpr(t0, ret); + break; + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(v0_t); +} + +static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc, + TCGv v0, TCGv v1, int rd) +{ + TCGv_i32 t0; + + t0 =3D tcg_temp_new_i32(); + + tcg_gen_movi_i32(t0, rd >> 3); + + switch (opc) { + case NM_POOL32AXF_2_0_7: + switch (extract32(ctx->opcode, 9, 3)) { + case NM_DPA_W_PH: + check_dsp_r2(ctx); + gen_helper_dpa_w_ph(t0, v1, v0, cpu_env); + break; + case NM_DPAQ_S_W_PH: + check_dsp(ctx); + gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env); + break; + case NM_DPS_W_PH: + check_dsp_r2(ctx); + gen_helper_dps_w_ph(t0, v1, v0, cpu_env); + break; + case NM_DPSQ_S_W_PH: + check_dsp(ctx); + gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_POOL32AXF_2_8_15: + switch (extract32(ctx->opcode, 9, 3)) { + case NM_DPAX_W_PH: + check_dsp_r2(ctx); + gen_helper_dpax_w_ph(t0, v0, v1, cpu_env); + break; + case NM_DPAQ_SA_L_W: + check_dsp(ctx); + gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env); + break; + case NM_DPSX_W_PH: + check_dsp_r2(ctx); + gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env); + break; + case NM_DPSQ_SA_L_W: + check_dsp(ctx); + gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_POOL32AXF_2_16_23: + switch (extract32(ctx->opcode, 9, 3)) { + case NM_DPAU_H_QBL: + check_dsp(ctx); + gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env); + break; + case NM_DPAQX_S_W_PH: + check_dsp_r2(ctx); + gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env); + break; + case NM_DPSU_H_QBL: + check_dsp(ctx); + gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env); + break; + case NM_DPSQX_S_W_PH: + check_dsp_r2(ctx); + gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env); + break; + case NM_MULSA_W_PH: + check_dsp_r2(ctx); + gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_POOL32AXF_2_24_31: + switch (extract32(ctx->opcode, 9, 3)) { + case NM_DPAU_H_QBR: + check_dsp(ctx); + gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env); + break; + case NM_DPAQX_SA_W_PH: + check_dsp_r2(ctx); + gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env); + break; + case NM_DPSU_H_QBR: + check_dsp(ctx); + gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env); + break; + case NM_DPSQX_SA_W_PH: + check_dsp_r2(ctx); + gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env); + break; + case NM_MULSAQ_S_W_PH: + check_dsp(ctx); + gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free_i32(t0); +} + +static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc, + int rt, int rs, int rd) +{ + int ret =3D rt; + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + TCGv v0_t =3D tcg_temp_new(); + TCGv v1_t =3D tcg_temp_new(); + + gen_load_gpr(v0_t, rt); + gen_load_gpr(v1_t, rs); + + switch (opc) { + case NM_POOL32AXF_2_0_7: + switch (extract32(ctx->opcode, 9, 3)) { + case NM_DPA_W_PH: + case NM_DPAQ_S_W_PH: + case NM_DPS_W_PH: + case NM_DPSQ_S_W_PH: + gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); + break; + case NM_BALIGN: + check_dsp_r2(ctx); + if (rt !=3D 0) { + gen_load_gpr(t0, rs); + rd &=3D 3; + if (rd !=3D 0 && rd !=3D 2) { + tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_shri_tl(t0, t0, 8 * (4 - rd)); + tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); + } + tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); + } + break; + case NM_MADD: + check_dsp(ctx); + { + int acc =3D extract32(ctx->opcode, 14, 2); + TCGv_i64 t2 =3D tcg_temp_new_i64(); + TCGv_i64 t3 =3D tcg_temp_new_i64(); + + gen_load_gpr(t0, rt); + gen_load_gpr(t1, rs); + tcg_gen_ext_tl_i64(t2, t0); + tcg_gen_ext_tl_i64(t3, t1); + tcg_gen_mul_i64(t2, t2, t3); + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); + tcg_gen_add_i64(t2, t2, t3); + tcg_temp_free_i64(t3); + gen_move_low32(cpu_LO[acc], t2); + gen_move_high32(cpu_HI[acc], t2); + tcg_temp_free_i64(t2); + } + break; + case NM_MULT: + check_dsp(ctx); + { + int acc =3D extract32(ctx->opcode, 14, 2); + TCGv_i32 t2 =3D tcg_temp_new_i32(); + TCGv_i32 t3 =3D tcg_temp_new_i32(); + + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + tcg_gen_trunc_tl_i32(t2, t0); + tcg_gen_trunc_tl_i32(t3, t1); + tcg_gen_muls2_i32(t2, t3, t2, t3); + tcg_gen_ext_i32_tl(cpu_LO[acc], t2); + tcg_gen_ext_i32_tl(cpu_HI[acc], t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t3); + } + break; + case NM_EXTRV_W: + check_dsp(ctx); + gen_load_gpr(v1_t, rs); + tcg_gen_movi_tl(t0, rd >> 3); + gen_helper_extr_w(t0, t0, v1_t, cpu_env); + gen_store_gpr(t0, ret); + break; + } + break; + case NM_POOL32AXF_2_8_15: + switch (extract32(ctx->opcode, 9, 3)) { + case NM_DPAX_W_PH: + case NM_DPAQ_SA_L_W: + case NM_DPSX_W_PH: + case NM_DPSQ_SA_L_W: + gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); + break; + case NM_MADDU: + check_dsp(ctx); + { + int acc =3D extract32(ctx->opcode, 14, 2); + TCGv_i64 t2 =3D tcg_temp_new_i64(); + TCGv_i64 t3 =3D tcg_temp_new_i64(); + + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_extu_tl_i64(t2, t0); + tcg_gen_extu_tl_i64(t3, t1); + tcg_gen_mul_i64(t2, t2, t3); + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); + tcg_gen_add_i64(t2, t2, t3); + tcg_temp_free_i64(t3); + gen_move_low32(cpu_LO[acc], t2); + gen_move_high32(cpu_HI[acc], t2); + tcg_temp_free_i64(t2); + } + break; + case NM_MULTU: + check_dsp(ctx); + { + int acc =3D extract32(ctx->opcode, 14, 2); + TCGv_i32 t2 =3D tcg_temp_new_i32(); + TCGv_i32 t3 =3D tcg_temp_new_i32(); + + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + tcg_gen_trunc_tl_i32(t2, t0); + tcg_gen_trunc_tl_i32(t3, t1); + tcg_gen_mulu2_i32(t2, t3, t2, t3); + tcg_gen_ext_i32_tl(cpu_LO[acc], t2); + tcg_gen_ext_i32_tl(cpu_HI[acc], t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t3); + } + break; + case NM_EXTRV_R_W: + check_dsp(ctx); + tcg_gen_movi_tl(t0, rd >> 3); + gen_helper_extr_r_w(t0, t0, v1_t, cpu_env); + gen_store_gpr(t0, ret); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_POOL32AXF_2_16_23: + switch (extract32(ctx->opcode, 9, 3)) { + case NM_DPAU_H_QBL: + case NM_DPAQX_S_W_PH: + case NM_DPSU_H_QBL: + case NM_DPSQX_S_W_PH: + case NM_MULSA_W_PH: + gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); + break; + case NM_EXTPV: + check_dsp(ctx); + tcg_gen_movi_tl(t0, rd >> 3); + gen_helper_extp(t0, t0, v1_t, cpu_env); + gen_store_gpr(t0, ret); + break; + case NM_MSUB: + check_dsp(ctx); + { + int acc =3D extract32(ctx->opcode, 14, 2); + TCGv_i64 t2 =3D tcg_temp_new_i64(); + TCGv_i64 t3 =3D tcg_temp_new_i64(); + + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + tcg_gen_ext_tl_i64(t2, t0); + tcg_gen_ext_tl_i64(t3, t1); + tcg_gen_mul_i64(t2, t2, t3); + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); + tcg_gen_sub_i64(t2, t3, t2); + tcg_temp_free_i64(t3); + gen_move_low32(cpu_LO[acc], t2); + gen_move_high32(cpu_HI[acc], t2); + tcg_temp_free_i64(t2); + } + break; + case NM_EXTRV_RS_W: + check_dsp(ctx); + tcg_gen_movi_tl(t0, rd >> 3); + gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env); + gen_store_gpr(t0, ret); + break; + } + break; + case NM_POOL32AXF_2_24_31: + switch (extract32(ctx->opcode, 9, 3)) { + case NM_DPAU_H_QBR: + case NM_DPAQX_SA_W_PH: + case NM_DPSU_H_QBR: + case NM_DPSQX_SA_W_PH: + case NM_MULSAQ_S_W_PH: + gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); + break; + case NM_EXTPDPV: + check_dsp(ctx); + tcg_gen_movi_tl(t0, rd >> 3); + gen_helper_extpdp(t0, t0, v1_t, cpu_env); + gen_store_gpr(t0, ret); + break; + case NM_MSUBU: + check_dsp(ctx); + { + int acc =3D extract32(ctx->opcode, 14, 2); + TCGv_i64 t2 =3D tcg_temp_new_i64(); + TCGv_i64 t3 =3D tcg_temp_new_i64(); + + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_extu_tl_i64(t2, t0); + tcg_gen_extu_tl_i64(t3, t1); + tcg_gen_mul_i64(t2, t2, t3); + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); + tcg_gen_sub_i64(t2, t3, t2); + tcg_temp_free_i64(t3); + gen_move_low32(cpu_LO[acc], t2); + gen_move_high32(cpu_HI[acc], t2); + tcg_temp_free_i64(t2); + } + break; + case NM_EXTRV_S_H: + check_dsp(ctx); + tcg_gen_movi_tl(t0, rd >> 3); + gen_helper_extr_s_h(t0, t0, v0_t, cpu_env); + gen_store_gpr(t0, ret); + break; + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free(t0); + tcg_temp_free(t1); + + tcg_temp_free(v0_t); + tcg_temp_free(v1_t); +} + +static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc, + int rt, int rs) +{ + int ret =3D rt; + TCGv t0 =3D tcg_temp_new(); + TCGv v0_t =3D tcg_temp_new(); + + gen_load_gpr(v0_t, rs); + + switch (opc) { + case NM_ABSQ_S_QB: + check_dsp_r2(ctx); + gen_helper_absq_s_qb(v0_t, v0_t, cpu_env); + gen_store_gpr(v0_t, ret); + break; + case NM_ABSQ_S_PH: + check_dsp(ctx); + gen_helper_absq_s_ph(v0_t, v0_t, cpu_env); + gen_store_gpr(v0_t, ret); + break; + case NM_ABSQ_S_W: + check_dsp(ctx); + gen_helper_absq_s_w(v0_t, v0_t, cpu_env); + gen_store_gpr(v0_t, ret); + break; + case NM_PRECEQ_W_PHL: + check_dsp(ctx); + tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000); + tcg_gen_ext32s_tl(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_PRECEQ_W_PHR: + check_dsp(ctx); + tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF); + tcg_gen_shli_tl(v0_t, v0_t, 16); + tcg_gen_ext32s_tl(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_PRECEQU_PH_QBL: + check_dsp(ctx); + gen_helper_precequ_ph_qbl(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_PRECEQU_PH_QBR: + check_dsp(ctx); + gen_helper_precequ_ph_qbr(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_PRECEQU_PH_QBLA: + check_dsp(ctx); + gen_helper_precequ_ph_qbla(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_PRECEQU_PH_QBRA: + check_dsp(ctx); + gen_helper_precequ_ph_qbra(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_PRECEU_PH_QBL: + check_dsp(ctx); + gen_helper_preceu_ph_qbl(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_PRECEU_PH_QBR: + check_dsp(ctx); + gen_helper_preceu_ph_qbr(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_PRECEU_PH_QBLA: + check_dsp(ctx); + gen_helper_preceu_ph_qbla(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_PRECEU_PH_QBRA: + check_dsp(ctx); + gen_helper_preceu_ph_qbra(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_REPLV_PH: + check_dsp(ctx); + tcg_gen_ext16u_tl(v0_t, v0_t); + tcg_gen_shli_tl(t0, v0_t, 16); + tcg_gen_or_tl(v0_t, v0_t, t0); + tcg_gen_ext32s_tl(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_REPLV_QB: + check_dsp(ctx); + tcg_gen_ext8u_tl(v0_t, v0_t); + tcg_gen_shli_tl(t0, v0_t, 8); + tcg_gen_or_tl(v0_t, v0_t, t0); + tcg_gen_shli_tl(t0, v0_t, 16); + tcg_gen_or_tl(v0_t, v0_t, t0); + tcg_gen_ext32s_tl(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_BITREV: + check_dsp(ctx); + gen_helper_bitrev(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_INSV: + check_dsp(ctx); + { + TCGv tv0 =3D tcg_temp_new(); + + gen_load_gpr(tv0, rt); + gen_helper_insv(v0_t, cpu_env, v0_t, tv0); + gen_store_gpr(v0_t, ret); + tcg_temp_free(tv0); + } + break; + case NM_RADDU_W_QB: + check_dsp(ctx); + gen_helper_raddu_w_qb(v0_t, v0_t); + gen_store_gpr(v0_t, ret); + break; + case NM_BITSWAP: + gen_bitswap(ctx, OPC_BITSWAP, ret, rs); + break; + case NM_CLO: + check_nms(ctx); + gen_cl(ctx, OPC_CLO, ret, rs); + break; + case NM_CLZ: + check_nms(ctx); + gen_cl(ctx, OPC_CLZ, ret, rs); + break; + case NM_WSBH: + gen_bshfl(ctx, OPC_WSBH, ret, rs); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free(v0_t); + tcg_temp_free(t0); +} + +static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc, + int rt, int rs, int rd) +{ + TCGv t0 =3D tcg_temp_new(); + TCGv rs_t =3D tcg_temp_new(); + + gen_load_gpr(rs_t, rs); + + switch (opc) { + case NM_SHRA_R_QB: + check_dsp_r2(ctx); + tcg_gen_movi_tl(t0, rd >> 2); + switch (extract32(ctx->opcode, 12, 1)) { + case 0: + /* NM_SHRA_QB */ + gen_helper_shra_qb(t0, t0, rs_t); + gen_store_gpr(t0, rt); + break; + case 1: + /* NM_SHRA_R_QB */ + gen_helper_shra_r_qb(t0, t0, rs_t); + gen_store_gpr(t0, rt); + break; + } + break; + case NM_SHRL_PH: + check_dsp_r2(ctx); + tcg_gen_movi_tl(t0, rd >> 1); + gen_helper_shrl_ph(t0, t0, rs_t); + gen_store_gpr(t0, rt); + break; + case NM_REPL_QB: + check_dsp(ctx); + { + int16_t imm; + target_long result; + imm =3D extract32(ctx->opcode, 13, 8); + result =3D (uint32_t)imm << 24 | + (uint32_t)imm << 16 | + (uint32_t)imm << 8 | + (uint32_t)imm; + result =3D (int32_t)result; + tcg_gen_movi_tl(t0, result); + gen_store_gpr(t0, rt); + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + tcg_temp_free(t0); + tcg_temp_free(rs_t); +} + + +static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *c= tx) +{ + int rt =3D extract32(ctx->opcode, 21, 5); + int rs =3D extract32(ctx->opcode, 16, 5); + int rd =3D extract32(ctx->opcode, 11, 5); + + switch (extract32(ctx->opcode, 6, 3)) { + case NM_POOL32AXF_1: + { + int32_t op1 =3D extract32(ctx->opcode, 9, 3); + gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd); + } + break; + case NM_POOL32AXF_2: + { + int32_t op1 =3D extract32(ctx->opcode, 12, 2); + gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd); + } + break; + case NM_POOL32AXF_4: + { + int32_t op1 =3D extract32(ctx->opcode, 9, 7); + gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs); + } + break; + case NM_POOL32AXF_5: + switch (extract32(ctx->opcode, 9, 7)) { +#ifndef CONFIG_USER_ONLY + case NM_TLBP: + gen_cp0(env, ctx, OPC_TLBP, 0, 0); + break; + case NM_TLBR: + gen_cp0(env, ctx, OPC_TLBR, 0, 0); + break; + case NM_TLBWI: + gen_cp0(env, ctx, OPC_TLBWI, 0, 0); + break; + case NM_TLBWR: + gen_cp0(env, ctx, OPC_TLBWR, 0, 0); + break; + case NM_TLBINV: + gen_cp0(env, ctx, OPC_TLBINV, 0, 0); + break; + case NM_TLBINVF: + gen_cp0(env, ctx, OPC_TLBINVF, 0, 0); + break; + case NM_DI: + check_cp0_enabled(ctx); + { + TCGv t0 =3D tcg_temp_new(); + + save_cpu_state(ctx, 1); + gen_helper_di(t0, cpu_env); + gen_store_gpr(t0, rt); + /* Stop translation as we may have switched the execution mode= */ + ctx->base.is_jmp =3D DISAS_STOP; + tcg_temp_free(t0); + } + break; + case NM_EI: + check_cp0_enabled(ctx); + { + TCGv t0 =3D tcg_temp_new(); + + save_cpu_state(ctx, 1); + gen_helper_ei(t0, cpu_env); + gen_store_gpr(t0, rt); + /* Stop translation as we may have switched the execution mode= */ + ctx->base.is_jmp =3D DISAS_STOP; + tcg_temp_free(t0); + } + break; + case NM_RDPGPR: + gen_load_srsgpr(rs, rt); + break; + case NM_WRPGPR: + gen_store_srsgpr(rs, rt); + break; + case NM_WAIT: + gen_cp0(env, ctx, OPC_WAIT, 0, 0); + break; + case NM_DERET: + gen_cp0(env, ctx, OPC_DERET, 0, 0); + break; + case NM_ERETX: + gen_cp0(env, ctx, OPC_ERET, 0, 0); + break; +#endif + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_POOL32AXF_7: + { + int32_t op1 =3D extract32(ctx->opcode, 9, 3); + gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd); + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* nanoMIPS Branches */ +static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc, + int insn_bytes, + int rs, int rt, int32_t offset) +{ + target_ulong btgt =3D -1; + int bcond_compute =3D 0; + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + + /* Load needed operands */ + switch (opc) { + case OPC_BEQ: + case OPC_BNE: + /* Compare two registers */ + if (rs !=3D rt) { + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + bcond_compute =3D 1; + } + btgt =3D ctx->base.pc_next + insn_bytes + offset; + break; + case OPC_BGEZAL: + /* Compare to zero */ + if (rs !=3D 0) { + gen_load_gpr(t0, rs); + bcond_compute =3D 1; + } + btgt =3D ctx->base.pc_next + insn_bytes + offset; + break; + case OPC_BPOSGE32: + tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); + bcond_compute =3D 1; + btgt =3D ctx->base.pc_next + insn_bytes + offset; + break; + case OPC_JR: + case OPC_JALR: + /* Jump to register */ + if (offset !=3D 0 && offset !=3D 16) { + /* + * Hint =3D 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the + * others are reserved. + */ + MIPS_INVAL("jump hint"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + gen_load_gpr(btarget, rs); + break; + default: + MIPS_INVAL("branch/jump"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + if (bcond_compute =3D=3D 0) { + /* No condition to be computed */ + switch (opc) { + case OPC_BEQ: /* rx =3D=3D rx */ + /* Always take */ + ctx->hflags |=3D MIPS_HFLAG_B; + break; + case OPC_BGEZAL: /* 0 >=3D 0 */ + /* Always take and link */ + tcg_gen_movi_tl(cpu_gpr[31], + ctx->base.pc_next + insn_bytes); + ctx->hflags |=3D MIPS_HFLAG_B; + break; + case OPC_BNE: /* rx !=3D rx */ + tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); + /* Skip the instruction in the delay slot */ + ctx->base.pc_next +=3D 4; + goto out; + case OPC_JR: + ctx->hflags |=3D MIPS_HFLAG_BR; + break; + case OPC_JALR: + if (rt > 0) { + tcg_gen_movi_tl(cpu_gpr[rt], + ctx->base.pc_next + insn_bytes); + } + ctx->hflags |=3D MIPS_HFLAG_BR; + break; + default: + MIPS_INVAL("branch/jump"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + } else { + switch (opc) { + case OPC_BEQ: + tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); + goto not_likely; + case OPC_BNE: + tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); + goto not_likely; + case OPC_BGEZAL: + tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); + tcg_gen_movi_tl(cpu_gpr[31], + ctx->base.pc_next + insn_bytes); + goto not_likely; + case OPC_BPOSGE32: + tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); + not_likely: + ctx->hflags |=3D MIPS_HFLAG_BC; + break; + default: + MIPS_INVAL("conditional branch/jump"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + } + + ctx->btarget =3D btgt; + + out: + if (insn_bytes =3D=3D 2) { + ctx->hflags |=3D MIPS_HFLAG_B16; + } + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +/* Immediate Value Compact Branches */ +static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc, + int rt, int32_t imm, int32_t offset) +{ + TCGCond cond =3D TCG_COND_ALWAYS; + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + + gen_load_gpr(t0, rt); + tcg_gen_movi_tl(t1, imm); + ctx->btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); + + /* Load needed operands and calculate btarget */ + switch (opc) { + case NM_BEQIC: + if (rt =3D=3D 0 && imm =3D=3D 0) { + /* Unconditional branch */ + } else if (rt =3D=3D 0 && imm !=3D 0) { + /* Treat as NOP */ + goto out; + } else { + cond =3D TCG_COND_EQ; + } + break; + case NM_BBEQZC: + case NM_BBNEZC: + check_nms(ctx); + if (imm >=3D 32 && !(ctx->hflags & MIPS_HFLAG_64)) { + generate_exception_end(ctx, EXCP_RI); + goto out; + } else if (rt =3D=3D 0 && opc =3D=3D NM_BBEQZC) { + /* Unconditional branch */ + } else if (rt =3D=3D 0 && opc =3D=3D NM_BBNEZC) { + /* Treat as NOP */ + goto out; + } else { + tcg_gen_shri_tl(t0, t0, imm); + tcg_gen_andi_tl(t0, t0, 1); + tcg_gen_movi_tl(t1, 0); + if (opc =3D=3D NM_BBEQZC) { + cond =3D TCG_COND_EQ; + } else { + cond =3D TCG_COND_NE; + } + } + break; + case NM_BNEIC: + if (rt =3D=3D 0 && imm =3D=3D 0) { + /* Treat as NOP */ + goto out; + } else if (rt =3D=3D 0 && imm !=3D 0) { + /* Unconditional branch */ + } else { + cond =3D TCG_COND_NE; + } + break; + case NM_BGEIC: + if (rt =3D=3D 0 && imm =3D=3D 0) { + /* Unconditional branch */ + } else { + cond =3D TCG_COND_GE; + } + break; + case NM_BLTIC: + cond =3D TCG_COND_LT; + break; + case NM_BGEIUC: + if (rt =3D=3D 0 && imm =3D=3D 0) { + /* Unconditional branch */ + } else { + cond =3D TCG_COND_GEU; + } + break; + case NM_BLTIUC: + cond =3D TCG_COND_LTU; + break; + default: + MIPS_INVAL("Immediate Value Compact branch"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + + /* branch completion */ + clear_branch_hflags(ctx); + ctx->base.is_jmp =3D DISAS_NORETURN; + + if (cond =3D=3D TCG_COND_ALWAYS) { + /* Uncoditional compact branch */ + gen_goto_tb(ctx, 0, ctx->btarget); + } else { + /* Conditional compact branch */ + TCGLabel *fs =3D gen_new_label(); + + tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs); + + gen_goto_tb(ctx, 1, ctx->btarget); + gen_set_label(fs); + + gen_goto_tb(ctx, 0, ctx->base.pc_next + 4); + } + +out: + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */ +static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs, + int rt) +{ + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + + /* load rs */ + gen_load_gpr(t0, rs); + + /* link */ + if (rt !=3D 0) { + tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4); + } + + /* calculate btarget */ + tcg_gen_shli_tl(t0, t0, 1); + tcg_gen_movi_tl(t1, ctx->base.pc_next + 4); + gen_op_addr_add(ctx, btarget, t1, t0); + + /* branch completion */ + clear_branch_hflags(ctx); + ctx->base.is_jmp =3D DISAS_NORETURN; + + /* unconditional branch to register */ + tcg_gen_mov_tl(cpu_PC, btarget); + tcg_gen_lookup_and_goto_ptr(); + + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +/* nanoMIPS Branches */ +static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc, + int rs, int rt, int32_t offset) +{ + int bcond_compute =3D 0; + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + + /* Load needed operands and calculate btarget */ + switch (opc) { + /* compact branch */ + case OPC_BGEC: + case OPC_BLTC: + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + bcond_compute =3D 1; + ctx->btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); + break; + case OPC_BGEUC: + case OPC_BLTUC: + if (rs =3D=3D 0 || rs =3D=3D rt) { + /* OPC_BLEZALC, OPC_BGEZALC */ + /* OPC_BGTZALC, OPC_BLTZALC */ + tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4); + } + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + bcond_compute =3D 1; + ctx->btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); + break; + case OPC_BC: + ctx->btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); + break; + case OPC_BEQZC: + if (rs !=3D 0) { + /* OPC_BEQZC, OPC_BNEZC */ + gen_load_gpr(t0, rs); + bcond_compute =3D 1; + ctx->btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); + } else { + /* OPC_JIC, OPC_JIALC */ + TCGv tbase =3D tcg_temp_new(); + TCGv toffset =3D tcg_temp_new(); + + gen_load_gpr(tbase, rt); + tcg_gen_movi_tl(toffset, offset); + gen_op_addr_add(ctx, btarget, tbase, toffset); + tcg_temp_free(tbase); + tcg_temp_free(toffset); + } + break; + default: + MIPS_INVAL("Compact branch/jump"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + + if (bcond_compute =3D=3D 0) { + /* Uncoditional compact branch */ + switch (opc) { + case OPC_BC: + gen_goto_tb(ctx, 0, ctx->btarget); + break; + default: + MIPS_INVAL("Compact branch/jump"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + } else { + /* Conditional compact branch */ + TCGLabel *fs =3D gen_new_label(); + + switch (opc) { + case OPC_BGEUC: + if (rs =3D=3D 0 && rt !=3D 0) { + /* OPC_BLEZALC */ + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs= ); + } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { + /* OPC_BGEZALC */ + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs= ); + } else { + /* OPC_BGEUC */ + tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, f= s); + } + break; + case OPC_BLTUC: + if (rs =3D=3D 0 && rt !=3D 0) { + /* OPC_BGTZALC */ + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs= ); + } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { + /* OPC_BLTZALC */ + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs= ); + } else { + /* OPC_BLTUC */ + tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, f= s); + } + break; + case OPC_BGEC: + if (rs =3D=3D 0 && rt !=3D 0) { + /* OPC_BLEZC */ + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs= ); + } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { + /* OPC_BGEZC */ + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs= ); + } else { + /* OPC_BGEC */ + tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs= ); + } + break; + case OPC_BLTC: + if (rs =3D=3D 0 && rt !=3D 0) { + /* OPC_BGTZC */ + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs= ); + } else if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { + /* OPC_BLTZC */ + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs= ); + } else { + /* OPC_BLTC */ + tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs= ); + } + break; + case OPC_BEQZC: + tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); + break; + default: + MIPS_INVAL("Compact conditional branch/jump"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + + /* branch completion */ + clear_branch_hflags(ctx); + ctx->base.is_jmp =3D DISAS_NORETURN; + + /* Generating branch here as compact branches don't have delay slo= t */ + gen_goto_tb(ctx, 1, ctx->btarget); + gen_set_label(fs); + + gen_goto_tb(ctx, 0, ctx->base.pc_next + 4); + } + +out: + tcg_temp_free(t0); + tcg_temp_free(t1); +} + + +/* nanoMIPS CP1 Branches */ +static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op, + int32_t ft, int32_t offset) +{ + target_ulong btarget; + TCGv_i64 t0 =3D tcg_temp_new_i64(); + + gen_load_fpr64(ctx, t0, ft); + tcg_gen_andi_i64(t0, t0, 1); + + btarget =3D addr_add(ctx, ctx->base.pc_next + 4, offset); + + switch (op) { + case NM_BC1EQZC: + tcg_gen_xori_i64(t0, t0, 1); + ctx->hflags |=3D MIPS_HFLAG_BC; + break; + case NM_BC1NEZC: + /* t0 already set */ + ctx->hflags |=3D MIPS_HFLAG_BC; + break; + default: + MIPS_INVAL("cp1 cond branch"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + + tcg_gen_trunc_i64_tl(bcond, t0); + + ctx->btarget =3D btarget; + +out: + tcg_temp_free_i64(t0); +} + + +static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt) +{ + TCGv t0, t1; + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + + if ((extract32(ctx->opcode, 6, 1)) =3D=3D 1) { + /* PP.LSXS instructions require shifting */ + switch (extract32(ctx->opcode, 7, 4)) { + case NM_SHXS: + check_nms(ctx); + /* fall through */ + case NM_LHXS: + case NM_LHUXS: + tcg_gen_shli_tl(t0, t0, 1); + break; + case NM_SWXS: + check_nms(ctx); + /* fall through */ + case NM_LWXS: + case NM_LWC1XS: + case NM_SWC1XS: + tcg_gen_shli_tl(t0, t0, 2); + break; + case NM_LDC1XS: + case NM_SDC1XS: + tcg_gen_shli_tl(t0, t0, 3); + break; + } + } + gen_op_addr_add(ctx, t0, t0, t1); + + switch (extract32(ctx->opcode, 7, 4)) { + case NM_LBX: + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, + MO_SB); + gen_store_gpr(t0, rd); + break; + case NM_LHX: + /*case NM_LHXS:*/ + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, + MO_TESW); + gen_store_gpr(t0, rd); + break; + case NM_LWX: + /*case NM_LWXS:*/ + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, + MO_TESL); + gen_store_gpr(t0, rd); + break; + case NM_LBUX: + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, + MO_UB); + gen_store_gpr(t0, rd); + break; + case NM_LHUX: + /*case NM_LHUXS:*/ + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, + MO_TEUW); + gen_store_gpr(t0, rd); + break; + case NM_SBX: + check_nms(ctx); + gen_load_gpr(t1, rd); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, + MO_8); + break; + case NM_SHX: + /*case NM_SHXS:*/ + check_nms(ctx); + gen_load_gpr(t1, rd); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, + MO_TEUW); + break; + case NM_SWX: + /*case NM_SWXS:*/ + check_nms(ctx); + gen_load_gpr(t1, rd); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, + MO_TEUL); + break; + case NM_LWC1X: + /*case NM_LWC1XS:*/ + case NM_LDC1X: + /*case NM_LDC1XS:*/ + case NM_SWC1X: + /*case NM_SWC1XS:*/ + case NM_SDC1X: + /*case NM_SDC1XS:*/ + if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { + check_cp1_enabled(ctx); + switch (extract32(ctx->opcode, 7, 4)) { + case NM_LWC1X: + /*case NM_LWC1XS:*/ + gen_flt_ldst(ctx, OPC_LWC1, rd, t0); + break; + case NM_LDC1X: + /*case NM_LDC1XS:*/ + gen_flt_ldst(ctx, OPC_LDC1, rd, t0); + break; + case NM_SWC1X: + /*case NM_SWC1XS:*/ + gen_flt_ldst(ctx, OPC_SWC1, rd, t0); + break; + case NM_SDC1X: + /*case NM_SDC1XS:*/ + gen_flt_ldst(ctx, OPC_SDC1, rd, t0); + break; + } + } else { + generate_exception_err(ctx, EXCP_CpU, 1); + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +static void gen_pool32f_nanomips_insn(DisasContext *ctx) +{ + int rt, rs, rd; + + rt =3D extract32(ctx->opcode, 21, 5); + rs =3D extract32(ctx->opcode, 16, 5); + rd =3D extract32(ctx->opcode, 11, 5); + + if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) { + generate_exception_end(ctx, EXCP_RI); + return; + } + check_cp1_enabled(ctx); + switch (extract32(ctx->opcode, 0, 3)) { + case NM_POOL32F_0: + switch (extract32(ctx->opcode, 3, 7)) { + case NM_RINT_S: + gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0); + break; + case NM_RINT_D: + gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0); + break; + case NM_CLASS_S: + gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0); + break; + case NM_CLASS_D: + gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0); + break; + case NM_ADD_S: + gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0); + break; + case NM_ADD_D: + gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0); + break; + case NM_SUB_S: + gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0); + break; + case NM_SUB_D: + gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0); + break; + case NM_MUL_S: + gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0); + break; + case NM_MUL_D: + gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0); + break; + case NM_DIV_S: + gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0); + break; + case NM_DIV_D: + gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0); + break; + case NM_SELEQZ_S: + gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs); + break; + case NM_SELEQZ_D: + gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs); + break; + case NM_SELNEZ_S: + gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs); + break; + case NM_SELNEZ_D: + gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs); + break; + case NM_SEL_S: + gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); + break; + case NM_SEL_D: + gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs); + break; + case NM_MADDF_S: + gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0); + break; + case NM_MADDF_D: + gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0); + break; + case NM_MSUBF_S: + gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0); + break; + case NM_MSUBF_D: + gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_POOL32F_3: + switch (extract32(ctx->opcode, 3, 3)) { + case NM_MIN_FMT: + switch (extract32(ctx->opcode, 9, 1)) { + case FMT_SDPS_S: + gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); + break; + case FMT_SDPS_D: + gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0); + break; + } + break; + case NM_MAX_FMT: + switch (extract32(ctx->opcode, 9, 1)) { + case FMT_SDPS_S: + gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); + break; + case FMT_SDPS_D: + gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0); + break; + } + break; + case NM_MINA_FMT: + switch (extract32(ctx->opcode, 9, 1)) { + case FMT_SDPS_S: + gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); + break; + case FMT_SDPS_D: + gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0); + break; + } + break; + case NM_MAXA_FMT: + switch (extract32(ctx->opcode, 9, 1)) { + case FMT_SDPS_S: + gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); + break; + case FMT_SDPS_D: + gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0); + break; + } + break; + case NM_POOL32FXF: + switch (extract32(ctx->opcode, 6, 8)) { + case NM_CFC1: + gen_cp1(ctx, OPC_CFC1, rt, rs); + break; + case NM_CTC1: + gen_cp1(ctx, OPC_CTC1, rt, rs); + break; + case NM_MFC1: + gen_cp1(ctx, OPC_MFC1, rt, rs); + break; + case NM_MTC1: + gen_cp1(ctx, OPC_MTC1, rt, rs); + break; + case NM_MFHC1: + gen_cp1(ctx, OPC_MFHC1, rt, rs); + break; + case NM_MTHC1: + gen_cp1(ctx, OPC_MTHC1, rt, rs); + break; + case NM_CVT_S_PL: + gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0); + break; + case NM_CVT_S_PU: + gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0); + break; + default: + switch (extract32(ctx->opcode, 6, 9)) { + case NM_CVT_L_S: + gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0); + break; + case NM_CVT_L_D: + gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0); + break; + case NM_CVT_W_S: + gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0); + break; + case NM_CVT_W_D: + gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0); + break; + case NM_RSQRT_S: + gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0); + break; + case NM_RSQRT_D: + gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0); + break; + case NM_SQRT_S: + gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0); + break; + case NM_SQRT_D: + gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0); + break; + case NM_RECIP_S: + gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0); + break; + case NM_RECIP_D: + gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0); + break; + case NM_FLOOR_L_S: + gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0); + break; + case NM_FLOOR_L_D: + gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0); + break; + case NM_FLOOR_W_S: + gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0); + break; + case NM_FLOOR_W_D: + gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0); + break; + case NM_CEIL_L_S: + gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0); + break; + case NM_CEIL_L_D: + gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0); + break; + case NM_CEIL_W_S: + gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0); + break; + case NM_CEIL_W_D: + gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0); + break; + case NM_TRUNC_L_S: + gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0); + break; + case NM_TRUNC_L_D: + gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0); + break; + case NM_TRUNC_W_S: + gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0); + break; + case NM_TRUNC_W_D: + gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0); + break; + case NM_ROUND_L_S: + gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0); + break; + case NM_ROUND_L_D: + gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0); + break; + case NM_ROUND_W_S: + gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0); + break; + case NM_ROUND_W_D: + gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0); + break; + case NM_MOV_S: + gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0); + break; + case NM_MOV_D: + gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0); + break; + case NM_ABS_S: + gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0); + break; + case NM_ABS_D: + gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0); + break; + case NM_NEG_S: + gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0); + break; + case NM_NEG_D: + gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0); + break; + case NM_CVT_D_S: + gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0); + break; + case NM_CVT_D_W: + gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0); + break; + case NM_CVT_D_L: + gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0); + break; + case NM_CVT_S_D: + gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0); + break; + case NM_CVT_S_W: + gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0); + break; + case NM_CVT_S_L: + gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + } + break; + } + break; + case NM_POOL32F_5: + switch (extract32(ctx->opcode, 3, 3)) { + case NM_CMP_CONDN_S: + gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); + break; + case NM_CMP_CONDN_D: + gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc, + int rd, int rs, int rt) +{ + int ret =3D rd; + TCGv t0 =3D tcg_temp_new(); + TCGv v1_t =3D tcg_temp_new(); + TCGv v2_t =3D tcg_temp_new(); + + gen_load_gpr(v1_t, rs); + gen_load_gpr(v2_t, rt); + + switch (opc) { + case NM_CMP_EQ_PH: + check_dsp(ctx); + gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); + break; + case NM_CMP_LT_PH: + check_dsp(ctx); + gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); + break; + case NM_CMP_LE_PH: + check_dsp(ctx); + gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); + break; + case NM_CMPU_EQ_QB: + check_dsp(ctx); + gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); + break; + case NM_CMPU_LT_QB: + check_dsp(ctx); + gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); + break; + case NM_CMPU_LE_QB: + check_dsp(ctx); + gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); + break; + case NM_CMPGU_EQ_QB: + check_dsp(ctx); + gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_CMPGU_LT_QB: + check_dsp(ctx); + gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_CMPGU_LE_QB: + check_dsp(ctx); + gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_CMPGDU_EQ_QB: + check_dsp_r2(ctx); + gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); + tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); + gen_store_gpr(v1_t, ret); + break; + case NM_CMPGDU_LT_QB: + check_dsp_r2(ctx); + gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); + tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); + gen_store_gpr(v1_t, ret); + break; + case NM_CMPGDU_LE_QB: + check_dsp_r2(ctx); + gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); + tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); + gen_store_gpr(v1_t, ret); + break; + case NM_PACKRL_PH: + check_dsp(ctx); + gen_helper_packrl_ph(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_PICK_QB: + check_dsp(ctx); + gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_PICK_PH: + check_dsp(ctx); + gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_ADDQ_S_W: + check_dsp(ctx); + gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_SUBQ_S_W: + check_dsp(ctx); + gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_ADDSC: + check_dsp(ctx); + gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_ADDWC: + check_dsp(ctx); + gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_ADDQ_S_PH: + check_dsp(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* ADDQ_PH */ + gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* ADDQ_S_PH */ + gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_ADDQH_R_PH: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* ADDQH_PH */ + gen_helper_addqh_ph(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* ADDQH_R_PH */ + gen_helper_addqh_r_ph(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_ADDQH_R_W: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* ADDQH_W */ + gen_helper_addqh_w(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* ADDQH_R_W */ + gen_helper_addqh_r_w(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_ADDU_S_QB: + check_dsp(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* ADDU_QB */ + gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* ADDU_S_QB */ + gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_ADDU_S_PH: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* ADDU_PH */ + gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* ADDU_S_PH */ + gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_ADDUH_R_QB: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* ADDUH_QB */ + gen_helper_adduh_qb(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* ADDUH_R_QB */ + gen_helper_adduh_r_qb(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_SHRAV_R_PH: + check_dsp(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* SHRAV_PH */ + gen_helper_shra_ph(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* SHRAV_R_PH */ + gen_helper_shra_r_ph(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_SHRAV_R_QB: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* SHRAV_QB */ + gen_helper_shra_qb(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* SHRAV_R_QB */ + gen_helper_shra_r_qb(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_SUBQ_S_PH: + check_dsp(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* SUBQ_PH */ + gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* SUBQ_S_PH */ + gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_SUBQH_R_PH: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* SUBQH_PH */ + gen_helper_subqh_ph(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* SUBQH_R_PH */ + gen_helper_subqh_r_ph(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_SUBQH_R_W: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* SUBQH_W */ + gen_helper_subqh_w(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* SUBQH_R_W */ + gen_helper_subqh_r_w(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_SUBU_S_QB: + check_dsp(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* SUBU_QB */ + gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* SUBU_S_QB */ + gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_SUBU_S_PH: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* SUBU_PH */ + gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* SUBU_S_PH */ + gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_SUBUH_R_QB: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* SUBUH_QB */ + gen_helper_subuh_qb(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* SUBUH_R_QB */ + gen_helper_subuh_r_qb(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_SHLLV_S_PH: + check_dsp(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* SHLLV_PH */ + gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* SHLLV_S_PH */ + gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_PRECR_SRA_R_PH_W: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* PRECR_SRA_PH_W */ + { + TCGv_i32 sa_t =3D tcg_const_i32(rd); + gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t, + cpu_gpr[rt]); + gen_store_gpr(v1_t, rt); + tcg_temp_free_i32(sa_t); + } + break; + case 1: + /* PRECR_SRA_R_PH_W */ + { + TCGv_i32 sa_t =3D tcg_const_i32(rd); + gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t, + cpu_gpr[rt]); + gen_store_gpr(v1_t, rt); + tcg_temp_free_i32(sa_t); + } + break; + } + break; + case NM_MULEU_S_PH_QBL: + check_dsp(ctx); + gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_MULEU_S_PH_QBR: + check_dsp(ctx); + gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_MULQ_RS_PH: + check_dsp(ctx); + gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_MULQ_S_PH: + check_dsp_r2(ctx); + gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_MULQ_RS_W: + check_dsp_r2(ctx); + gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_MULQ_S_W: + check_dsp_r2(ctx); + gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_APPEND: + check_dsp_r2(ctx); + gen_load_gpr(t0, rs); + if (rd !=3D 0) { + tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd); + } + tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); + break; + case NM_MODSUB: + check_dsp(ctx); + gen_helper_modsub(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_SHRAV_R_W: + check_dsp(ctx); + gen_helper_shra_r_w(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_SHRLV_PH: + check_dsp_r2(ctx); + gen_helper_shrl_ph(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_SHRLV_QB: + check_dsp(ctx); + gen_helper_shrl_qb(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_SHLLV_QB: + check_dsp(ctx); + gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_SHLLV_S_W: + check_dsp(ctx); + gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_SHILO: + check_dsp(ctx); + { + TCGv tv0 =3D tcg_temp_new(); + TCGv tv1 =3D tcg_temp_new(); + int16_t imm =3D extract32(ctx->opcode, 16, 7); + + tcg_gen_movi_tl(tv0, rd >> 3); + tcg_gen_movi_tl(tv1, imm); + gen_helper_shilo(tv0, tv1, cpu_env); + } + break; + case NM_MULEQ_S_W_PHL: + check_dsp(ctx); + gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_MULEQ_S_W_PHR: + check_dsp(ctx); + gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_MUL_S_PH: + check_dsp_r2(ctx); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* MUL_PH */ + gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case 1: + /* MUL_S_PH */ + gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + } + break; + case NM_PRECR_QB_PH: + check_dsp_r2(ctx); + gen_helper_precr_qb_ph(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_PRECRQ_QB_PH: + check_dsp(ctx); + gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_PRECRQ_PH_W: + check_dsp(ctx); + gen_helper_precrq_ph_w(v1_t, v1_t, v2_t); + gen_store_gpr(v1_t, ret); + break; + case NM_PRECRQ_RS_PH_W: + check_dsp(ctx); + gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_PRECRQU_S_QB_PH: + check_dsp(ctx); + gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env); + gen_store_gpr(v1_t, ret); + break; + case NM_SHRA_R_W: + check_dsp(ctx); + tcg_gen_movi_tl(t0, rd); + gen_helper_shra_r_w(v1_t, t0, v1_t); + gen_store_gpr(v1_t, rt); + break; + case NM_SHRA_R_PH: + check_dsp(ctx); + tcg_gen_movi_tl(t0, rd >> 1); + switch (extract32(ctx->opcode, 10, 1)) { + case 0: + /* SHRA_PH */ + gen_helper_shra_ph(v1_t, t0, v1_t); + gen_store_gpr(v1_t, rt); + break; + case 1: + /* SHRA_R_PH */ + gen_helper_shra_r_ph(v1_t, t0, v1_t); + gen_store_gpr(v1_t, rt); + break; + } + break; + case NM_SHLL_S_PH: + check_dsp(ctx); + tcg_gen_movi_tl(t0, rd >> 1); + switch (extract32(ctx->opcode, 10, 2)) { + case 0: + /* SHLL_PH */ + gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env); + gen_store_gpr(v1_t, rt); + break; + case 2: + /* SHLL_S_PH */ + gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env); + gen_store_gpr(v1_t, rt); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_SHLL_S_W: + check_dsp(ctx); + tcg_gen_movi_tl(t0, rd); + gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env); + gen_store_gpr(v1_t, rt); + break; + case NM_REPL_PH: + check_dsp(ctx); + { + int16_t imm; + imm =3D sextract32(ctx->opcode, 11, 11); + imm =3D (int16_t)(imm << 6) >> 6; + if (rt !=3D 0) { + tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm)); + } + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) +{ + uint16_t insn; + uint32_t op; + int rt, rs, rd; + int offset; + int imm; + + insn =3D cpu_lduw_code(env, ctx->base.pc_next + 2); + ctx->opcode =3D (ctx->opcode << 16) | insn; + + rt =3D extract32(ctx->opcode, 21, 5); + rs =3D extract32(ctx->opcode, 16, 5); + rd =3D extract32(ctx->opcode, 11, 5); + + op =3D extract32(ctx->opcode, 26, 6); + switch (op) { + case NM_P_ADDIU: + if (rt =3D=3D 0) { + /* P.RI */ + switch (extract32(ctx->opcode, 19, 2)) { + case NM_SIGRIE: + default: + generate_exception_end(ctx, EXCP_RI); + break; + case NM_P_SYSCALL: + if ((extract32(ctx->opcode, 18, 1)) =3D=3D NM_SYSCALL) { + generate_exception_end(ctx, EXCP_SYSCALL); + } else { + generate_exception_end(ctx, EXCP_RI); + } + break; + case NM_BREAK: + generate_exception_end(ctx, EXCP_BREAK); + break; + case NM_SDBBP: + if (is_uhi(extract32(ctx->opcode, 0, 19))) { + gen_helper_do_semihosting(cpu_env); + } else { + if (ctx->hflags & MIPS_HFLAG_SBRI) { + generate_exception_end(ctx, EXCP_RI); + } else { + generate_exception_end(ctx, EXCP_DBp); + } + } + break; + } + } else { + /* NM_ADDIU */ + imm =3D extract32(ctx->opcode, 0, 16); + if (rs !=3D 0) { + tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm); + } else { + tcg_gen_movi_tl(cpu_gpr[rt], imm); + } + tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); + } + break; + case NM_ADDIUPC: + if (rt !=3D 0) { + offset =3D sextract32(ctx->opcode, 0, 1) << 21 | + extract32(ctx->opcode, 1, 20) << 1; + target_long addr =3D addr_add(ctx, ctx->base.pc_next + 4, offs= et); + tcg_gen_movi_tl(cpu_gpr[rt], addr); + } + break; + case NM_POOL32A: + switch (ctx->opcode & 0x07) { + case NM_POOL32A0: + gen_pool32a0_nanomips_insn(env, ctx); + break; + case NM_POOL32A5: + { + int32_t op1 =3D extract32(ctx->opcode, 3, 7); + gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt); + } + break; + case NM_POOL32A7: + switch (extract32(ctx->opcode, 3, 3)) { + case NM_P_LSX: + gen_p_lsx(ctx, rd, rs, rt); + break; + case NM_LSA: + /* + * In nanoMIPS, the shift field directly encodes the shift + * amount, meaning that the supported shift values are in + * the range 0 to 3 (instead of 1 to 4 in MIPSR6). + */ + gen_lsa(ctx, OPC_LSA, rd, rs, rt, + extract32(ctx->opcode, 9, 2) - 1); + break; + case NM_EXTW: + gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5)); + break; + case NM_POOL32AXF: + gen_pool32axf_nanomips_insn(env, ctx); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_P_GP_W: + switch (ctx->opcode & 0x03) { + case NM_ADDIUGP_W: + if (rt !=3D 0) { + offset =3D extract32(ctx->opcode, 0, 21); + gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset); + } + break; + case NM_LWGP: + gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2= ); + break; + case NM_SWGP: + gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2= ); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_P48I: + { + insn =3D cpu_lduw_code(env, ctx->base.pc_next + 4); + target_long addr_off =3D extract32(ctx->opcode, 0, 16) | insn = << 16; + switch (extract32(ctx->opcode, 16, 5)) { + case NM_LI48: + check_nms(ctx); + if (rt !=3D 0) { + tcg_gen_movi_tl(cpu_gpr[rt], addr_off); + } + break; + case NM_ADDIU48: + check_nms(ctx); + if (rt !=3D 0) { + tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off); + tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); + } + break; + case NM_ADDIUGP48: + check_nms(ctx); + if (rt !=3D 0) { + gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_o= ff); + } + break; + case NM_ADDIUPC48: + check_nms(ctx); + if (rt !=3D 0) { + target_long addr =3D addr_add(ctx, ctx->base.pc_next += 6, + addr_off); + + tcg_gen_movi_tl(cpu_gpr[rt], addr); + } + break; + case NM_LWPC48: + check_nms(ctx); + if (rt !=3D 0) { + TCGv t0; + t0 =3D tcg_temp_new(); + + target_long addr =3D addr_add(ctx, ctx->base.pc_next += 6, + addr_off); + + tcg_gen_movi_tl(t0, addr); + tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_T= ESL); + tcg_temp_free(t0); + } + break; + case NM_SWPC48: + check_nms(ctx); + { + TCGv t0, t1; + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + + target_long addr =3D addr_add(ctx, ctx->base.pc_next += 6, + addr_off); + + tcg_gen_movi_tl(t0, addr); + gen_load_gpr(t1, rt); + + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); + + tcg_temp_free(t0); + tcg_temp_free(t1); + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + return 6; + } + case NM_P_U12: + switch (extract32(ctx->opcode, 12, 4)) { + case NM_ORI: + gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, = 12)); + break; + case NM_XORI: + gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0,= 12)); + break; + case NM_ANDI: + gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0,= 12)); + break; + case NM_P_SR: + switch (extract32(ctx->opcode, 20, 1)) { + case NM_PP_SR: + switch (ctx->opcode & 3) { + case NM_SAVE: + gen_save(ctx, rt, extract32(ctx->opcode, 16, 4), + extract32(ctx->opcode, 2, 1), + extract32(ctx->opcode, 3, 9) << 3); + break; + case NM_RESTORE: + case NM_RESTORE_JRC: + gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4), + extract32(ctx->opcode, 2, 1), + extract32(ctx->opcode, 3, 9) << 3); + if ((ctx->opcode & 3) =3D=3D NM_RESTORE_JRC) { + gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0); + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_P_SR_F: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_SLTI: + gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 1= 2)); + break; + case NM_SLTIU: + gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, = 12)); + break; + case NM_SEQI: + { + TCGv t0 =3D tcg_temp_new(); + + imm =3D extract32(ctx->opcode, 0, 12); + gen_load_gpr(t0, rs); + tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm); + gen_store_gpr(t0, rt); + + tcg_temp_free(t0); + } + break; + case NM_ADDIUNEG: + imm =3D (int16_t) extract32(ctx->opcode, 0, 12); + gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm); + break; + case NM_P_SHIFT: + { + int shift =3D extract32(ctx->opcode, 0, 5); + switch (extract32(ctx->opcode, 5, 4)) { + case NM_P_SLL: + if (rt =3D=3D 0 && shift =3D=3D 0) { + /* NOP */ + } else if (rt =3D=3D 0 && shift =3D=3D 3) { + /* EHB - treat as NOP */ + } else if (rt =3D=3D 0 && shift =3D=3D 5) { + /* PAUSE - treat as NOP */ + } else if (rt =3D=3D 0 && shift =3D=3D 6) { + /* SYNC */ + gen_sync(extract32(ctx->opcode, 16, 5)); + } else { + /* SLL */ + gen_shift_imm(ctx, OPC_SLL, rt, rs, + extract32(ctx->opcode, 0, 5)); + } + break; + case NM_SRL: + gen_shift_imm(ctx, OPC_SRL, rt, rs, + extract32(ctx->opcode, 0, 5)); + break; + case NM_SRA: + gen_shift_imm(ctx, OPC_SRA, rt, rs, + extract32(ctx->opcode, 0, 5)); + break; + case NM_ROTR: + gen_shift_imm(ctx, OPC_ROTR, rt, rs, + extract32(ctx->opcode, 0, 5)); + break; + } + } + break; + case NM_P_ROTX: + check_nms(ctx); + if (rt !=3D 0) { + TCGv t0 =3D tcg_temp_new(); + TCGv_i32 shift =3D tcg_const_i32(extract32(ctx->opcode, 0,= 5)); + TCGv_i32 shiftx =3D tcg_const_i32(extract32(ctx->opcode, 7= , 4) + << 1); + TCGv_i32 stripe =3D tcg_const_i32(extract32(ctx->opcode, 6= , 1)); + + gen_load_gpr(t0, rs); + gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe); + tcg_temp_free(t0); + + tcg_temp_free_i32(shift); + tcg_temp_free_i32(shiftx); + tcg_temp_free_i32(stripe); + } + break; + case NM_P_INS: + switch (((ctx->opcode >> 10) & 2) | + (extract32(ctx->opcode, 5, 1))) { + case NM_INS: + check_nms(ctx); + gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0,= 5), + extract32(ctx->opcode, 6, 5)); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_P_EXT: + switch (((ctx->opcode >> 10) & 2) | + (extract32(ctx->opcode, 5, 1))) { + case NM_EXT: + check_nms(ctx); + gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0,= 5), + extract32(ctx->opcode, 6, 5)); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_POOL32F: + gen_pool32f_nanomips_insn(ctx); + break; + case NM_POOL32S: + break; + case NM_P_LUI: + switch (extract32(ctx->opcode, 1, 1)) { + case NM_LUI: + if (rt !=3D 0) { + tcg_gen_movi_tl(cpu_gpr[rt], + sextract32(ctx->opcode, 0, 1) << 31 | + extract32(ctx->opcode, 2, 10) << 21 | + extract32(ctx->opcode, 12, 9) << 12); + } + break; + case NM_ALUIPC: + if (rt !=3D 0) { + offset =3D sextract32(ctx->opcode, 0, 1) << 31 | + extract32(ctx->opcode, 2, 10) << 21 | + extract32(ctx->opcode, 12, 9) << 12; + target_long addr; + addr =3D ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, off= set); + tcg_gen_movi_tl(cpu_gpr[rt], addr); + } + break; + } + break; + case NM_P_GP_BH: + { + uint32_t u =3D extract32(ctx->opcode, 0, 18); + + switch (extract32(ctx->opcode, 18, 3)) { + case NM_LBGP: + gen_ld(ctx, OPC_LB, rt, 28, u); + break; + case NM_SBGP: + gen_st(ctx, OPC_SB, rt, 28, u); + break; + case NM_LBUGP: + gen_ld(ctx, OPC_LBU, rt, 28, u); + break; + case NM_ADDIUGP_B: + if (rt !=3D 0) { + gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u); + } + break; + case NM_P_GP_LH: + u &=3D ~1; + switch (ctx->opcode & 1) { + case NM_LHGP: + gen_ld(ctx, OPC_LH, rt, 28, u); + break; + case NM_LHUGP: + gen_ld(ctx, OPC_LHU, rt, 28, u); + break; + } + break; + case NM_P_GP_SH: + u &=3D ~1; + switch (ctx->opcode & 1) { + case NM_SHGP: + gen_st(ctx, OPC_SH, rt, 28, u); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_P_GP_CP1: + u &=3D ~0x3; + switch (ctx->opcode & 0x3) { + case NM_LWC1GP: + gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u); + break; + case NM_LDC1GP: + gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u); + break; + case NM_SWC1GP: + gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u); + break; + case NM_SDC1GP: + gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u); + break; + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + } + break; + case NM_P_LS_U12: + { + uint32_t u =3D extract32(ctx->opcode, 0, 12); + + switch (extract32(ctx->opcode, 12, 4)) { + case NM_P_PREFU12: + if (rt =3D=3D 31) { + /* SYNCI */ + /* + * Break the TB to be able to sync copied instructions + * immediately. + */ + ctx->base.is_jmp =3D DISAS_STOP; + } else { + /* PREF */ + /* Treat as NOP. */ + } + break; + case NM_LB: + gen_ld(ctx, OPC_LB, rt, rs, u); + break; + case NM_LH: + gen_ld(ctx, OPC_LH, rt, rs, u); + break; + case NM_LW: + gen_ld(ctx, OPC_LW, rt, rs, u); + break; + case NM_LBU: + gen_ld(ctx, OPC_LBU, rt, rs, u); + break; + case NM_LHU: + gen_ld(ctx, OPC_LHU, rt, rs, u); + break; + case NM_SB: + gen_st(ctx, OPC_SB, rt, rs, u); + break; + case NM_SH: + gen_st(ctx, OPC_SH, rt, rs, u); + break; + case NM_SW: + gen_st(ctx, OPC_SW, rt, rs, u); + break; + case NM_LWC1: + gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u); + break; + case NM_LDC1: + gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u); + break; + case NM_SWC1: + gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u); + break; + case NM_SDC1: + gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + } + break; + case NM_P_LS_S9: + { + int32_t s =3D (sextract32(ctx->opcode, 15, 1) << 8) | + extract32(ctx->opcode, 0, 8); + + switch (extract32(ctx->opcode, 8, 3)) { + case NM_P_LS_S0: + switch (extract32(ctx->opcode, 11, 4)) { + case NM_LBS9: + gen_ld(ctx, OPC_LB, rt, rs, s); + break; + case NM_LHS9: + gen_ld(ctx, OPC_LH, rt, rs, s); + break; + case NM_LWS9: + gen_ld(ctx, OPC_LW, rt, rs, s); + break; + case NM_LBUS9: + gen_ld(ctx, OPC_LBU, rt, rs, s); + break; + case NM_LHUS9: + gen_ld(ctx, OPC_LHU, rt, rs, s); + break; + case NM_SBS9: + gen_st(ctx, OPC_SB, rt, rs, s); + break; + case NM_SHS9: + gen_st(ctx, OPC_SH, rt, rs, s); + break; + case NM_SWS9: + gen_st(ctx, OPC_SW, rt, rs, s); + break; + case NM_LWC1S9: + gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s); + break; + case NM_LDC1S9: + gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s); + break; + case NM_SWC1S9: + gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s); + break; + case NM_SDC1S9: + gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s); + break; + case NM_P_PREFS9: + if (rt =3D=3D 31) { + /* SYNCI */ + /* + * Break the TB to be able to sync copied instruct= ions + * immediately. + */ + ctx->base.is_jmp =3D DISAS_STOP; + } else { + /* PREF */ + /* Treat as NOP. */ + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_P_LS_S1: + switch (extract32(ctx->opcode, 11, 4)) { + case NM_UALH: + case NM_UASH: + check_nms(ctx); + { + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + + gen_base_offset_addr(ctx, t0, rs, s); + + switch (extract32(ctx->opcode, 11, 4)) { + case NM_UALH: + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TE= SW | + MO_UNALN); + gen_store_gpr(t0, rt); + break; + case NM_UASH: + gen_load_gpr(t1, rt); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TE= UW | + MO_UNALN); + break; + } + tcg_temp_free(t0); + tcg_temp_free(t1); + } + break; + case NM_P_LL: + switch (ctx->opcode & 0x03) { + case NM_LL: + gen_ld(ctx, OPC_LL, rt, rs, s); + break; + case NM_LLWP: + check_xnp(ctx); + gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3,= 5)); + break; + } + break; + case NM_P_SC: + switch (ctx->opcode & 0x03) { + case NM_SC: + gen_st_cond(ctx, rt, rs, s, MO_TESL, false); + break; + case NM_SCWP: + check_xnp(ctx); + gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3,= 5), + false); + break; + } + break; + case NM_CACHE: + check_cp0_enabled(ctx); + if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { + gen_cache_operation(ctx, rt, rs, s); + } + break; + } + break; + case NM_P_LS_E0: + switch (extract32(ctx->opcode, 11, 4)) { + case NM_LBE: + check_eva(ctx); + check_cp0_enabled(ctx); + gen_ld(ctx, OPC_LBE, rt, rs, s); + break; + case NM_SBE: + check_eva(ctx); + check_cp0_enabled(ctx); + gen_st(ctx, OPC_SBE, rt, rs, s); + break; + case NM_LBUE: + check_eva(ctx); + check_cp0_enabled(ctx); + gen_ld(ctx, OPC_LBUE, rt, rs, s); + break; + case NM_P_PREFE: + if (rt =3D=3D 31) { + /* case NM_SYNCIE */ + check_eva(ctx); + check_cp0_enabled(ctx); + /* + * Break the TB to be able to sync copied instruct= ions + * immediately. + */ + ctx->base.is_jmp =3D DISAS_STOP; + } else { + /* case NM_PREFE */ + check_eva(ctx); + check_cp0_enabled(ctx); + /* Treat as NOP. */ + } + break; + case NM_LHE: + check_eva(ctx); + check_cp0_enabled(ctx); + gen_ld(ctx, OPC_LHE, rt, rs, s); + break; + case NM_SHE: + check_eva(ctx); + check_cp0_enabled(ctx); + gen_st(ctx, OPC_SHE, rt, rs, s); + break; + case NM_LHUE: + check_eva(ctx); + check_cp0_enabled(ctx); + gen_ld(ctx, OPC_LHUE, rt, rs, s); + break; + case NM_CACHEE: + check_nms_dl_il_sl_tl_l2c(ctx); + gen_cache_operation(ctx, rt, rs, s); + break; + case NM_LWE: + check_eva(ctx); + check_cp0_enabled(ctx); + gen_ld(ctx, OPC_LWE, rt, rs, s); + break; + case NM_SWE: + check_eva(ctx); + check_cp0_enabled(ctx); + gen_st(ctx, OPC_SWE, rt, rs, s); + break; + case NM_P_LLE: + switch (extract32(ctx->opcode, 2, 2)) { + case NM_LLE: + check_xnp(ctx); + check_eva(ctx); + check_cp0_enabled(ctx); + gen_ld(ctx, OPC_LLE, rt, rs, s); + break; + case NM_LLWPE: + check_xnp(ctx); + check_eva(ctx); + check_cp0_enabled(ctx); + gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3,= 5)); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_P_SCE: + switch (extract32(ctx->opcode, 2, 2)) { + case NM_SCE: + check_xnp(ctx); + check_eva(ctx); + check_cp0_enabled(ctx); + gen_st_cond(ctx, rt, rs, s, MO_TESL, true); + break; + case NM_SCWPE: + check_xnp(ctx); + check_eva(ctx); + check_cp0_enabled(ctx); + gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3,= 5), + true); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + } + break; + case NM_P_LS_WM: + case NM_P_LS_UAWM: + check_nms(ctx); + { + int count =3D extract32(ctx->opcode, 12, 3); + int counter =3D 0; + + offset =3D sextract32(ctx->opcode, 15, 1) << 8 | + extract32(ctx->opcode, 0, 8); + TCGv va =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + MemOp memop =3D (extract32(ctx->opcode, 8, 3)) =3D=3D + NM_P_LS_UAWM ? MO_UNALN : 0; + + count =3D (count =3D=3D 0) ? 8 : count; + while (counter !=3D count) { + int this_rt =3D ((rt + counter) & 0x1f) | (rt & 0x= 10); + int this_offset =3D offset + (counter << 2); + + gen_base_offset_addr(ctx, va, rs, this_offset); + + switch (extract32(ctx->opcode, 11, 1)) { + case NM_LWM: + tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx, + memop | MO_TESL); + gen_store_gpr(t1, this_rt); + if ((this_rt =3D=3D rs) && + (counter !=3D (count - 1))) { + /* UNPREDICTABLE */ + } + break; + case NM_SWM: + this_rt =3D (rt =3D=3D 0) ? 0 : this_rt; + gen_load_gpr(t1, this_rt); + tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx, + memop | MO_TEUL); + break; + } + counter++; + } + tcg_temp_free(va); + tcg_temp_free(t1); + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + } + break; + case NM_MOVE_BALC: + check_nms(ctx); + { + TCGv t0 =3D tcg_temp_new(); + int32_t s =3D sextract32(ctx->opcode, 0, 1) << 21 | + extract32(ctx->opcode, 1, 20) << 1; + rd =3D (extract32(ctx->opcode, 24, 1)) =3D=3D 0 ? 4 : 5; + rt =3D decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3= | + extract32(ctx->opcode, 21, 3)); + gen_load_gpr(t0, rt); + tcg_gen_mov_tl(cpu_gpr[rd], t0); + gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s); + tcg_temp_free(t0); + } + break; + case NM_P_BAL: + { + int32_t s =3D sextract32(ctx->opcode, 0, 1) << 25 | + extract32(ctx->opcode, 1, 24) << 1; + + if ((extract32(ctx->opcode, 25, 1)) =3D=3D 0) { + /* BC */ + gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s); + } else { + /* BALC */ + gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s); + } + } + break; + case NM_P_J: + switch (extract32(ctx->opcode, 12, 4)) { + case NM_JALRC: + case NM_JALRC_HB: + gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0); + break; + case NM_P_BALRSC: + gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_P_BR1: + { + int32_t s =3D sextract32(ctx->opcode, 0, 1) << 14 | + extract32(ctx->opcode, 1, 13) << 1; + switch (extract32(ctx->opcode, 14, 2)) { + case NM_BEQC: + check_nms(ctx); + gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s); + break; + case NM_P_BR3A: + s =3D sextract32(ctx->opcode, 0, 1) << 14 | + extract32(ctx->opcode, 1, 13) << 1; + check_cp1_enabled(ctx); + switch (extract32(ctx->opcode, 16, 5)) { + case NM_BC1EQZC: + gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s); + break; + case NM_BC1NEZC: + gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s); + break; + case NM_BPOSGE32C: + check_dsp_r3(ctx); + { + int32_t imm =3D extract32(ctx->opcode, 1, 13) | + extract32(ctx->opcode, 0, 1) << 13; + + gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2, + imm); + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_BGEC: + if (rs =3D=3D rt) { + gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s); + } else { + gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s= ); + } + break; + case NM_BGEUC: + if (rs =3D=3D rt || rt =3D=3D 0) { + gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s); + } else if (rs =3D=3D 0) { + gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s= ); + } else { + gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, = s); + } + break; + } + } + break; + case NM_P_BR2: + { + int32_t s =3D sextract32(ctx->opcode, 0, 1) << 14 | + extract32(ctx->opcode, 1, 13) << 1; + switch (extract32(ctx->opcode, 14, 2)) { + case NM_BNEC: + check_nms(ctx); + gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s); + break; + case NM_BLTC: + if (rs !=3D 0 && rt !=3D 0 && rs =3D=3D rt) { + /* NOP */ + ctx->hflags |=3D MIPS_HFLAG_FBNSLOT; + } else { + gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s= ); + } + break; + case NM_BLTUC: + if (rs =3D=3D 0 || rs =3D=3D rt) { + /* NOP */ + ctx->hflags |=3D MIPS_HFLAG_FBNSLOT; + } else { + gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, = s); + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + } + break; + case NM_P_BRI: + { + int32_t s =3D sextract32(ctx->opcode, 0, 1) << 11 | + extract32(ctx->opcode, 1, 10) << 1; + uint32_t u =3D extract32(ctx->opcode, 11, 7); + + gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3), + rt, u, s); + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + return 4; +} + +static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t op; + int rt =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode)); + int rs =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); + int rd =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode)); + int offset; + int imm; + + /* make sure instructions are on a halfword boundary */ + if (ctx->base.pc_next & 0x1) { + TCGv tmp =3D tcg_const_tl(ctx->base.pc_next); + tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); + tcg_temp_free(tmp); + generate_exception_end(ctx, EXCP_AdEL); + return 2; + } + + op =3D extract32(ctx->opcode, 10, 6); + switch (op) { + case NM_P16_MV: + rt =3D NANOMIPS_EXTRACT_RD5(ctx->opcode); + if (rt !=3D 0) { + /* MOVE */ + rs =3D NANOMIPS_EXTRACT_RS5(ctx->opcode); + gen_arith(ctx, OPC_ADDU, rt, rs, 0); + } else { + /* P16.RI */ + switch (extract32(ctx->opcode, 3, 2)) { + case NM_P16_SYSCALL: + if (extract32(ctx->opcode, 2, 1) =3D=3D 0) { + generate_exception_end(ctx, EXCP_SYSCALL); + } else { + generate_exception_end(ctx, EXCP_RI); + } + break; + case NM_BREAK16: + generate_exception_end(ctx, EXCP_BREAK); + break; + case NM_SDBBP16: + if (is_uhi(extract32(ctx->opcode, 0, 3))) { + gen_helper_do_semihosting(cpu_env); + } else { + if (ctx->hflags & MIPS_HFLAG_SBRI) { + generate_exception_end(ctx, EXCP_RI); + } else { + generate_exception_end(ctx, EXCP_DBp); + } + } + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + } + break; + case NM_P16_SHIFT: + { + int shift =3D extract32(ctx->opcode, 0, 3); + uint32_t opc =3D 0; + shift =3D (shift =3D=3D 0) ? 8 : shift; + + switch (extract32(ctx->opcode, 3, 1)) { + case NM_SLL16: + opc =3D OPC_SLL; + break; + case NM_SRL16: + opc =3D OPC_SRL; + break; + } + gen_shift_imm(ctx, opc, rt, rs, shift); + } + break; + case NM_P16C: + switch (ctx->opcode & 1) { + case NM_POOL16C_0: + gen_pool16c_nanomips_insn(ctx); + break; + case NM_LWXS16: + gen_ldxs(ctx, rt, rs, rd); + break; + } + break; + case NM_P16_A1: + switch (extract32(ctx->opcode, 6, 1)) { + case NM_ADDIUR1SP: + imm =3D extract32(ctx->opcode, 0, 6) << 2; + gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_P16_A2: + switch (extract32(ctx->opcode, 3, 1)) { + case NM_ADDIUR2: + imm =3D extract32(ctx->opcode, 0, 3) << 2; + gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm); + break; + case NM_P_ADDIURS5: + rt =3D extract32(ctx->opcode, 5, 5); + if (rt !=3D 0) { + /* imm =3D sign_extend(s[3] . s[2:0] , from_nbits =3D 4) */ + imm =3D (sextract32(ctx->opcode, 4, 1) << 3) | + (extract32(ctx->opcode, 0, 3)); + gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm); + } + break; + } + break; + case NM_P16_ADDU: + switch (ctx->opcode & 0x1) { + case NM_ADDU16: + gen_arith(ctx, OPC_ADDU, rd, rs, rt); + break; + case NM_SUBU16: + gen_arith(ctx, OPC_SUBU, rd, rs, rt); + break; + } + break; + case NM_P16_4X4: + rt =3D (extract32(ctx->opcode, 9, 1) << 3) | + extract32(ctx->opcode, 5, 3); + rs =3D (extract32(ctx->opcode, 4, 1) << 3) | + extract32(ctx->opcode, 0, 3); + rt =3D decode_gpr_gpr4(rt); + rs =3D decode_gpr_gpr4(rs); + switch ((extract32(ctx->opcode, 7, 2) & 0x2) | + (extract32(ctx->opcode, 3, 1))) { + case NM_ADDU4X4: + check_nms(ctx); + gen_arith(ctx, OPC_ADDU, rt, rs, rt); + break; + case NM_MUL4X4: + check_nms(ctx); + gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_LI16: + { + int imm =3D extract32(ctx->opcode, 0, 7); + imm =3D (imm =3D=3D 0x7f ? -1 : imm); + if (rt !=3D 0) { + tcg_gen_movi_tl(cpu_gpr[rt], imm); + } + } + break; + case NM_ANDI16: + { + uint32_t u =3D extract32(ctx->opcode, 0, 4); + u =3D (u =3D=3D 12) ? 0xff : + (u =3D=3D 13) ? 0xffff : u; + gen_logic_imm(ctx, OPC_ANDI, rt, rs, u); + } + break; + case NM_P16_LB: + offset =3D extract32(ctx->opcode, 0, 2); + switch (extract32(ctx->opcode, 2, 2)) { + case NM_LB16: + gen_ld(ctx, OPC_LB, rt, rs, offset); + break; + case NM_SB16: + rt =3D decode_gpr_gpr3_src_store( + NANOMIPS_EXTRACT_RT3(ctx->opcode)); + gen_st(ctx, OPC_SB, rt, rs, offset); + break; + case NM_LBU16: + gen_ld(ctx, OPC_LBU, rt, rs, offset); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_P16_LH: + offset =3D extract32(ctx->opcode, 1, 2) << 1; + switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) { + case NM_LH16: + gen_ld(ctx, OPC_LH, rt, rs, offset); + break; + case NM_SH16: + rt =3D decode_gpr_gpr3_src_store( + NANOMIPS_EXTRACT_RT3(ctx->opcode)); + gen_st(ctx, OPC_SH, rt, rs, offset); + break; + case NM_LHU16: + gen_ld(ctx, OPC_LHU, rt, rs, offset); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case NM_LW16: + offset =3D extract32(ctx->opcode, 0, 4) << 2; + gen_ld(ctx, OPC_LW, rt, rs, offset); + break; + case NM_LWSP16: + rt =3D NANOMIPS_EXTRACT_RD5(ctx->opcode); + offset =3D extract32(ctx->opcode, 0, 5) << 2; + gen_ld(ctx, OPC_LW, rt, 29, offset); + break; + case NM_LW4X4: + check_nms(ctx); + rt =3D (extract32(ctx->opcode, 9, 1) << 3) | + extract32(ctx->opcode, 5, 3); + rs =3D (extract32(ctx->opcode, 4, 1) << 3) | + extract32(ctx->opcode, 0, 3); + offset =3D (extract32(ctx->opcode, 3, 1) << 3) | + (extract32(ctx->opcode, 8, 1) << 2); + rt =3D decode_gpr_gpr4(rt); + rs =3D decode_gpr_gpr4(rs); + gen_ld(ctx, OPC_LW, rt, rs, offset); + break; + case NM_SW4X4: + check_nms(ctx); + rt =3D (extract32(ctx->opcode, 9, 1) << 3) | + extract32(ctx->opcode, 5, 3); + rs =3D (extract32(ctx->opcode, 4, 1) << 3) | + extract32(ctx->opcode, 0, 3); + offset =3D (extract32(ctx->opcode, 3, 1) << 3) | + (extract32(ctx->opcode, 8, 1) << 2); + rt =3D decode_gpr_gpr4_zero(rt); + rs =3D decode_gpr_gpr4(rs); + gen_st(ctx, OPC_SW, rt, rs, offset); + break; + case NM_LWGP16: + offset =3D extract32(ctx->opcode, 0, 7) << 2; + gen_ld(ctx, OPC_LW, rt, 28, offset); + break; + case NM_SWSP16: + rt =3D NANOMIPS_EXTRACT_RD5(ctx->opcode); + offset =3D extract32(ctx->opcode, 0, 5) << 2; + gen_st(ctx, OPC_SW, rt, 29, offset); + break; + case NM_SW16: + rt =3D decode_gpr_gpr3_src_store( + NANOMIPS_EXTRACT_RT3(ctx->opcode)); + rs =3D decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); + offset =3D extract32(ctx->opcode, 0, 4) << 2; + gen_st(ctx, OPC_SW, rt, rs, offset); + break; + case NM_SWGP16: + rt =3D decode_gpr_gpr3_src_store( + NANOMIPS_EXTRACT_RT3(ctx->opcode)); + offset =3D extract32(ctx->opcode, 0, 7) << 2; + gen_st(ctx, OPC_SW, rt, 28, offset); + break; + case NM_BC16: + gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0, + (sextract32(ctx->opcode, 0, 1) << 10) | + (extract32(ctx->opcode, 1, 9) << 1)); + break; + case NM_BALC16: + gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0, + (sextract32(ctx->opcode, 0, 1) << 10) | + (extract32(ctx->opcode, 1, 9) << 1)); + break; + case NM_BEQZC16: + gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0, + (sextract32(ctx->opcode, 0, 1) << 7) | + (extract32(ctx->opcode, 1, 6) << 1)); + break; + case NM_BNEZC16: + gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0, + (sextract32(ctx->opcode, 0, 1) << 7) | + (extract32(ctx->opcode, 1, 6) << 1)); + break; + case NM_P16_BR: + switch (ctx->opcode & 0xf) { + case 0: + /* P16.JRC */ + switch (extract32(ctx->opcode, 4, 1)) { + case NM_JRC: + gen_compute_branch_nm(ctx, OPC_JR, 2, + extract32(ctx->opcode, 5, 5), 0, 0); + break; + case NM_JALRC16: + gen_compute_branch_nm(ctx, OPC_JALR, 2, + extract32(ctx->opcode, 5, 5), 31, 0); + break; + } + break; + default: + { + /* P16.BRI */ + uint32_t opc =3D extract32(ctx->opcode, 4, 3) < + extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OP= C_BNE; + gen_compute_branch_nm(ctx, opc, 2, rs, rt, + extract32(ctx->opcode, 0, 4) << 1); + } + break; + } + break; + case NM_P16_SR: + { + int count =3D extract32(ctx->opcode, 0, 4); + int u =3D extract32(ctx->opcode, 4, 4) << 4; + + rt =3D 30 + extract32(ctx->opcode, 9, 1); + switch (extract32(ctx->opcode, 8, 1)) { + case NM_SAVE16: + gen_save(ctx, rt, count, 0, u); + break; + case NM_RESTORE_JRC16: + gen_restore(ctx, rt, count, 0, u); + gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0); + break; + } + } + break; + case NM_MOVEP: + case NM_MOVEPREV: + check_nms(ctx); + { + static const int gpr2reg1[] =3D {4, 5, 6, 7}; + static const int gpr2reg2[] =3D {5, 6, 7, 8}; + int re; + int rd2 =3D extract32(ctx->opcode, 3, 1) << 1 | + extract32(ctx->opcode, 8, 1); + int r1 =3D gpr2reg1[rd2]; + int r2 =3D gpr2reg2[rd2]; + int r3 =3D extract32(ctx->opcode, 4, 1) << 3 | + extract32(ctx->opcode, 0, 3); + int r4 =3D extract32(ctx->opcode, 9, 1) << 3 | + extract32(ctx->opcode, 5, 3); + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + if (op =3D=3D NM_MOVEP) { + rd =3D r1; + re =3D r2; + rs =3D decode_gpr_gpr4_zero(r3); + rt =3D decode_gpr_gpr4_zero(r4); + } else { + rd =3D decode_gpr_gpr4(r3); + re =3D decode_gpr_gpr4(r4); + rs =3D r1; + rt =3D r2; + } + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + tcg_gen_mov_tl(cpu_gpr[rd], t0); + tcg_gen_mov_tl(cpu_gpr[re], t1); + tcg_temp_free(t0); + tcg_temp_free(t1); + } + break; + default: + return decode_nanomips_32_48_opc(env, ctx); + } + + return 2; +} --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.67 as permitted sender) client-ip=209.85.221.67; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f67.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.67 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906598; cv=none; d=zohomail.com; s=zohoarc; b=ldnEjev+xAFVzEyLOr/8TneMbkBaY4CLkMsn5mlaAlGHOqCHHMfxA7YSLqFlbHc5i9KWcBietZH8KIQh6x6R+NuOxxAwe7WwrUC/DUqRMTYgWMKiAfRWDAz0YjRWl9oB1g6d22i8VhwEc4w3TlLfgliggtFJPWg1ZTOsChimJUY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906598; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=rX+PiacrD0NOUjJecJPa9l0sr2knH8aocVaAZdGhX04=; b=Q+Un9RFXZ1o1gHb7uRJAIyZS9V0yEsJFA0l7jWgqmkST1xOtcpPNMhH4UeiL/z6bg3hdOukvhiM7BfzV10yWXDEDQGYjYNQ8QwkDkXpu7x2eBNFh9GOGPRZpSs3VTr5Gh3y4RJEhBdCHdmqS7/4xIbhkIA/nYxlDXlZ+sk45a8o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.67 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) by mx.zohomail.com with SMTPS id 1605906598132500.87789632215834; Fri, 20 Nov 2020 13:09:58 -0800 (PST) Received: by mail-wr1-f67.google.com with SMTP id j7so11729400wrp.3 for ; Fri, 20 Nov 2020 13:09:57 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id a15sm6342117wrn.75.2020.11.20.13.09.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:09:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rX+PiacrD0NOUjJecJPa9l0sr2knH8aocVaAZdGhX04=; b=Yta7lBFI8muJcLZJ4Vvy3ZoWCW0icroAmkko3jZcQ25pIi0FNBmcOkH5WRaIdi6jL+ QQiQK57E1UV2lIBgCMR6Dn+ECZCNHcA4qYjMHMR3PsC7UKl/E7+wesYWErV0wuKuZWoi XN8CXjn8hlK/NiKVNwabRDwGWfYZFG5tFRFMmfCf2cY0p/ICHmi+6yR0pz0kWo4w0zG3 qneeL12/EcOAdltSRNdJagCAF18WzD8kNw5fQW50SuBDryaMY2LXgP1zEVvC7bcS5hg2 jitKM3bENKX2xOw8eIwhcpsL6hlVixYIPdf43mUjM7ttJFFXqjLOMqzfZZO5LJyfPEmB dGlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=rX+PiacrD0NOUjJecJPa9l0sr2knH8aocVaAZdGhX04=; b=hGTSQupEDi5PeU17NEVGN6DOuXIH+K4N0sGjPFhkI53WAYCRpr4kmp+kv8m8xn/yis wtF+iZS1DTNli0ih1WVLEZTN5R1J/ZJ+MDbBknlWyyCt5sRQcSLBlxCFuhwxoknEXX8r LYX0CTU6W6+azfJ5SsUzNM5ydM+fg63mNehSt1LEnl5HJmSHlVqr4KlZ+4hA91erMXf7 ZHkeZDxpNxiG7FCVjVA1sUIvNmwCRs5fYI+DNGpgN5iE6F4DcI3toWt/S7yylATilIko 9veeSjWX62Ue+XU00j503VNlpbHtgyN1kqYL7sbmIqTmgHVD7JbsrYBu2drGEaWWFBe6 h07w== X-Gm-Message-State: AOAM532rJDZsq25yPwIbyppp/aCxKqlrLaOLMK2C6Ul4txA0wDf9g/Cl Ae43xB+sVs/D2HyjGxi6ML8= X-Google-Smtp-Source: ABdhPJx/GvEhKU9fgySWor6l4wOLe5pFQBIFdl6c9COb3cllkBlk5mi8Gc56x4xGLSqNTnq714Bviw== X-Received: by 2002:adf:fa0c:: with SMTP id m12mr16595763wrr.222.1605906596154; Fri, 20 Nov 2020 13:09:56 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 13/26] target/mips: Extract NEC Vr54xx helpers to vendor-vr54xx_helper.c Date: Fri, 20 Nov 2020 22:08:31 +0100 Message-Id: <20201120210844.2625602-14-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract NEC Vr54xx helpers from op_helper.c to a new file: 'vendor-vr54xx_helper.c'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/op_helper.c | 118 -------------------------- target/mips/vendor-vr54xx_helper.c | 131 +++++++++++++++++++++++++++++ target/mips/meson.build | 1 + 3 files changed, 132 insertions(+), 118 deletions(-) create mode 100644 target/mips/vendor-vr54xx_helper.c diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index dd09a4c714a..a900c008b5a 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -54,124 +54,6 @@ static void raise_exception(CPUMIPSState *env, uint32_t= exception) do_raise_exception(env, exception, 0); } =20 -/* 64 bits arithmetic for 32 bits hosts */ -static inline uint64_t get_HILO(CPUMIPSState *env) -{ - return ((uint64_t)(env->active_tc.HI[0]) << 32) | - (uint32_t)env->active_tc.LO[0]; -} - -static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO) -{ - env->active_tc.LO[0] =3D (int32_t)(HILO & 0xFFFFFFFF); - return env->active_tc.HI[0] =3D (int32_t)(HILO >> 32); -} - -static inline target_ulong set_HI_LOT0(CPUMIPSState *env, uint64_t HILO) -{ - target_ulong tmp =3D env->active_tc.LO[0] =3D (int32_t)(HILO & 0xFFFFF= FFF); - env->active_tc.HI[0] =3D (int32_t)(HILO >> 32); - return tmp; -} - -/* Multiplication variants of the vr54xx. */ -target_ulong helper_muls(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HI_LOT0(env, 0 - ((int64_t)(int32_t)arg1 * - (int64_t)(int32_t)arg2)); -} - -target_ulong helper_mulsu(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HI_LOT0(env, 0 - (uint64_t)(uint32_t)arg1 * - (uint64_t)(uint32_t)arg2); -} - -target_ulong helper_macc(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HI_LOT0(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg= 1 * - (int64_t)(int32_t)arg2); -} - -target_ulong helper_macchi(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HIT0_LO(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg= 1 * - (int64_t)(int32_t)arg2); -} - -target_ulong helper_maccu(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HI_LOT0(env, (uint64_t)get_HILO(env) + - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2= ); -} - -target_ulong helper_macchiu(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HIT0_LO(env, (uint64_t)get_HILO(env) + - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2= ); -} - -target_ulong helper_msac(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HI_LOT0(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg= 1 * - (int64_t)(int32_t)arg2); -} - -target_ulong helper_msachi(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HIT0_LO(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg= 1 * - (int64_t)(int32_t)arg2); -} - -target_ulong helper_msacu(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HI_LOT0(env, (uint64_t)get_HILO(env) - - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2= ); -} - -target_ulong helper_msachiu(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HIT0_LO(env, (uint64_t)get_HILO(env) - - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2= ); -} - -target_ulong helper_mulhi(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HIT0_LO(env, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg= 2); -} - -target_ulong helper_mulhiu(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HIT0_LO(env, (uint64_t)(uint32_t)arg1 * - (uint64_t)(uint32_t)arg2); -} - -target_ulong helper_mulshi(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HIT0_LO(env, 0 - (int64_t)(int32_t)arg1 * - (int64_t)(int32_t)arg2); -} - -target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1, - target_ulong arg2) -{ - return set_HIT0_LO(env, 0 - (uint64_t)(uint32_t)arg1 * - (uint64_t)(uint32_t)arg2); -} - static inline target_ulong bitswap(target_ulong v) { v =3D ((v >> 1) & (target_ulong)0x5555555555555555ULL) | diff --git a/target/mips/vendor-vr54xx_helper.c b/target/mips/vendor-vr54xx= _helper.c new file mode 100644 index 00000000000..d8c8f648b54 --- /dev/null +++ b/target/mips/vendor-vr54xx_helper.c @@ -0,0 +1,131 @@ +/* + * MIPS NEC Vr54xx instruction emulation helpers for QEMU. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" + +/* 64 bits arithmetic for 32 bits hosts */ +static inline uint64_t get_HILO(CPUMIPSState *env) +{ + return ((uint64_t)(env->active_tc.HI[0]) << 32) | + (uint32_t)env->active_tc.LO[0]; +} + +static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO) +{ + env->active_tc.LO[0] =3D (int32_t)(HILO & 0xFFFFFFFF); + return env->active_tc.HI[0] =3D (int32_t)(HILO >> 32); +} + +static inline target_ulong set_HI_LOT0(CPUMIPSState *env, uint64_t HILO) +{ + target_ulong tmp =3D env->active_tc.LO[0] =3D (int32_t)(HILO & 0xFFFFF= FFF); + env->active_tc.HI[0] =3D (int32_t)(HILO >> 32); + return tmp; +} + +/* Multiplication variants of the vr54xx. */ +target_ulong helper_muls(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HI_LOT0(env, 0 - ((int64_t)(int32_t)arg1 * + (int64_t)(int32_t)arg2)); +} + +target_ulong helper_mulsu(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HI_LOT0(env, 0 - (uint64_t)(uint32_t)arg1 * + (uint64_t)(uint32_t)arg2); +} + +target_ulong helper_macc(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HI_LOT0(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg= 1 * + (int64_t)(int32_t)arg2); +} + +target_ulong helper_macchi(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HIT0_LO(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg= 1 * + (int64_t)(int32_t)arg2); +} + +target_ulong helper_maccu(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HI_LOT0(env, (uint64_t)get_HILO(env) + + (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2= ); +} + +target_ulong helper_macchiu(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HIT0_LO(env, (uint64_t)get_HILO(env) + + (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2= ); +} + +target_ulong helper_msac(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HI_LOT0(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg= 1 * + (int64_t)(int32_t)arg2); +} + +target_ulong helper_msachi(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HIT0_LO(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg= 1 * + (int64_t)(int32_t)arg2); +} + +target_ulong helper_msacu(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HI_LOT0(env, (uint64_t)get_HILO(env) - + (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2= ); +} + +target_ulong helper_msachiu(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HIT0_LO(env, (uint64_t)get_HILO(env) - + (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2= ); +} + +target_ulong helper_mulhi(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HIT0_LO(env, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg= 2); +} + +target_ulong helper_mulhiu(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HIT0_LO(env, (uint64_t)(uint32_t)arg1 * + (uint64_t)(uint32_t)arg2); +} + +target_ulong helper_mulshi(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HIT0_LO(env, 0 - (int64_t)(int32_t)arg1 * + (int64_t)(int32_t)arg2); +} + +target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1, + target_ulong arg2) +{ + return set_HIT0_LO(env, 0 - (uint64_t)(uint32_t)arg1 * + (uint64_t)(uint32_t)arg2); +} diff --git a/target/mips/meson.build b/target/mips/meson.build index cc4677d94dc..b63ef41cb1d 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -8,6 +8,7 @@ 'op_helper.c', 'mod-mips-dsp_helper.c', 'mod-mips-msa_helper.c', + 'vendor-vr54xx_helper.c', =20 'translate.c', )) --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.65 as permitted sender) client-ip=209.85.221.65; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f65.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.65 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906602; cv=none; d=zohomail.com; s=zohoarc; b=fRwJ8nNM6g8gElKpgH3mYptjXf2dty1obGCJpjuax/F9BQRrtKSaz9kCcMW3Z0UJ00PzwsRGR42hJOk5M4ch+5KcnJd9L0qsq//rBvuI0xT705WKsG994UqLliVOjyXQltRxmhGx/64mPWgN2b5vo5Ik7XVuoeYMXFRLWPYYJw8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906602; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=JEHnZl4YADHNWK7TNk7/iWZzROyNDdjEmMHtpAgiEoE=; b=BUkJCAAvJGZmuMMKKCjY6M91XsUBh3NBxSfCjxHnO4ZCIfgJdGs4gdReeDiJJOZkUoLt/eLzZo7k7DXBiQywH1txuqD1t2k5pdB5EM5uxqn4nFAEz96DthDtuczbqvlt7h/GpXXIfg+7MnmCtAnmPhiaoBEz41XCGz5GwzKAwu8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.65 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wr1-f65.google.com (mail-wr1-f65.google.com [209.85.221.65]) by mx.zohomail.com with SMTPS id 1605906602853132.73597897853472; Fri, 20 Nov 2020 13:10:02 -0800 (PST) Received: by mail-wr1-f65.google.com with SMTP id p1so11648463wrf.12 for ; Fri, 20 Nov 2020 13:10:02 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id r9sm7081829wrg.59.2020.11.20.13.09.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JEHnZl4YADHNWK7TNk7/iWZzROyNDdjEmMHtpAgiEoE=; b=FmBsuO3NLt3j/xxyd1q3DSWYS3iWvp+KYaLJ4Ia7sTlqM0LkWnuLO4ivEWFd+Z/0V3 2IHPUY4OXjuUjtLKf8SxWi4kHcpKKZPtUf1QVImhiuBY5VI3T893wyZgWhkeUFwwi06e eCCEhY6XaxwcqBZY84ack2VDU5Sea29GZsihft+lZ3+fXfJtwFLTM0SQ77LWKxYNSRbl wkderKC/o4m2SwxqNBNVEUgs+HR28WzHy+hhHADrmxrOFE4rmDo7IetZP7/ItHiOtuim EizlzPPnG0e8ACrweNuwARhE5DrW21ffB5kRK3eMIcJg6soUaKVQZpzH9sdzwwkgbNSt RfcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=JEHnZl4YADHNWK7TNk7/iWZzROyNDdjEmMHtpAgiEoE=; b=hadfqNXOT217ou+dCSVbeeRy+mK3s6xflBMv4K4fajx1IuKH5Hrt0ItwPXmw5SUyAA z/UrgWTvJXyj3JwkGmht9hLrB7RDkWnQbsa8XviV0U5mYncuMLF3d6vtOLr8WIlQJjEj vNpFfg7kfFpqagTJcyLw6wr63PFBBcrUOLhsabkA/gKhkRmXA0N2JVDtVdmCY7+ajKpo bMo7Suq9ruutI7apkd5rU6BlQjMI4Sy77jQJ8ot+ygBjWGcimgjreJVPuubIGncR7Lqf Fwuz9WgsyqHzNDzdJlZblEiQiCk9N4R2WmPuuPHI23b1YLM66mNntmuiozPdX8p5EYYE IsHw== X-Gm-Message-State: AOAM532eNiJwL/gb9/HiYZB33/smoJRCS2BBYpTFAdIE55pVx0mjNN2I MY7+nPkVjN22mIyLkiGnMmA= X-Google-Smtp-Source: ABdhPJxLpvbPQU9WdLtOjPYTyNa7CsfXOf6CDfzI6e+Y8eC7/pFlpH/EIlxz6swOvjRvGf0vu9KckA== X-Received: by 2002:a5d:6cc5:: with SMTP id c5mr19342972wrc.301.1605906600988; Fri, 20 Nov 2020 13:10:00 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 14/26] target/mips: Extract NEC Vr54xx helper definitions Date: Fri, 20 Nov 2020 22:08:32 +0100 Message-Id: <20201120210844.2625602-15-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract the NEC Vr54xx helper definitions to 'vendor-vr54xx_helper.h'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/helper.h | 17 ++--------------- target/mips/vendor-vr54xx_helper.h.inc | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 target/mips/vendor-vr54xx_helper.h.inc diff --git a/target/mips/helper.h b/target/mips/helper.h index ee93c2de836..77d66018c8c 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -20,21 +20,6 @@ DEF_HELPER_3(lld, tl, env, tl, int) #endif #endif =20 -DEF_HELPER_3(muls, tl, env, tl, tl) -DEF_HELPER_3(mulsu, tl, env, tl, tl) -DEF_HELPER_3(macc, tl, env, tl, tl) -DEF_HELPER_3(maccu, tl, env, tl, tl) -DEF_HELPER_3(msac, tl, env, tl, tl) -DEF_HELPER_3(msacu, tl, env, tl, tl) -DEF_HELPER_3(mulhi, tl, env, tl, tl) -DEF_HELPER_3(mulhiu, tl, env, tl, tl) -DEF_HELPER_3(mulshi, tl, env, tl, tl) -DEF_HELPER_3(mulshiu, tl, env, tl, tl) -DEF_HELPER_3(macchi, tl, env, tl, tl) -DEF_HELPER_3(macchiu, tl, env, tl, tl) -DEF_HELPER_3(msachi, tl, env, tl, tl) -DEF_HELPER_3(msachiu, tl, env, tl, tl) - DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) #ifdef TARGET_MIPS64 DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl) @@ -424,3 +409,5 @@ DEF_HELPER_3(cache, void, env, tl, i32) #include "mod-mips-dsp_helper.h.inc" #include "mod-mips-msa_helper.h.inc" #include "mod-mips-mt_helper.h.inc" + +#include "vendor-vr54xx_helper.h.inc" diff --git a/target/mips/vendor-vr54xx_helper.h.inc b/target/mips/vendor-vr= 54xx_helper.h.inc new file mode 100644 index 00000000000..50b1f5b818d --- /dev/null +++ b/target/mips/vendor-vr54xx_helper.h.inc @@ -0,0 +1,24 @@ +/* + * MIPS NEC Vr54xx instruction emulation helpers for QEMU. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +DEF_HELPER_3(muls, tl, env, tl, tl) +DEF_HELPER_3(mulsu, tl, env, tl, tl) +DEF_HELPER_3(macc, tl, env, tl, tl) +DEF_HELPER_3(maccu, tl, env, tl, tl) +DEF_HELPER_3(msac, tl, env, tl, tl) +DEF_HELPER_3(msacu, tl, env, tl, tl) +DEF_HELPER_3(mulhi, tl, env, tl, tl) +DEF_HELPER_3(mulhiu, tl, env, tl, tl) +DEF_HELPER_3(mulshi, tl, env, tl, tl) +DEF_HELPER_3(mulshiu, tl, env, tl, tl) +DEF_HELPER_3(macchi, tl, env, tl, tl) +DEF_HELPER_3(macchiu, tl, env, tl, tl) +DEF_HELPER_3(msachi, tl, env, tl, tl) +DEF_HELPER_3(msachiu, tl, env, tl, tl) --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.43 as permitted sender) client-ip=209.85.221.43; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f43.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.43 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail(p=none dis=none) header.from=amsat.org ARC-Seal: i=1; a=rsa-sha256; t=1605906607; cv=none; d=zohomail.com; s=zohoarc; b=Vg/5Fg/k4f/VQXGumcLuUzHnudavgQmsqvyHgl9AaZLpogxDz4ZvTzia36W10uFthCzxZTt7LPxF6UdS8ciAa3ScNCJp610skhadhAqWg9zOQdUC6o5KrcWKQ1vEJrkQWt5e8Bk7ANGxqb1lOpG+4fXupiq7nzOkrymYILPOU+c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906607; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=yEPTreAcbmYuWQ/wNZf45C6fc4wRRcv0srLw4kg+KsE=; b=lG4XCilvo/7pck+BetpFOBLTm4lhZY2/ZgfQ9PB7BUb6s3zWWtWdFGcG+faFTV1bDXLGrSZ/CWDvk4NS/4/Ehz2Wi7A/CdYjouasbpLD4J6bGK5HUXjsVnTcq7VnUClNfA0uJ6r5xCiMSzNyGPA17fOXM1eSvca9HiSpe8aoeY0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.43 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) by mx.zohomail.com with SMTPS id 160590660785774.30911288604989; Fri, 20 Nov 2020 13:10:07 -0800 (PST) Received: by mail-wr1-f43.google.com with SMTP id o15so11708375wru.6 for ; Fri, 20 Nov 2020 13:10:07 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id w186sm5417507wmb.26.2020.11.20.13.10.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yEPTreAcbmYuWQ/wNZf45C6fc4wRRcv0srLw4kg+KsE=; b=RVbt5BO3aY2rd/K4BEnZA/k7HLmYBwURaXB0YTkE0eeoX39OnNnehbCsKe6wWh/Ma2 p5w4nLyABYEW4nnWmKn2UjRe/RLQNdGW4sDIMsaGkhqypIn8ehQYu4HYYTRZpeHJVFR9 mCV5voyNHrFSNVabIhz6JgWTKkKYXbIWF2GpfPYBnK3ea2Y01DyuwtLMDbDgVpoPtgeC RR4cP6X7UZsqurcBCOYX5MkSaBF+ZJS3HI+vIPHuIuiPeHlpif02AMdFmJYmDvd4l1QB PiQ+5mvNqFKWwbJ8WAlZOfg7WbrWnW3ecQ9Mx09UERWBf6EGC5AF2s9DChSm+SpFlM8r Zqtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=yEPTreAcbmYuWQ/wNZf45C6fc4wRRcv0srLw4kg+KsE=; b=npBxlB00vaWfdcK5sTVPyIMVn+mImrlE1UurgmR54K2Y5/YLQ8071FKhvDk40A56i9 XX/hyMn82uJEfihXueMx3npZ7JFmtbbkqvkEaPrqyJE658yPyyJxWfBenSQBVQczDivQ O9wx13CAbN9tS6BGuMBscXEwQoLQa/eJ6WCoGZQdf1SwYw/Iv/1cDc12fI2DNSH08nuF Q+FeGqzsQwQjya9quFl35ksYGM9ak2UvI86MtDSq7ht9aHi2v/5sIH9UZ/7oUCNO2Tlw RmR0cMWYBFxyYEw+utwPC+qIoQn6fcA53uirdgmOTsBV9r/bttNzZ77s7IfouGztuTfa UHWg== X-Gm-Message-State: AOAM530x8j5o5DvxdtX5jL9eE8UArKfWo7xX7oRJjVPJX0JLC5YOKlEw yJWVl9TJVkkYYvugNbjtqEo= X-Google-Smtp-Source: ABdhPJxqkJB7aYRijiVJL7s5nyKRmLXfIBurxYsRZI1v+TtDEAkMJ9UtR7xj+Rp9luiEnca1qPS2hw== X-Received: by 2002:a5d:5222:: with SMTP id i2mr19165213wra.247.1605906605979; Fri, 20 Nov 2020 13:10:05 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 15/26] target/mips: Extract NEC Vr54xx translation routines Date: Fri, 20 Nov 2020 22:08:33 +0100 Message-Id: <20201120210844.2625602-16-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract the NEC Vr54xx translation routines to 'vendor-vr54xx_translate.c.inc'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/translate.c | 86 +-------------------- target/mips/vendor-vr54xx_translate.c.inc | 93 +++++++++++++++++++++++ 2 files changed, 95 insertions(+), 84 deletions(-) create mode 100644 target/mips/vendor-vr54xx_translate.c.inc diff --git a/target/mips/translate.c b/target/mips/translate.c index 095ee31ab5f..b01a16e9da4 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -295,26 +295,6 @@ enum { OPC_DLSA =3D 0x15 | OPC_SPECIAL, }; =20 -/* Multiplication variants of the vr54xx. */ -#define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6))) - -enum { - OPC_VR54XX_MULS =3D (0x03 << 6) | OPC_MULT, - OPC_VR54XX_MULSU =3D (0x03 << 6) | OPC_MULTU, - OPC_VR54XX_MACC =3D (0x05 << 6) | OPC_MULT, - OPC_VR54XX_MACCU =3D (0x05 << 6) | OPC_MULTU, - OPC_VR54XX_MSAC =3D (0x07 << 6) | OPC_MULT, - OPC_VR54XX_MSACU =3D (0x07 << 6) | OPC_MULTU, - OPC_VR54XX_MULHI =3D (0x09 << 6) | OPC_MULT, - OPC_VR54XX_MULHIU =3D (0x09 << 6) | OPC_MULTU, - OPC_VR54XX_MULSHI =3D (0x0B << 6) | OPC_MULT, - OPC_VR54XX_MULSHIU =3D (0x0B << 6) | OPC_MULTU, - OPC_VR54XX_MACCHI =3D (0x0D << 6) | OPC_MULT, - OPC_VR54XX_MACCHIU =3D (0x0D << 6) | OPC_MULTU, - OPC_VR54XX_MSACHI =3D (0x0F << 6) | OPC_MULT, - OPC_VR54XX_MSACHIU =3D (0x0F << 6) | OPC_MULTU, -}; - /* REGIMM (rt field) opcodes */ #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16= ))) =20 @@ -4546,70 +4526,6 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t= opc, tcg_temp_free(t1); } =20 -static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc, - int rd, int rs, int rt) -{ - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - - switch (opc) { - case OPC_VR54XX_MULS: - gen_helper_muls(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MULSU: - gen_helper_mulsu(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MACC: - gen_helper_macc(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MACCU: - gen_helper_maccu(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MSAC: - gen_helper_msac(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MSACU: - gen_helper_msacu(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MULHI: - gen_helper_mulhi(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MULHIU: - gen_helper_mulhiu(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MULSHI: - gen_helper_mulshi(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MULSHIU: - gen_helper_mulshiu(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MACCHI: - gen_helper_macchi(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MACCHIU: - gen_helper_macchiu(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MSACHI: - gen_helper_msachi(t0, cpu_env, t0, t1); - break; - case OPC_VR54XX_MSACHIU: - gen_helper_msachiu(t0, cpu_env, t0, t1); - break; - default: - MIPS_INVAL("mul vr54xx"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - gen_store_gpr(t0, rd); - - out: - tcg_temp_free(t0); - tcg_temp_free(t1); -} - static void gen_cl(DisasContext *ctx, uint32_t opc, int rd, int rs) { @@ -13022,6 +12938,8 @@ out: =20 #include "mod-mips-dsp_translate.c.inc" =20 +#include "vendor-vr54xx_translate.c.inc" + static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) { int rs, rt, rd, sa; diff --git a/target/mips/vendor-vr54xx_translate.c.inc b/target/mips/vendor= -vr54xx_translate.c.inc new file mode 100644 index 00000000000..8c952a98ebc --- /dev/null +++ b/target/mips/vendor-vr54xx_translate.c.inc @@ -0,0 +1,93 @@ +/* + * MIPS NEC Vr54xx translation routines. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +/* Multiplication variants of the vr54xx. */ +#define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6))) + +enum { + OPC_VR54XX_MULS =3D (0x03 << 6) | OPC_MULT, + OPC_VR54XX_MULSU =3D (0x03 << 6) | OPC_MULTU, + OPC_VR54XX_MACC =3D (0x05 << 6) | OPC_MULT, + OPC_VR54XX_MACCU =3D (0x05 << 6) | OPC_MULTU, + OPC_VR54XX_MSAC =3D (0x07 << 6) | OPC_MULT, + OPC_VR54XX_MSACU =3D (0x07 << 6) | OPC_MULTU, + OPC_VR54XX_MULHI =3D (0x09 << 6) | OPC_MULT, + OPC_VR54XX_MULHIU =3D (0x09 << 6) | OPC_MULTU, + OPC_VR54XX_MULSHI =3D (0x0B << 6) | OPC_MULT, + OPC_VR54XX_MULSHIU =3D (0x0B << 6) | OPC_MULTU, + OPC_VR54XX_MACCHI =3D (0x0D << 6) | OPC_MULT, + OPC_VR54XX_MACCHIU =3D (0x0D << 6) | OPC_MULTU, + OPC_VR54XX_MSACHI =3D (0x0F << 6) | OPC_MULT, + OPC_VR54XX_MSACHIU =3D (0x0F << 6) | OPC_MULTU, +}; + +static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc, + int rd, int rs, int rt) +{ + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + + switch (opc) { + case OPC_VR54XX_MULS: + gen_helper_muls(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MULSU: + gen_helper_mulsu(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MACC: + gen_helper_macc(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MACCU: + gen_helper_maccu(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MSAC: + gen_helper_msac(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MSACU: + gen_helper_msacu(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MULHI: + gen_helper_mulhi(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MULHIU: + gen_helper_mulhiu(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MULSHI: + gen_helper_mulshi(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MULSHIU: + gen_helper_mulshiu(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MACCHI: + gen_helper_macchi(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MACCHIU: + gen_helper_macchiu(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MSACHI: + gen_helper_msachi(t0, cpu_env, t0, t1); + break; + case OPC_VR54XX_MSACHIU: + gen_helper_msachiu(t0, cpu_env, t0, t1); + break; + default: + MIPS_INVAL("mul vr54xx"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + gen_store_gpr(t0, rd); + + out: + tcg_temp_free(t0); + tcg_temp_free(t1); +} --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.68 as permitted sender) client-ip=209.85.128.68; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f68.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.68 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906613; cv=none; d=zohomail.com; s=zohoarc; b=EdDo/+0+cSyrxB5acKDjq4f0lvfKJ8XpBYB5HfkiqqskASJjpq/VPLI7OQwaObxQvqr/0rB1DrmS7xaMMztvgpaHO+phnofCkBOsCNa1rSf3chGMOL3olVZsObWl6P5eGz60QCg3vRvWQrtBBXbIE7ytw31sWyLop1esD7hknco= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906613; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=0+8w6ImWecSqTCfHwLUXCfd+P5NiNx/WvPTWih6RYyo=; b=NYPNXV7x80YjBr3glf7svNi+1QDSqSHlfzptpVCJ/+jNDgAKV/0xicgFoiosS7tBZJQl5Vh3pSu379ol47FUS7IFeSejOsUdBTaDi/KXoRywUWDGtyNEsWfZhbJJGlRVPuMN6Jps23jYZc8qPxwqVOlxyapOu3gE6mvRUL4dQ+A= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.68 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by mx.zohomail.com with SMTPS id 1605906613148608.8012204966877; Fri, 20 Nov 2020 13:10:13 -0800 (PST) Received: by mail-wm1-f68.google.com with SMTP id a65so11267118wme.1 for ; Fri, 20 Nov 2020 13:10:12 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id i10sm6845357wrs.22.2020.11.20.13.10.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0+8w6ImWecSqTCfHwLUXCfd+P5NiNx/WvPTWih6RYyo=; b=pkTNOvB8y+OJrLv8XH7UxY7qKIJUp9HWlgtIbr4Oee45ESlB0oGO3acFYXDvChJfuk JJXdgTmg+jJJsNc837QWZ+KIoOZqnawjFPBvuWlcYy0ZEFu12duRZoOcuGGaWBaADIKs Py6TGiRLRGd2FsUmHmtNRsT7qqr5wJ2Upcz2tvI6iB7KdpAQot9LXwzfEko7jagGn9Z7 ll9/YgT7yKpxtENtQQrFjR5IvvI4zQs0rvhR6SaMkAv+QXOzELua2uwVnrfUa40Ymo+0 4INX8IOfPZbTgeryQBwhJrc/bibARCA57EivkDPfGbOTSeUhZ5nfzdKXFnsHEA2FFTJe yEuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=0+8w6ImWecSqTCfHwLUXCfd+P5NiNx/WvPTWih6RYyo=; b=PKDU/sv4AtVuBLdZFcx6v/20s5TH70tDjEE/ksdpqkr/R151s+vLdfevIajalSONJA msePt8zlIR4gv0qCeSiiBd/UAF9u5vY5HJ5NDEVUZM5B5jF803pRA4YYdn5Q1/GDzSrk //Du+gHPQEdGpgTAgJYlG6gWfOVh/bmUopvQnbXzw4pI8uec3m+kN4yLfcfyN7qDYVnU qby6E0e8s+YkIbJeWcSX7+z9/1tj3E23lMTJ84XJaHB2Tm1KyV3tLgcsrFPnUtgUVhP4 AliPVwMrZfThDB4p/wY8i3zK1NyOJZPN7yP3FrwnfkHvJmnEZo5qI6ZaN1GeRQCZEyuo Fo7w== X-Gm-Message-State: AOAM530xdZGaccPqGfuoWwAiaYhjOF1SHXZfwJzzADNh042hXdu3YFH4 i2O3FcHJsPmN4bJK1vH1GtE= X-Google-Smtp-Source: ABdhPJwCIMNdi8KuCnWJZjUu/GQRCPiA/Z4qFnmC7EL7gx+d3s4WLNmjHYwiZEqWrlnNYZ7zQwLzzg== X-Received: by 2002:a1c:44d4:: with SMTP id r203mr11817646wma.60.1605906611337; Fri, 20 Nov 2020 13:10:11 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 16/26] target/mips: Rename lmmi_helper.c as loong-simd_helper.c Date: Fri, 20 Nov 2020 22:08:34 +0100 Message-Id: <20201120210844.2625602-17-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) The LoongMMI extension has been renamed LoongSIMD (part of the LoongISA). Rename the helper file accordingly. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/{lmmi_helper.c =3D> vendor-loong-simd_helper.c} | 0 target/mips/meson.build | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename target/mips/{lmmi_helper.c =3D> vendor-loong-simd_helper.c} (100%) diff --git a/target/mips/lmmi_helper.c b/target/mips/vendor-loong-simd_help= er.c similarity index 100% rename from target/mips/lmmi_helper.c rename to target/mips/vendor-loong-simd_helper.c diff --git a/target/mips/meson.build b/target/mips/meson.build index b63ef41cb1d..e8f0c080099 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -4,10 +4,10 @@ 'fpu_helper.c', 'gdbstub.c', 'helper.c', - 'lmmi_helper.c', 'op_helper.c', 'mod-mips-dsp_helper.c', 'mod-mips-msa_helper.c', + 'vendor-loong-simd_helper.c', 'vendor-vr54xx_helper.c', =20 'translate.c', --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.67 as permitted sender) client-ip=209.85.221.67; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f67.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.67 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906618; cv=none; d=zohomail.com; s=zohoarc; b=cOhONEnMiCbHV6aZhZ7nulLYzmwNqhszK8Qwnp8EpN9aAzZSk/TwE7PPFVDiwN1lslrR8FrVYI048P4UsoUqf+XHKr1CREf50AXbKholcP71Dy7nOfT2z9own4/G9PTmOibtHPhTgiCp30Es/GrhevA/WZJZy8iua9du9t+rCiY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906618; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=mGpWJo81sEg14F0La+W267Kh3e04560JtsIKJ6WctAs=; b=OeJhpXDwZftVtKV+HnGey5KzW9BRyjcs6pjtcRkqGRJSUrJz+Bc63wijjMTHyOuhdz75IFl+89rau9ywKfUvwHB8IpwH942DKQMJlq0Lnt5kZKTO8JCUE/Ef23wbq5lnAVijZvjnHEDh6mmcXj6Z+5YHG9LcQvtPrwhyxsrRS20= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.67 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) by mx.zohomail.com with SMTPS id 1605906618112922.3181470844761; Fri, 20 Nov 2020 13:10:18 -0800 (PST) Received: by mail-wr1-f67.google.com with SMTP id c17so11656776wrc.11 for ; Fri, 20 Nov 2020 13:10:17 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id d3sm6542024wrg.16.2020.11.20.13.10.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mGpWJo81sEg14F0La+W267Kh3e04560JtsIKJ6WctAs=; b=s9H+wkgh8r+Is1lPC9kHaVcMvST7hZOA/2SrnOXoq0dUyvjQ1/EcBA2a/03u8aWTAm 2XnQmj7IUeMUfpMRXD48gKeuz1MxwKXTgfp//96qaA5LTD15tyg9RQjg9p7wR1U0FvCT WAt0GN0vkD0hXKNsNSsa57tWYdqqZe+/IJDqz9Fote9h2LxOLi5y/JTEz1aAUUonarW6 2lO9FQvCN3ISnZwCHQBh7DX0nvi3pk2L6wXuPlTM0un7LcFPmlRI0Vp3QXjDy5aIfPd5 Ogg7Uf509E1ZV8AnSQKKrOOaLnhromBsDMClJJLmtmLFeFU2QrjKQLlbYaSa1k8tNuQA vlhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=mGpWJo81sEg14F0La+W267Kh3e04560JtsIKJ6WctAs=; b=PvZdnKhhUYyEfHbXIuzDWr3uSEnOXO3phyfJUqOKL6P7WLwHwON/9ldpnhdMhwiA9i TNSh0/Vem9dm5o1OrRL4beAqzN/jN83tNpPz30ASL+zqZwgTNUas/Eeyt5Y/jdIFlEJ4 DD+dkD2kGUE1m/+Qs/MWzMx4AbuXc0TsjUHnssT0SyEEnAjDW+kNktGZ7rkN0xXhLxK1 WZqiMVQT9buq5/YEErjVjB87mQbTLLbFASVvU6WhJ9b0Qx7so71Vn3LUHz+ZETddu7FX ZRvpGhvt3oYUgQeGWKmIMaiQLsPPyCAgrX2NQ6shxxx+0CtjFeGUCi6/5JzFrf3upzHF uhKg== X-Gm-Message-State: AOAM530jJTDk3Db68jkxkmLLVOnjhUjZkgvnatOo3v9AF/0OCuesP7zc Ymb3axn/XtRMrqrnaC5G+lg= X-Google-Smtp-Source: ABdhPJyT83mp/scHb82XhBnzPZwIfyXE/LFPmg82pmZVsMxV4Arn5Gyur3DCBhGXFnarxHZXwmP97w== X-Received: by 2002:adf:9144:: with SMTP id j62mr19053439wrj.419.1605906616303; Fri, 20 Nov 2020 13:10:16 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 17/26] target/mips: Extract Loongson SIMD helper definitions Date: Fri, 20 Nov 2020 22:08:35 +0100 Message-Id: <20201120210844.2625602-18-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract the Loongson SIMD helper definitions to 'vendor-loong-simd_helper.h'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/helper.h | 60 +------------------ target/mips/vendor-loong-simd_helper.h.inc | 69 ++++++++++++++++++++++ 2 files changed, 70 insertions(+), 59 deletions(-) create mode 100644 target/mips/vendor-loong-simd_helper.h.inc diff --git a/target/mips/helper.h b/target/mips/helper.h index 77d66018c8c..134dcaf0d59 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -343,65 +343,6 @@ DEF_HELPER_1(rdhwr_xnp, tl, env) DEF_HELPER_2(pmon, void, env, int) DEF_HELPER_1(wait, void, env) =20 -/* Loongson multimedia functions. */ -DEF_HELPER_FLAGS_2(paddsh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(paddush, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(paddh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(paddw, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(paddsb, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(paddusb, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(paddb, TCG_CALL_NO_RWG_SE, i64, i64, i64) - -DEF_HELPER_FLAGS_2(psubsh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psubush, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psubh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psubw, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psubsb, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psubusb, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psubb, TCG_CALL_NO_RWG_SE, i64, i64, i64) - -DEF_HELPER_FLAGS_2(pshufh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(packsswh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(packsshb, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(packushb, TCG_CALL_NO_RWG_SE, i64, i64, i64) - -DEF_HELPER_FLAGS_2(punpcklhw, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(punpckhhw, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(punpcklbh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(punpckhbh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(punpcklwd, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(punpckhwd, TCG_CALL_NO_RWG_SE, i64, i64, i64) - -DEF_HELPER_FLAGS_2(pavgh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pavgb, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pmaxsh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pminsh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pmaxub, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pminub, TCG_CALL_NO_RWG_SE, i64, i64, i64) - -DEF_HELPER_FLAGS_2(pcmpeqw, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pcmpgtw, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pcmpeqh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pcmpgth, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pcmpeqb, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pcmpgtb, TCG_CALL_NO_RWG_SE, i64, i64, i64) - -DEF_HELPER_FLAGS_2(psllw, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psllh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psrlw, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psrlh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psraw, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(psrah, TCG_CALL_NO_RWG_SE, i64, i64, i64) - -DEF_HELPER_FLAGS_2(pmullh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pmulhh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pmulhuh, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(pmaddhw, TCG_CALL_NO_RWG_SE, i64, i64, i64) - -DEF_HELPER_FLAGS_2(pasubub, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_1(biadd, TCG_CALL_NO_RWG_SE, i64, i64) -DEF_HELPER_FLAGS_1(pmovmskb, TCG_CALL_NO_RWG_SE, i64, i64) - DEF_HELPER_3(cache, void, env, tl, i32) =20 #include "isa-micromips_helper.h.inc" @@ -411,3 +352,4 @@ DEF_HELPER_3(cache, void, env, tl, i32) #include "mod-mips-mt_helper.h.inc" =20 #include "vendor-vr54xx_helper.h.inc" +#include "vendor-loong-simd_helper.h.inc" diff --git a/target/mips/vendor-loong-simd_helper.h.inc b/target/mips/vendo= r-loong-simd_helper.h.inc new file mode 100644 index 00000000000..30e5fda66e9 --- /dev/null +++ b/target/mips/vendor-loong-simd_helper.h.inc @@ -0,0 +1,69 @@ +/* + * Loongson SIMD instruction emulation helpers for QEMU. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2011 Richard Henderson + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +DEF_HELPER_FLAGS_2(paddsh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(paddush, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(paddh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(paddw, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(paddsb, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(paddusb, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(paddb, TCG_CALL_NO_RWG_SE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(psubsh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psubush, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psubh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psubw, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psubsb, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psubusb, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psubb, TCG_CALL_NO_RWG_SE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(pshufh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(packsswh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(packsshb, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(packushb, TCG_CALL_NO_RWG_SE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(punpcklhw, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(punpckhhw, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(punpcklbh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(punpckhbh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(punpcklwd, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(punpckhwd, TCG_CALL_NO_RWG_SE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(pavgh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pavgb, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pmaxsh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pminsh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pmaxub, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pminub, TCG_CALL_NO_RWG_SE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(pcmpeqw, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pcmpgtw, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pcmpeqh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pcmpgth, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pcmpeqb, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pcmpgtb, TCG_CALL_NO_RWG_SE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(psllw, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psllh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psrlw, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psrlh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psraw, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(psrah, TCG_CALL_NO_RWG_SE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(pmullh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pmulhh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pmulhuh, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(pmaddhw, TCG_CALL_NO_RWG_SE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(pasubub, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_1(biadd, TCG_CALL_NO_RWG_SE, i64, i64) +DEF_HELPER_FLAGS_1(pmovmskb, TCG_CALL_NO_RWG_SE, i64, i64) --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.42 as permitted sender) client-ip=209.85.128.42; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f42.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.42 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906623; cv=none; d=zohomail.com; s=zohoarc; b=BE/rnwm2VH+y+QkI1H8UBxZPsptSq80Gsh7HzQmzlJyRkY5Z7f26TIRoDhHcJVVq8ThEpZStvOYLGwQ0GZM8PqOswAsdcTnK51mIM/P3YPmQ+8EdW09lBQ8QDFX8wY2Yt5PCoB7I2whtoitQHb1WXSXfMGWFoAVPWLZiaq9wPto= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906623; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=KfAp08XE0D2s8Fjwe59WUfdrK7InEGIvBOoZZbDUm/0=; b=ZjuaIrY+O5x65ni1IMm5C4QqwSbV2qhOvkgek+jqrLOvAKCTCFxZoNGf2RRma/OHMz/LGUaKKLcwouS9JEhW5/YxHaG4I6BwRd6h/snp0sapeF4xDAvTvxs1dMHl9TtW89iobL7Z/ahOUbdxTsz8hflByqmu/65KmFrHZmYQAgw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.42 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) by mx.zohomail.com with SMTPS id 1605906623889759.6125705093616; Fri, 20 Nov 2020 13:10:23 -0800 (PST) Received: by mail-wm1-f42.google.com with SMTP id s13so11247595wmh.4 for ; Fri, 20 Nov 2020 13:10:23 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id a9sm6177162wrp.21.2020.11.20.13.10.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KfAp08XE0D2s8Fjwe59WUfdrK7InEGIvBOoZZbDUm/0=; b=WOddeF5891lhkwUQdyXB7EIkLhRCqhXisRaEPwURomX3TyMt+azAYpXiE0q7SJeaRX YHTHnJw/wK19Zz0d6rVMThFwGocVCT7FnlrLry5jApDPiIgb1STOR0nqSl3h6OVskH/4 CFROJZwrLhjRNp4xJ5JrSBa4VtyA0P2jN8t5vdzyTHy7KzK5+xXW8o8iCaU9wpuRGy2R XEqJfK11STOVO2GrlfKt2fOBu8swQdq6jECM8MSKCuw+Nisu2j72KiSZCVIx7K8sH+y6 qqB4lZYcWVjaYHUe6xcyOXKpZ0s2PMOgcXG3r4MAapNBiGLUbDGFecobK2lN2SSycfSA ufbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=KfAp08XE0D2s8Fjwe59WUfdrK7InEGIvBOoZZbDUm/0=; b=Ei8NCJXz0If55btAZrA4sWBcmnjstlQl6OyUG8sAISfG8x0TdluX7aGnSWLMErDJbD vMTycUYMoS2HYLU69Wk0YE3YhI2PLvPYdp+ghptUYLkbSixWKTpbak3e9J9d/RZUT+CI IgedJ1AQpEbkwM/VmycE1D2krJr8kVGiL1s2aI2NPkZUqP9Yt5RihcJqPvdDO4KGlqno cFpaQF1d+ESb6zKeMHvi8igDvIZf0Tbe1yTjMKY/KLw00rURQeQ0Q2L4iRjagtNdQM4C /PYV7Urg7TiFwx+vvse5G93BSt/dYDw0p6NEi2/J+ZC7x3epFp+YPeB2H+3f01PQ6wJL QjLw== X-Gm-Message-State: AOAM530o5wXZwwjOBtE2HAKII+c9vT/CK8Px9SNxkp8seWGmv0dJWZzl u3lkqEMxqbK804VH40Braps= X-Google-Smtp-Source: ABdhPJy6UB6VIvI1hU8iZ8g7/vcp7+5px1D6ABX7IOF7EUmpu0ba8XUHSkP/gY+dkZabyiM2lRVuvA== X-Received: by 2002:a1c:9ec9:: with SMTP id h192mr11859866wme.8.1605906621631; Fri, 20 Nov 2020 13:10:21 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 18/26] target/mips: Extract Loongson SIMD translation routines Date: Fri, 20 Nov 2020 22:08:36 +0100 Message-Id: <20201120210844.2625602-19-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) LoongSIMD (formerly LoongMMI in Loongson 2E/F) is the 128-bit SIMD extension from the LoongISA. Extract 600 lines of translation routines to 'vendor-loong-simd_translate.c.inc'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/translate.c | 598 +---------------- target/mips/vendor-loong-simd_translate.c.inc | 611 ++++++++++++++++++ 2 files changed, 612 insertions(+), 597 deletions(-) create mode 100644 target/mips/vendor-loong-simd_translate.c.inc diff --git a/target/mips/translate.c b/target/mips/translate.c index b01a16e9da4..105a104bb0c 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -330,19 +330,6 @@ enum { OPC_MUL =3D 0x02 | OPC_SPECIAL2, OPC_MSUB =3D 0x04 | OPC_SPECIAL2, OPC_MSUBU =3D 0x05 | OPC_SPECIAL2, - /* Loongson 2F */ - OPC_MULT_G_2F =3D 0x10 | OPC_SPECIAL2, - OPC_DMULT_G_2F =3D 0x11 | OPC_SPECIAL2, - OPC_MULTU_G_2F =3D 0x12 | OPC_SPECIAL2, - OPC_DMULTU_G_2F =3D 0x13 | OPC_SPECIAL2, - OPC_DIV_G_2F =3D 0x14 | OPC_SPECIAL2, - OPC_DDIV_G_2F =3D 0x15 | OPC_SPECIAL2, - OPC_DIVU_G_2F =3D 0x16 | OPC_SPECIAL2, - OPC_DDIVU_G_2F =3D 0x17 | OPC_SPECIAL2, - OPC_MOD_G_2F =3D 0x1c | OPC_SPECIAL2, - OPC_DMOD_G_2F =3D 0x1d | OPC_SPECIAL2, - OPC_MODU_G_2F =3D 0x1e | OPC_SPECIAL2, - OPC_DMODU_G_2F =3D 0x1f | OPC_SPECIAL2, /* Misc */ OPC_CLZ =3D 0x20 | OPC_SPECIAL2, OPC_CLO =3D 0x21 | OPC_SPECIAL2, @@ -4569,590 +4556,6 @@ static void gen_cl(DisasContext *ctx, uint32_t opc, } } =20 -/* Godson integer instructions */ -static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, - int rd, int rs, int rt) -{ - TCGv t0, t1; - - if (rd =3D=3D 0) { - /* Treat as NOP. */ - return; - } - - switch (opc) { - case OPC_MULT_G_2E: - case OPC_MULT_G_2F: - case OPC_MULTU_G_2E: - case OPC_MULTU_G_2F: -#if defined(TARGET_MIPS64) - case OPC_DMULT_G_2E: - case OPC_DMULT_G_2F: - case OPC_DMULTU_G_2E: - case OPC_DMULTU_G_2F: -#endif - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - break; - default: - t0 =3D tcg_temp_local_new(); - t1 =3D tcg_temp_local_new(); - break; - } - - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - - switch (opc) { - case OPC_MULT_G_2E: - case OPC_MULT_G_2F: - tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); - tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); - break; - case OPC_MULTU_G_2E: - case OPC_MULTU_G_2F: - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_ext32u_tl(t1, t1); - tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); - tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); - break; - case OPC_DIV_G_2E: - case OPC_DIV_G_2F: - { - TCGLabel *l1 =3D gen_new_label(); - TCGLabel *l2 =3D gen_new_label(); - TCGLabel *l3 =3D gen_new_label(); - tcg_gen_ext32s_tl(t0, t0); - tcg_gen_ext32s_tl(t1, t1); - tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); - tcg_gen_movi_tl(cpu_gpr[rd], 0); - tcg_gen_br(l3); - gen_set_label(l1); - tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); - tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); - tcg_gen_mov_tl(cpu_gpr[rd], t0); - tcg_gen_br(l3); - gen_set_label(l2); - tcg_gen_div_tl(cpu_gpr[rd], t0, t1); - tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); - gen_set_label(l3); - } - break; - case OPC_DIVU_G_2E: - case OPC_DIVU_G_2F: - { - TCGLabel *l1 =3D gen_new_label(); - TCGLabel *l2 =3D gen_new_label(); - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_ext32u_tl(t1, t1); - tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); - tcg_gen_movi_tl(cpu_gpr[rd], 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); - tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); - gen_set_label(l2); - } - break; - case OPC_MOD_G_2E: - case OPC_MOD_G_2F: - { - TCGLabel *l1 =3D gen_new_label(); - TCGLabel *l2 =3D gen_new_label(); - TCGLabel *l3 =3D gen_new_label(); - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_ext32u_tl(t1, t1); - tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); - tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); - tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); - gen_set_label(l1); - tcg_gen_movi_tl(cpu_gpr[rd], 0); - tcg_gen_br(l3); - gen_set_label(l2); - tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); - tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); - gen_set_label(l3); - } - break; - case OPC_MODU_G_2E: - case OPC_MODU_G_2F: - { - TCGLabel *l1 =3D gen_new_label(); - TCGLabel *l2 =3D gen_new_label(); - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_ext32u_tl(t1, t1); - tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); - tcg_gen_movi_tl(cpu_gpr[rd], 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); - tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); - gen_set_label(l2); - } - break; -#if defined(TARGET_MIPS64) - case OPC_DMULT_G_2E: - case OPC_DMULT_G_2F: - tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); - break; - case OPC_DMULTU_G_2E: - case OPC_DMULTU_G_2F: - tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); - break; - case OPC_DDIV_G_2E: - case OPC_DDIV_G_2F: - { - TCGLabel *l1 =3D gen_new_label(); - TCGLabel *l2 =3D gen_new_label(); - TCGLabel *l3 =3D gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); - tcg_gen_movi_tl(cpu_gpr[rd], 0); - tcg_gen_br(l3); - gen_set_label(l1); - tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); - tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); - tcg_gen_mov_tl(cpu_gpr[rd], t0); - tcg_gen_br(l3); - gen_set_label(l2); - tcg_gen_div_tl(cpu_gpr[rd], t0, t1); - gen_set_label(l3); - } - break; - case OPC_DDIVU_G_2E: - case OPC_DDIVU_G_2F: - { - TCGLabel *l1 =3D gen_new_label(); - TCGLabel *l2 =3D gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); - tcg_gen_movi_tl(cpu_gpr[rd], 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); - gen_set_label(l2); - } - break; - case OPC_DMOD_G_2E: - case OPC_DMOD_G_2F: - { - TCGLabel *l1 =3D gen_new_label(); - TCGLabel *l2 =3D gen_new_label(); - TCGLabel *l3 =3D gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); - tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); - tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); - gen_set_label(l1); - tcg_gen_movi_tl(cpu_gpr[rd], 0); - tcg_gen_br(l3); - gen_set_label(l2); - tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); - gen_set_label(l3); - } - break; - case OPC_DMODU_G_2E: - case OPC_DMODU_G_2F: - { - TCGLabel *l1 =3D gen_new_label(); - TCGLabel *l2 =3D gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); - tcg_gen_movi_tl(cpu_gpr[rd], 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); - gen_set_label(l2); - } - break; -#endif - } - - tcg_temp_free(t0); - tcg_temp_free(t1); -} - -/* Loongson multimedia instructions */ -static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int= rt) -{ - uint32_t opc, shift_max; - TCGv_i64 t0, t1; - TCGCond cond; - - opc =3D MASK_LMMI(ctx->opcode); - switch (opc) { - case OPC_ADD_CP2: - case OPC_SUB_CP2: - case OPC_DADD_CP2: - case OPC_DSUB_CP2: - t0 =3D tcg_temp_local_new_i64(); - t1 =3D tcg_temp_local_new_i64(); - break; - default: - t0 =3D tcg_temp_new_i64(); - t1 =3D tcg_temp_new_i64(); - break; - } - - check_cp1_enabled(ctx); - gen_load_fpr64(ctx, t0, rs); - gen_load_fpr64(ctx, t1, rt); - - switch (opc) { - case OPC_PADDSH: - gen_helper_paddsh(t0, t0, t1); - break; - case OPC_PADDUSH: - gen_helper_paddush(t0, t0, t1); - break; - case OPC_PADDH: - gen_helper_paddh(t0, t0, t1); - break; - case OPC_PADDW: - gen_helper_paddw(t0, t0, t1); - break; - case OPC_PADDSB: - gen_helper_paddsb(t0, t0, t1); - break; - case OPC_PADDUSB: - gen_helper_paddusb(t0, t0, t1); - break; - case OPC_PADDB: - gen_helper_paddb(t0, t0, t1); - break; - - case OPC_PSUBSH: - gen_helper_psubsh(t0, t0, t1); - break; - case OPC_PSUBUSH: - gen_helper_psubush(t0, t0, t1); - break; - case OPC_PSUBH: - gen_helper_psubh(t0, t0, t1); - break; - case OPC_PSUBW: - gen_helper_psubw(t0, t0, t1); - break; - case OPC_PSUBSB: - gen_helper_psubsb(t0, t0, t1); - break; - case OPC_PSUBUSB: - gen_helper_psubusb(t0, t0, t1); - break; - case OPC_PSUBB: - gen_helper_psubb(t0, t0, t1); - break; - - case OPC_PSHUFH: - gen_helper_pshufh(t0, t0, t1); - break; - case OPC_PACKSSWH: - gen_helper_packsswh(t0, t0, t1); - break; - case OPC_PACKSSHB: - gen_helper_packsshb(t0, t0, t1); - break; - case OPC_PACKUSHB: - gen_helper_packushb(t0, t0, t1); - break; - - case OPC_PUNPCKLHW: - gen_helper_punpcklhw(t0, t0, t1); - break; - case OPC_PUNPCKHHW: - gen_helper_punpckhhw(t0, t0, t1); - break; - case OPC_PUNPCKLBH: - gen_helper_punpcklbh(t0, t0, t1); - break; - case OPC_PUNPCKHBH: - gen_helper_punpckhbh(t0, t0, t1); - break; - case OPC_PUNPCKLWD: - gen_helper_punpcklwd(t0, t0, t1); - break; - case OPC_PUNPCKHWD: - gen_helper_punpckhwd(t0, t0, t1); - break; - - case OPC_PAVGH: - gen_helper_pavgh(t0, t0, t1); - break; - case OPC_PAVGB: - gen_helper_pavgb(t0, t0, t1); - break; - case OPC_PMAXSH: - gen_helper_pmaxsh(t0, t0, t1); - break; - case OPC_PMINSH: - gen_helper_pminsh(t0, t0, t1); - break; - case OPC_PMAXUB: - gen_helper_pmaxub(t0, t0, t1); - break; - case OPC_PMINUB: - gen_helper_pminub(t0, t0, t1); - break; - - case OPC_PCMPEQW: - gen_helper_pcmpeqw(t0, t0, t1); - break; - case OPC_PCMPGTW: - gen_helper_pcmpgtw(t0, t0, t1); - break; - case OPC_PCMPEQH: - gen_helper_pcmpeqh(t0, t0, t1); - break; - case OPC_PCMPGTH: - gen_helper_pcmpgth(t0, t0, t1); - break; - case OPC_PCMPEQB: - gen_helper_pcmpeqb(t0, t0, t1); - break; - case OPC_PCMPGTB: - gen_helper_pcmpgtb(t0, t0, t1); - break; - - case OPC_PSLLW: - gen_helper_psllw(t0, t0, t1); - break; - case OPC_PSLLH: - gen_helper_psllh(t0, t0, t1); - break; - case OPC_PSRLW: - gen_helper_psrlw(t0, t0, t1); - break; - case OPC_PSRLH: - gen_helper_psrlh(t0, t0, t1); - break; - case OPC_PSRAW: - gen_helper_psraw(t0, t0, t1); - break; - case OPC_PSRAH: - gen_helper_psrah(t0, t0, t1); - break; - - case OPC_PMULLH: - gen_helper_pmullh(t0, t0, t1); - break; - case OPC_PMULHH: - gen_helper_pmulhh(t0, t0, t1); - break; - case OPC_PMULHUH: - gen_helper_pmulhuh(t0, t0, t1); - break; - case OPC_PMADDHW: - gen_helper_pmaddhw(t0, t0, t1); - break; - - case OPC_PASUBUB: - gen_helper_pasubub(t0, t0, t1); - break; - case OPC_BIADD: - gen_helper_biadd(t0, t0); - break; - case OPC_PMOVMSKB: - gen_helper_pmovmskb(t0, t0); - break; - - case OPC_PADDD: - tcg_gen_add_i64(t0, t0, t1); - break; - case OPC_PSUBD: - tcg_gen_sub_i64(t0, t0, t1); - break; - case OPC_XOR_CP2: - tcg_gen_xor_i64(t0, t0, t1); - break; - case OPC_NOR_CP2: - tcg_gen_nor_i64(t0, t0, t1); - break; - case OPC_AND_CP2: - tcg_gen_and_i64(t0, t0, t1); - break; - case OPC_OR_CP2: - tcg_gen_or_i64(t0, t0, t1); - break; - - case OPC_PANDN: - tcg_gen_andc_i64(t0, t1, t0); - break; - - case OPC_PINSRH_0: - tcg_gen_deposit_i64(t0, t0, t1, 0, 16); - break; - case OPC_PINSRH_1: - tcg_gen_deposit_i64(t0, t0, t1, 16, 16); - break; - case OPC_PINSRH_2: - tcg_gen_deposit_i64(t0, t0, t1, 32, 16); - break; - case OPC_PINSRH_3: - tcg_gen_deposit_i64(t0, t0, t1, 48, 16); - break; - - case OPC_PEXTRH: - tcg_gen_andi_i64(t1, t1, 3); - tcg_gen_shli_i64(t1, t1, 4); - tcg_gen_shr_i64(t0, t0, t1); - tcg_gen_ext16u_i64(t0, t0); - break; - - case OPC_ADDU_CP2: - tcg_gen_add_i64(t0, t0, t1); - tcg_gen_ext32s_i64(t0, t0); - break; - case OPC_SUBU_CP2: - tcg_gen_sub_i64(t0, t0, t1); - tcg_gen_ext32s_i64(t0, t0); - break; - - case OPC_SLL_CP2: - shift_max =3D 32; - goto do_shift; - case OPC_SRL_CP2: - shift_max =3D 32; - goto do_shift; - case OPC_SRA_CP2: - shift_max =3D 32; - goto do_shift; - case OPC_DSLL_CP2: - shift_max =3D 64; - goto do_shift; - case OPC_DSRL_CP2: - shift_max =3D 64; - goto do_shift; - case OPC_DSRA_CP2: - shift_max =3D 64; - goto do_shift; - do_shift: - /* Make sure shift count isn't TCG undefined behaviour. */ - tcg_gen_andi_i64(t1, t1, shift_max - 1); - - switch (opc) { - case OPC_SLL_CP2: - case OPC_DSLL_CP2: - tcg_gen_shl_i64(t0, t0, t1); - break; - case OPC_SRA_CP2: - case OPC_DSRA_CP2: - /* - * Since SRA is UndefinedResult without sign-extended inputs, - * we can treat SRA and DSRA the same. - */ - tcg_gen_sar_i64(t0, t0, t1); - break; - case OPC_SRL_CP2: - /* We want to shift in zeros for SRL; zero-extend first. */ - tcg_gen_ext32u_i64(t0, t0); - /* FALLTHRU */ - case OPC_DSRL_CP2: - tcg_gen_shr_i64(t0, t0, t1); - break; - } - - if (shift_max =3D=3D 32) { - tcg_gen_ext32s_i64(t0, t0); - } - - /* Shifts larger than MAX produce zero. */ - tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); - tcg_gen_neg_i64(t1, t1); - tcg_gen_and_i64(t0, t0, t1); - break; - - case OPC_ADD_CP2: - case OPC_DADD_CP2: - { - TCGv_i64 t2 =3D tcg_temp_new_i64(); - TCGLabel *lab =3D gen_new_label(); - - tcg_gen_mov_i64(t2, t0); - tcg_gen_add_i64(t0, t1, t2); - if (opc =3D=3D OPC_ADD_CP2) { - tcg_gen_ext32s_i64(t0, t0); - } - tcg_gen_xor_i64(t1, t1, t2); - tcg_gen_xor_i64(t2, t2, t0); - tcg_gen_andc_i64(t1, t2, t1); - tcg_temp_free_i64(t2); - tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); - generate_exception(ctx, EXCP_OVERFLOW); - gen_set_label(lab); - break; - } - - case OPC_SUB_CP2: - case OPC_DSUB_CP2: - { - TCGv_i64 t2 =3D tcg_temp_new_i64(); - TCGLabel *lab =3D gen_new_label(); - - tcg_gen_mov_i64(t2, t0); - tcg_gen_sub_i64(t0, t1, t2); - if (opc =3D=3D OPC_SUB_CP2) { - tcg_gen_ext32s_i64(t0, t0); - } - tcg_gen_xor_i64(t1, t1, t2); - tcg_gen_xor_i64(t2, t2, t0); - tcg_gen_and_i64(t1, t1, t2); - tcg_temp_free_i64(t2); - tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); - generate_exception(ctx, EXCP_OVERFLOW); - gen_set_label(lab); - break; - } - - case OPC_PMULUW: - tcg_gen_ext32u_i64(t0, t0); - tcg_gen_ext32u_i64(t1, t1); - tcg_gen_mul_i64(t0, t0, t1); - break; - - case OPC_SEQU_CP2: - case OPC_SEQ_CP2: - cond =3D TCG_COND_EQ; - goto do_cc_cond; - break; - case OPC_SLTU_CP2: - cond =3D TCG_COND_LTU; - goto do_cc_cond; - break; - case OPC_SLT_CP2: - cond =3D TCG_COND_LT; - goto do_cc_cond; - break; - case OPC_SLEU_CP2: - cond =3D TCG_COND_LEU; - goto do_cc_cond; - break; - case OPC_SLE_CP2: - cond =3D TCG_COND_LE; - do_cc_cond: - { - int cc =3D (ctx->opcode >> 8) & 0x7; - TCGv_i64 t64 =3D tcg_temp_new_i64(); - TCGv_i32 t32 =3D tcg_temp_new_i32(); - - tcg_gen_setcond_i64(cond, t64, t0, t1); - tcg_gen_extrl_i64_i32(t32, t64); - tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, - get_fp_bit(cc), 1); - - tcg_temp_free_i32(t32); - tcg_temp_free_i64(t64); - } - goto no_rd; - break; - default: - MIPS_INVAL("loongson_cp2"); - generate_exception_end(ctx, EXCP_RI); - return; - } - - gen_store_fpr64(ctx, t0, rd); - -no_rd: - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -} - static void gen_loongson_lswc2(DisasContext *ctx, int rt, int rs, int rd) { @@ -12939,6 +12342,7 @@ out: #include "mod-mips-dsp_translate.c.inc" =20 #include "vendor-vr54xx_translate.c.inc" +#include "vendor-loong-simd_translate.c.inc" =20 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) { diff --git a/target/mips/vendor-loong-simd_translate.c.inc b/target/mips/ve= ndor-loong-simd_translate.c.inc new file mode 100644 index 00000000000..6ea7e9a9b82 --- /dev/null +++ b/target/mips/vendor-loong-simd_translate.c.inc @@ -0,0 +1,611 @@ +/* + * Loongson SIMD translation routines. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2011 Richard Henderson + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +enum { + /* Loongson 2F */ + OPC_MULT_G_2F =3D 0x10 | OPC_SPECIAL2, + OPC_DMULT_G_2F =3D 0x11 | OPC_SPECIAL2, + OPC_MULTU_G_2F =3D 0x12 | OPC_SPECIAL2, + OPC_DMULTU_G_2F =3D 0x13 | OPC_SPECIAL2, + OPC_DIV_G_2F =3D 0x14 | OPC_SPECIAL2, + OPC_DDIV_G_2F =3D 0x15 | OPC_SPECIAL2, + OPC_DIVU_G_2F =3D 0x16 | OPC_SPECIAL2, + OPC_DDIVU_G_2F =3D 0x17 | OPC_SPECIAL2, + OPC_MOD_G_2F =3D 0x1c | OPC_SPECIAL2, + OPC_DMOD_G_2F =3D 0x1d | OPC_SPECIAL2, + OPC_MODU_G_2F =3D 0x1e | OPC_SPECIAL2, + OPC_DMODU_G_2F =3D 0x1f | OPC_SPECIAL2, +}; + +/* Godson integer instructions */ +static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, + int rd, int rs, int rt) +{ + TCGv t0, t1; + + if (rd =3D=3D 0) { + /* Treat as NOP. */ + return; + } + + switch (opc) { + case OPC_MULT_G_2E: + case OPC_MULT_G_2F: + case OPC_MULTU_G_2E: + case OPC_MULTU_G_2F: +#if defined(TARGET_MIPS64) + case OPC_DMULT_G_2E: + case OPC_DMULT_G_2F: + case OPC_DMULTU_G_2E: + case OPC_DMULTU_G_2F: +#endif + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + break; + default: + t0 =3D tcg_temp_local_new(); + t1 =3D tcg_temp_local_new(); + break; + } + + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + + switch (opc) { + case OPC_MULT_G_2E: + case OPC_MULT_G_2F: + tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); + tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); + break; + case OPC_MULTU_G_2E: + case OPC_MULTU_G_2F: + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); + tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); + break; + case OPC_DIV_G_2E: + case OPC_DIV_G_2F: + { + TCGLabel *l1 =3D gen_new_label(); + TCGLabel *l2 =3D gen_new_label(); + TCGLabel *l3 =3D gen_new_label(); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); + tcg_gen_movi_tl(cpu_gpr[rd], 0); + tcg_gen_br(l3); + gen_set_label(l1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); + tcg_gen_mov_tl(cpu_gpr[rd], t0); + tcg_gen_br(l3); + gen_set_label(l2); + tcg_gen_div_tl(cpu_gpr[rd], t0, t1); + tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); + gen_set_label(l3); + } + break; + case OPC_DIVU_G_2E: + case OPC_DIVU_G_2F: + { + TCGLabel *l1 =3D gen_new_label(); + TCGLabel *l2 =3D gen_new_label(); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); + tcg_gen_movi_tl(cpu_gpr[rd], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); + tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); + gen_set_label(l2); + } + break; + case OPC_MOD_G_2E: + case OPC_MOD_G_2F: + { + TCGLabel *l1 =3D gen_new_label(); + TCGLabel *l2 =3D gen_new_label(); + TCGLabel *l3 =3D gen_new_label(); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_gpr[rd], 0); + tcg_gen_br(l3); + gen_set_label(l2); + tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); + tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); + gen_set_label(l3); + } + break; + case OPC_MODU_G_2E: + case OPC_MODU_G_2F: + { + TCGLabel *l1 =3D gen_new_label(); + TCGLabel *l2 =3D gen_new_label(); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); + tcg_gen_movi_tl(cpu_gpr[rd], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); + tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); + gen_set_label(l2); + } + break; +#if defined(TARGET_MIPS64) + case OPC_DMULT_G_2E: + case OPC_DMULT_G_2F: + tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); + break; + case OPC_DMULTU_G_2E: + case OPC_DMULTU_G_2F: + tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); + break; + case OPC_DDIV_G_2E: + case OPC_DDIV_G_2F: + { + TCGLabel *l1 =3D gen_new_label(); + TCGLabel *l2 =3D gen_new_label(); + TCGLabel *l3 =3D gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); + tcg_gen_movi_tl(cpu_gpr[rd], 0); + tcg_gen_br(l3); + gen_set_label(l1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); + tcg_gen_mov_tl(cpu_gpr[rd], t0); + tcg_gen_br(l3); + gen_set_label(l2); + tcg_gen_div_tl(cpu_gpr[rd], t0, t1); + gen_set_label(l3); + } + break; + case OPC_DDIVU_G_2E: + case OPC_DDIVU_G_2F: + { + TCGLabel *l1 =3D gen_new_label(); + TCGLabel *l2 =3D gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); + tcg_gen_movi_tl(cpu_gpr[rd], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); + gen_set_label(l2); + } + break; + case OPC_DMOD_G_2E: + case OPC_DMOD_G_2F: + { + TCGLabel *l1 =3D gen_new_label(); + TCGLabel *l2 =3D gen_new_label(); + TCGLabel *l3 =3D gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_gpr[rd], 0); + tcg_gen_br(l3); + gen_set_label(l2); + tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); + gen_set_label(l3); + } + break; + case OPC_DMODU_G_2E: + case OPC_DMODU_G_2F: + { + TCGLabel *l1 =3D gen_new_label(); + TCGLabel *l2 =3D gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); + tcg_gen_movi_tl(cpu_gpr[rd], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); + gen_set_label(l2); + } + break; +#endif + } + + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +/* Loongson multimedia instructions */ +static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int= rt) +{ + uint32_t opc, shift_max; + TCGv_i64 t0, t1; + TCGCond cond; + + opc =3D MASK_LMMI(ctx->opcode); + switch (opc) { + case OPC_ADD_CP2: + case OPC_SUB_CP2: + case OPC_DADD_CP2: + case OPC_DSUB_CP2: + t0 =3D tcg_temp_local_new_i64(); + t1 =3D tcg_temp_local_new_i64(); + break; + default: + t0 =3D tcg_temp_new_i64(); + t1 =3D tcg_temp_new_i64(); + break; + } + + check_cp1_enabled(ctx); + gen_load_fpr64(ctx, t0, rs); + gen_load_fpr64(ctx, t1, rt); + + switch (opc) { + case OPC_PADDSH: + gen_helper_paddsh(t0, t0, t1); + break; + case OPC_PADDUSH: + gen_helper_paddush(t0, t0, t1); + break; + case OPC_PADDH: + gen_helper_paddh(t0, t0, t1); + break; + case OPC_PADDW: + gen_helper_paddw(t0, t0, t1); + break; + case OPC_PADDSB: + gen_helper_paddsb(t0, t0, t1); + break; + case OPC_PADDUSB: + gen_helper_paddusb(t0, t0, t1); + break; + case OPC_PADDB: + gen_helper_paddb(t0, t0, t1); + break; + + case OPC_PSUBSH: + gen_helper_psubsh(t0, t0, t1); + break; + case OPC_PSUBUSH: + gen_helper_psubush(t0, t0, t1); + break; + case OPC_PSUBH: + gen_helper_psubh(t0, t0, t1); + break; + case OPC_PSUBW: + gen_helper_psubw(t0, t0, t1); + break; + case OPC_PSUBSB: + gen_helper_psubsb(t0, t0, t1); + break; + case OPC_PSUBUSB: + gen_helper_psubusb(t0, t0, t1); + break; + case OPC_PSUBB: + gen_helper_psubb(t0, t0, t1); + break; + + case OPC_PSHUFH: + gen_helper_pshufh(t0, t0, t1); + break; + case OPC_PACKSSWH: + gen_helper_packsswh(t0, t0, t1); + break; + case OPC_PACKSSHB: + gen_helper_packsshb(t0, t0, t1); + break; + case OPC_PACKUSHB: + gen_helper_packushb(t0, t0, t1); + break; + + case OPC_PUNPCKLHW: + gen_helper_punpcklhw(t0, t0, t1); + break; + case OPC_PUNPCKHHW: + gen_helper_punpckhhw(t0, t0, t1); + break; + case OPC_PUNPCKLBH: + gen_helper_punpcklbh(t0, t0, t1); + break; + case OPC_PUNPCKHBH: + gen_helper_punpckhbh(t0, t0, t1); + break; + case OPC_PUNPCKLWD: + gen_helper_punpcklwd(t0, t0, t1); + break; + case OPC_PUNPCKHWD: + gen_helper_punpckhwd(t0, t0, t1); + break; + + case OPC_PAVGH: + gen_helper_pavgh(t0, t0, t1); + break; + case OPC_PAVGB: + gen_helper_pavgb(t0, t0, t1); + break; + case OPC_PMAXSH: + gen_helper_pmaxsh(t0, t0, t1); + break; + case OPC_PMINSH: + gen_helper_pminsh(t0, t0, t1); + break; + case OPC_PMAXUB: + gen_helper_pmaxub(t0, t0, t1); + break; + case OPC_PMINUB: + gen_helper_pminub(t0, t0, t1); + break; + + case OPC_PCMPEQW: + gen_helper_pcmpeqw(t0, t0, t1); + break; + case OPC_PCMPGTW: + gen_helper_pcmpgtw(t0, t0, t1); + break; + case OPC_PCMPEQH: + gen_helper_pcmpeqh(t0, t0, t1); + break; + case OPC_PCMPGTH: + gen_helper_pcmpgth(t0, t0, t1); + break; + case OPC_PCMPEQB: + gen_helper_pcmpeqb(t0, t0, t1); + break; + case OPC_PCMPGTB: + gen_helper_pcmpgtb(t0, t0, t1); + break; + + case OPC_PSLLW: + gen_helper_psllw(t0, t0, t1); + break; + case OPC_PSLLH: + gen_helper_psllh(t0, t0, t1); + break; + case OPC_PSRLW: + gen_helper_psrlw(t0, t0, t1); + break; + case OPC_PSRLH: + gen_helper_psrlh(t0, t0, t1); + break; + case OPC_PSRAW: + gen_helper_psraw(t0, t0, t1); + break; + case OPC_PSRAH: + gen_helper_psrah(t0, t0, t1); + break; + + case OPC_PMULLH: + gen_helper_pmullh(t0, t0, t1); + break; + case OPC_PMULHH: + gen_helper_pmulhh(t0, t0, t1); + break; + case OPC_PMULHUH: + gen_helper_pmulhuh(t0, t0, t1); + break; + case OPC_PMADDHW: + gen_helper_pmaddhw(t0, t0, t1); + break; + + case OPC_PASUBUB: + gen_helper_pasubub(t0, t0, t1); + break; + case OPC_BIADD: + gen_helper_biadd(t0, t0); + break; + case OPC_PMOVMSKB: + gen_helper_pmovmskb(t0, t0); + break; + + case OPC_PADDD: + tcg_gen_add_i64(t0, t0, t1); + break; + case OPC_PSUBD: + tcg_gen_sub_i64(t0, t0, t1); + break; + case OPC_XOR_CP2: + tcg_gen_xor_i64(t0, t0, t1); + break; + case OPC_NOR_CP2: + tcg_gen_nor_i64(t0, t0, t1); + break; + case OPC_AND_CP2: + tcg_gen_and_i64(t0, t0, t1); + break; + case OPC_OR_CP2: + tcg_gen_or_i64(t0, t0, t1); + break; + + case OPC_PANDN: + tcg_gen_andc_i64(t0, t1, t0); + break; + + case OPC_PINSRH_0: + tcg_gen_deposit_i64(t0, t0, t1, 0, 16); + break; + case OPC_PINSRH_1: + tcg_gen_deposit_i64(t0, t0, t1, 16, 16); + break; + case OPC_PINSRH_2: + tcg_gen_deposit_i64(t0, t0, t1, 32, 16); + break; + case OPC_PINSRH_3: + tcg_gen_deposit_i64(t0, t0, t1, 48, 16); + break; + + case OPC_PEXTRH: + tcg_gen_andi_i64(t1, t1, 3); + tcg_gen_shli_i64(t1, t1, 4); + tcg_gen_shr_i64(t0, t0, t1); + tcg_gen_ext16u_i64(t0, t0); + break; + + case OPC_ADDU_CP2: + tcg_gen_add_i64(t0, t0, t1); + tcg_gen_ext32s_i64(t0, t0); + break; + case OPC_SUBU_CP2: + tcg_gen_sub_i64(t0, t0, t1); + tcg_gen_ext32s_i64(t0, t0); + break; + + case OPC_SLL_CP2: + shift_max =3D 32; + goto do_shift; + case OPC_SRL_CP2: + shift_max =3D 32; + goto do_shift; + case OPC_SRA_CP2: + shift_max =3D 32; + goto do_shift; + case OPC_DSLL_CP2: + shift_max =3D 64; + goto do_shift; + case OPC_DSRL_CP2: + shift_max =3D 64; + goto do_shift; + case OPC_DSRA_CP2: + shift_max =3D 64; + goto do_shift; + do_shift: + /* Make sure shift count isn't TCG undefined behaviour. */ + tcg_gen_andi_i64(t1, t1, shift_max - 1); + + switch (opc) { + case OPC_SLL_CP2: + case OPC_DSLL_CP2: + tcg_gen_shl_i64(t0, t0, t1); + break; + case OPC_SRA_CP2: + case OPC_DSRA_CP2: + /* + * Since SRA is UndefinedResult without sign-extended inputs, + * we can treat SRA and DSRA the same. + */ + tcg_gen_sar_i64(t0, t0, t1); + break; + case OPC_SRL_CP2: + /* We want to shift in zeros for SRL; zero-extend first. */ + tcg_gen_ext32u_i64(t0, t0); + /* FALLTHRU */ + case OPC_DSRL_CP2: + tcg_gen_shr_i64(t0, t0, t1); + break; + } + + if (shift_max =3D=3D 32) { + tcg_gen_ext32s_i64(t0, t0); + } + + /* Shifts larger than MAX produce zero. */ + tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); + tcg_gen_neg_i64(t1, t1); + tcg_gen_and_i64(t0, t0, t1); + break; + + case OPC_ADD_CP2: + case OPC_DADD_CP2: + { + TCGv_i64 t2 =3D tcg_temp_new_i64(); + TCGLabel *lab =3D gen_new_label(); + + tcg_gen_mov_i64(t2, t0); + tcg_gen_add_i64(t0, t1, t2); + if (opc =3D=3D OPC_ADD_CP2) { + tcg_gen_ext32s_i64(t0, t0); + } + tcg_gen_xor_i64(t1, t1, t2); + tcg_gen_xor_i64(t2, t2, t0); + tcg_gen_andc_i64(t1, t2, t1); + tcg_temp_free_i64(t2); + tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); + generate_exception(ctx, EXCP_OVERFLOW); + gen_set_label(lab); + break; + } + + case OPC_SUB_CP2: + case OPC_DSUB_CP2: + { + TCGv_i64 t2 =3D tcg_temp_new_i64(); + TCGLabel *lab =3D gen_new_label(); + + tcg_gen_mov_i64(t2, t0); + tcg_gen_sub_i64(t0, t1, t2); + if (opc =3D=3D OPC_SUB_CP2) { + tcg_gen_ext32s_i64(t0, t0); + } + tcg_gen_xor_i64(t1, t1, t2); + tcg_gen_xor_i64(t2, t2, t0); + tcg_gen_and_i64(t1, t1, t2); + tcg_temp_free_i64(t2); + tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); + generate_exception(ctx, EXCP_OVERFLOW); + gen_set_label(lab); + break; + } + + case OPC_PMULUW: + tcg_gen_ext32u_i64(t0, t0); + tcg_gen_ext32u_i64(t1, t1); + tcg_gen_mul_i64(t0, t0, t1); + break; + + case OPC_SEQU_CP2: + case OPC_SEQ_CP2: + cond =3D TCG_COND_EQ; + goto do_cc_cond; + break; + case OPC_SLTU_CP2: + cond =3D TCG_COND_LTU; + goto do_cc_cond; + break; + case OPC_SLT_CP2: + cond =3D TCG_COND_LT; + goto do_cc_cond; + break; + case OPC_SLEU_CP2: + cond =3D TCG_COND_LEU; + goto do_cc_cond; + break; + case OPC_SLE_CP2: + cond =3D TCG_COND_LE; + do_cc_cond: + { + int cc =3D (ctx->opcode >> 8) & 0x7; + TCGv_i64 t64 =3D tcg_temp_new_i64(); + TCGv_i32 t32 =3D tcg_temp_new_i32(); + + tcg_gen_setcond_i64(cond, t64, t0, t1); + tcg_gen_extrl_i64_i32(t32, t64); + tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, + get_fp_bit(cc), 1); + + tcg_temp_free_i32(t32); + tcg_temp_free_i64(t64); + } + goto no_rd; + break; + default: + MIPS_INVAL("loongson_cp2"); + generate_exception_end(ctx, EXCP_RI); + return; + } + + gen_store_fpr64(ctx, t0, rd); + +no_rd: + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); +} --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.49 as permitted sender) client-ip=209.85.221.49; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f49.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.49 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906628; cv=none; d=zohomail.com; s=zohoarc; b=ltY8TZ92D2GFP1LHuuAagB/zqonL7V3b2wirAMx2jPGDocpfUmiR/9GeY69KLNiEBRf4iZi4HisWUNJTyij0N4UzVfFINTFaTRQfyv5oBWHaDzWRTQV6CHEW8222zryfHDt8On3EbL5uQRso0aNOPLXHI47QksEcA+Q9i//QacM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906628; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Lz4O3VSdeq8YY2AcXxACks3Rk8SOTJPFTORx1KyBhHY=; b=QwCBq9EjMLv7MVtA9yU2Ona/eS/hzd50FShQk4Gkxhbw1lIx0Tmg3OUTIvpDZFH5EZqMbI5Cn+VpZi2lwRpHQRBHSBhhumt2lME2p/M7ykqBUCEcKuB5JAp0UuAC9W6GD3k/Q/7fhoqenJHOuxHWGB2L6F+bLnS5XWMjyfkySPs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.49 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) by mx.zohomail.com with SMTPS id 1605906628971238.26705396601312; Fri, 20 Nov 2020 13:10:28 -0800 (PST) Received: by mail-wr1-f49.google.com with SMTP id p1so11652616wrf.12 for ; Fri, 20 Nov 2020 13:10:28 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id o67sm2055544wmo.31.2020.11.20.13.10.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Lz4O3VSdeq8YY2AcXxACks3Rk8SOTJPFTORx1KyBhHY=; b=HfzVrAlofaRwkvttP2ReQcT5fr/lrZH0pWh0yeHoTghC4ptf3Gk/KVTyg0ncNAy+OU wuWezs30qFgNacQ/pfyfRXGbBeBRH1f8eNqJ6uLY0w6++2HeE07Nz+KURR/2PmjRmM+u 188IW8zMBSbqDidI+s9YRzAzdkSbP628IPcvvSoZHXXsoAy+hP7oky7erJz7RlExlinD zkD/5AjmzKGGed2efkaN0Z8DOT84xMKERNeRho4EpMrGatIqfM+Hm6sDFSs2I/P9+evz daeY9okDyX/gjT8EWQ7MpOVrmAEdFcbZ4VOfaEpEdJEjSwRDeTmQqMRpRzDo/7tnVa3W 7N6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=Lz4O3VSdeq8YY2AcXxACks3Rk8SOTJPFTORx1KyBhHY=; b=l/odSa2eR21oHdHt4ChYcZmBK991nwYKEsI/LfyXUNikKSY7CEpY6s04sKyjtDyGxd u2ShX2bTTQXu0wX/7hvaayolmUS0TGtr2OasDbL7c0NsbE+BeOHoQmfZm+qxAzJmcSt8 GnZCpVwV/Q5rntEnHD3j3INw8412yFLt172wDjKmRBrK0frroMQJ/RmBZMd2cGPjr9sb QVaZmA6eW/b0XGgw3sbY4+1gEOQgOdqMxXxXzeogC6Am5uZTk67f4OiFSQq0y3skyQI9 X8Fb7Q+cm/aFdnaZamBq5FbemTCb2imiVCg0IEfs1MtUDPgXcKJDL4gbtE9pd6yAR3NX RXNg== X-Gm-Message-State: AOAM531jSUaE/VG1A4mtRvDFDwU+bsh4iEMrkkZcH4FGU93Kn+TQAff6 S+tTPs3Ldo3o+klgMVWtbCQ= X-Google-Smtp-Source: ABdhPJyI8lzfMKTbAuluiQfCECL1d1hALf0MKUo/ViWj2UG20D5VOyVzxbQSbV+mjU6XBRRpd07gwQ== X-Received: by 2002:adf:f208:: with SMTP id p8mr18890572wro.280.1605906626867; Fri, 20 Nov 2020 13:10:26 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 19/26] target/mips: Extract Loongson EXTensions translation routines Date: Fri, 20 Nov 2020 22:08:37 +0100 Message-Id: <20201120210844.2625602-20-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) LoongEXTs are general-purpose extensions from the LoongISA. Extract 440 lines of translation routines to 'vendor-loong-lext_translate.c.inc'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/translate.c | 440 +---------------- target/mips/vendor-loong-lext_translate.c.inc | 450 ++++++++++++++++++ 2 files changed, 451 insertions(+), 439 deletions(-) create mode 100644 target/mips/vendor-loong-lext_translate.c.inc diff --git a/target/mips/translate.c b/target/mips/translate.c index 105a104bb0c..46306ab7e9c 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -399,48 +399,6 @@ enum { R6_OPC_SCD =3D 0x27 | OPC_SPECIAL3, }; =20 -/* Loongson EXT load/store quad word opcodes */ -#define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x802= 0)) -enum { - OPC_GSLQ =3D 0x0020 | OPC_LWC2, - OPC_GSLQC1 =3D 0x8020 | OPC_LWC2, - OPC_GSSHFL =3D OPC_LWC2, - OPC_GSSQ =3D 0x0020 | OPC_SWC2, - OPC_GSSQC1 =3D 0x8020 | OPC_SWC2, - OPC_GSSHFS =3D OPC_SWC2, -}; - -/* Loongson EXT shifted load/store opcodes */ -#define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03= f)) -enum { - OPC_GSLWLC1 =3D 0x4 | OPC_GSSHFL, - OPC_GSLWRC1 =3D 0x5 | OPC_GSSHFL, - OPC_GSLDLC1 =3D 0x6 | OPC_GSSHFL, - OPC_GSLDRC1 =3D 0x7 | OPC_GSSHFL, - OPC_GSSWLC1 =3D 0x4 | OPC_GSSHFS, - OPC_GSSWRC1 =3D 0x5 | OPC_GSSHFS, - OPC_GSSDLC1 =3D 0x6 | OPC_GSSHFS, - OPC_GSSDRC1 =3D 0x7 | OPC_GSSHFS, -}; - -/* Loongson EXT LDC2/SDC2 opcodes */ -#define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) - -enum { - OPC_GSLBX =3D 0x0 | OPC_LDC2, - OPC_GSLHX =3D 0x1 | OPC_LDC2, - OPC_GSLWX =3D 0x2 | OPC_LDC2, - OPC_GSLDX =3D 0x3 | OPC_LDC2, - OPC_GSLWXC1 =3D 0x6 | OPC_LDC2, - OPC_GSLDXC1 =3D 0x7 | OPC_LDC2, - OPC_GSSBX =3D 0x0 | OPC_SDC2, - OPC_GSSHX =3D 0x1 | OPC_SDC2, - OPC_GSSWX =3D 0x2 | OPC_SDC2, - OPC_GSSDX =3D 0x3 | OPC_SDC2, - OPC_GSSWXC1 =3D 0x6 | OPC_SDC2, - OPC_GSSDXC1 =3D 0x7 | OPC_SDC2, -}; - /* BSHFL opcodes */ #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)= )) =20 @@ -4556,403 +4514,6 @@ static void gen_cl(DisasContext *ctx, uint32_t opc, } } =20 -static void gen_loongson_lswc2(DisasContext *ctx, int rt, - int rs, int rd) -{ - TCGv t0, t1, t2; - TCGv_i32 fp0; -#if defined(TARGET_MIPS64) - int lsq_rt1 =3D ctx->opcode & 0x1f; - int lsq_offset =3D sextract32(ctx->opcode, 6, 9) << 4; -#endif - int shf_offset =3D sextract32(ctx->opcode, 6, 8); - - t0 =3D tcg_temp_new(); - - switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { -#if defined(TARGET_MIPS64) - case OPC_GSLQ: - t1 =3D tcg_temp_new(); - gen_base_offset_addr(ctx, t0, rs, lsq_offset); - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - gen_store_gpr(t1, rt); - gen_store_gpr(t0, lsq_rt1); - tcg_temp_free(t1); - break; - case OPC_GSLQC1: - check_cp1_enabled(ctx); - t1 =3D tcg_temp_new(); - gen_base_offset_addr(ctx, t0, rs, lsq_offset); - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - gen_store_fpr64(ctx, t1, rt); - gen_store_fpr64(ctx, t0, lsq_rt1); - tcg_temp_free(t1); - break; - case OPC_GSSQ: - t1 =3D tcg_temp_new(); - gen_base_offset_addr(ctx, t0, rs, lsq_offset); - gen_load_gpr(t1, rt); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); - gen_load_gpr(t1, lsq_rt1); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - tcg_temp_free(t1); - break; - case OPC_GSSQC1: - check_cp1_enabled(ctx); - t1 =3D tcg_temp_new(); - gen_base_offset_addr(ctx, t0, rs, lsq_offset); - gen_load_fpr64(ctx, t1, rt); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); - gen_load_fpr64(ctx, t1, lsq_rt1); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - tcg_temp_free(t1); - break; -#endif - case OPC_GSSHFL: - switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { - case OPC_GSLWLC1: - check_cp1_enabled(ctx); - gen_base_offset_addr(ctx, t0, rs, shf_offset); - t1 =3D tcg_temp_new(); - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - tcg_gen_andi_tl(t1, t0, 3); -#ifndef TARGET_WORDS_BIGENDIAN - tcg_gen_xori_tl(t1, t1, 3); -#endif - tcg_gen_shli_tl(t1, t1, 3); - tcg_gen_andi_tl(t0, t0, ~3); - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); - tcg_gen_shl_tl(t0, t0, t1); - t2 =3D tcg_const_tl(-1); - tcg_gen_shl_tl(t2, t2, t1); - fp0 =3D tcg_temp_new_i32(); - gen_load_fpr32(ctx, fp0, rt); - tcg_gen_ext_i32_tl(t1, fp0); - tcg_gen_andc_tl(t1, t1, t2); - tcg_temp_free(t2); - tcg_gen_or_tl(t0, t0, t1); - tcg_temp_free(t1); -#if defined(TARGET_MIPS64) - tcg_gen_extrl_i64_i32(fp0, t0); -#else - tcg_gen_ext32s_tl(fp0, t0); -#endif - gen_store_fpr32(ctx, fp0, rt); - tcg_temp_free_i32(fp0); - break; - case OPC_GSLWRC1: - check_cp1_enabled(ctx); - gen_base_offset_addr(ctx, t0, rs, shf_offset); - t1 =3D tcg_temp_new(); - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - tcg_gen_andi_tl(t1, t0, 3); -#ifdef TARGET_WORDS_BIGENDIAN - tcg_gen_xori_tl(t1, t1, 3); -#endif - tcg_gen_shli_tl(t1, t1, 3); - tcg_gen_andi_tl(t0, t0, ~3); - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); - tcg_gen_shr_tl(t0, t0, t1); - tcg_gen_xori_tl(t1, t1, 31); - t2 =3D tcg_const_tl(0xfffffffeull); - tcg_gen_shl_tl(t2, t2, t1); - fp0 =3D tcg_temp_new_i32(); - gen_load_fpr32(ctx, fp0, rt); - tcg_gen_ext_i32_tl(t1, fp0); - tcg_gen_and_tl(t1, t1, t2); - tcg_temp_free(t2); - tcg_gen_or_tl(t0, t0, t1); - tcg_temp_free(t1); -#if defined(TARGET_MIPS64) - tcg_gen_extrl_i64_i32(fp0, t0); -#else - tcg_gen_ext32s_tl(fp0, t0); -#endif - gen_store_fpr32(ctx, fp0, rt); - tcg_temp_free_i32(fp0); - break; -#if defined(TARGET_MIPS64) - case OPC_GSLDLC1: - check_cp1_enabled(ctx); - gen_base_offset_addr(ctx, t0, rs, shf_offset); - t1 =3D tcg_temp_new(); - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - tcg_gen_andi_tl(t1, t0, 7); -#ifndef TARGET_WORDS_BIGENDIAN - tcg_gen_xori_tl(t1, t1, 7); -#endif - tcg_gen_shli_tl(t1, t1, 3); - tcg_gen_andi_tl(t0, t0, ~7); - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); - tcg_gen_shl_tl(t0, t0, t1); - t2 =3D tcg_const_tl(-1); - tcg_gen_shl_tl(t2, t2, t1); - gen_load_fpr64(ctx, t1, rt); - tcg_gen_andc_tl(t1, t1, t2); - tcg_temp_free(t2); - tcg_gen_or_tl(t0, t0, t1); - tcg_temp_free(t1); - gen_store_fpr64(ctx, t0, rt); - break; - case OPC_GSLDRC1: - check_cp1_enabled(ctx); - gen_base_offset_addr(ctx, t0, rs, shf_offset); - t1 =3D tcg_temp_new(); - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - tcg_gen_andi_tl(t1, t0, 7); -#ifdef TARGET_WORDS_BIGENDIAN - tcg_gen_xori_tl(t1, t1, 7); -#endif - tcg_gen_shli_tl(t1, t1, 3); - tcg_gen_andi_tl(t0, t0, ~7); - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); - tcg_gen_shr_tl(t0, t0, t1); - tcg_gen_xori_tl(t1, t1, 63); - t2 =3D tcg_const_tl(0xfffffffffffffffeull); - tcg_gen_shl_tl(t2, t2, t1); - gen_load_fpr64(ctx, t1, rt); - tcg_gen_and_tl(t1, t1, t2); - tcg_temp_free(t2); - tcg_gen_or_tl(t0, t0, t1); - tcg_temp_free(t1); - gen_store_fpr64(ctx, t0, rt); - break; -#endif - default: - MIPS_INVAL("loongson_gsshfl"); - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - case OPC_GSSHFS: - switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { - case OPC_GSSWLC1: - check_cp1_enabled(ctx); - t1 =3D tcg_temp_new(); - gen_base_offset_addr(ctx, t0, rs, shf_offset); - fp0 =3D tcg_temp_new_i32(); - gen_load_fpr32(ctx, fp0, rt); - tcg_gen_ext_i32_tl(t1, fp0); - gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); - tcg_temp_free_i32(fp0); - tcg_temp_free(t1); - break; - case OPC_GSSWRC1: - check_cp1_enabled(ctx); - t1 =3D tcg_temp_new(); - gen_base_offset_addr(ctx, t0, rs, shf_offset); - fp0 =3D tcg_temp_new_i32(); - gen_load_fpr32(ctx, fp0, rt); - tcg_gen_ext_i32_tl(t1, fp0); - gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); - tcg_temp_free_i32(fp0); - tcg_temp_free(t1); - break; -#if defined(TARGET_MIPS64) - case OPC_GSSDLC1: - check_cp1_enabled(ctx); - t1 =3D tcg_temp_new(); - gen_base_offset_addr(ctx, t0, rs, shf_offset); - gen_load_fpr64(ctx, t1, rt); - gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); - tcg_temp_free(t1); - break; - case OPC_GSSDRC1: - check_cp1_enabled(ctx); - t1 =3D tcg_temp_new(); - gen_base_offset_addr(ctx, t0, rs, shf_offset); - gen_load_fpr64(ctx, t1, rt); - gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); - tcg_temp_free(t1); - break; -#endif - default: - MIPS_INVAL("loongson_gsshfs"); - generate_exception_end(ctx, EXCP_RI); - break; - } - break; - default: - MIPS_INVAL("loongson_gslsq"); - generate_exception_end(ctx, EXCP_RI); - break; - } - tcg_temp_free(t0); -} - -/* Loongson EXT LDC2/SDC2 */ -static void gen_loongson_lsdc2(DisasContext *ctx, int rt, - int rs, int rd) -{ - int offset =3D sextract32(ctx->opcode, 3, 8); - uint32_t opc =3D MASK_LOONGSON_LSDC2(ctx->opcode); - TCGv t0, t1; - TCGv_i32 fp0; - - /* Pre-conditions */ - switch (opc) { - case OPC_GSLBX: - case OPC_GSLHX: - case OPC_GSLWX: - case OPC_GSLDX: - /* prefetch, implement as NOP */ - if (rt =3D=3D 0) { - return; - } - break; - case OPC_GSSBX: - case OPC_GSSHX: - case OPC_GSSWX: - case OPC_GSSDX: - break; - case OPC_GSLWXC1: -#if defined(TARGET_MIPS64) - case OPC_GSLDXC1: -#endif - check_cp1_enabled(ctx); - /* prefetch, implement as NOP */ - if (rt =3D=3D 0) { - return; - } - break; - case OPC_GSSWXC1: -#if defined(TARGET_MIPS64) - case OPC_GSSDXC1: -#endif - check_cp1_enabled(ctx); - break; - default: - MIPS_INVAL("loongson_lsdc2"); - generate_exception_end(ctx, EXCP_RI); - return; - break; - } - - t0 =3D tcg_temp_new(); - - gen_base_offset_addr(ctx, t0, rs, offset); - gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); - - switch (opc) { - case OPC_GSLBX: - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); - gen_store_gpr(t0, rt); - break; - case OPC_GSLHX: - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | - ctx->default_tcg_memop_mask); - gen_store_gpr(t0, rt); - break; - case OPC_GSLWX: - gen_base_offset_addr(ctx, t0, rs, offset); - if (rd) { - gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); - } - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL | - ctx->default_tcg_memop_mask); - gen_store_gpr(t0, rt); - break; -#if defined(TARGET_MIPS64) - case OPC_GSLDX: - gen_base_offset_addr(ctx, t0, rs, offset); - if (rd) { - gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); - } - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - gen_store_gpr(t0, rt); - break; -#endif - case OPC_GSLWXC1: - check_cp1_enabled(ctx); - gen_base_offset_addr(ctx, t0, rs, offset); - if (rd) { - gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); - } - fp0 =3D tcg_temp_new_i32(); - tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | - ctx->default_tcg_memop_mask); - gen_store_fpr32(ctx, fp0, rt); - tcg_temp_free_i32(fp0); - break; -#if defined(TARGET_MIPS64) - case OPC_GSLDXC1: - check_cp1_enabled(ctx); - gen_base_offset_addr(ctx, t0, rs, offset); - if (rd) { - gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); - } - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - gen_store_fpr64(ctx, t0, rt); - break; -#endif - case OPC_GSSBX: - t1 =3D tcg_temp_new(); - gen_load_gpr(t1, rt); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); - tcg_temp_free(t1); - break; - case OPC_GSSHX: - t1 =3D tcg_temp_new(); - gen_load_gpr(t1, rt); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | - ctx->default_tcg_memop_mask); - tcg_temp_free(t1); - break; - case OPC_GSSWX: - t1 =3D tcg_temp_new(); - gen_load_gpr(t1, rt); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL | - ctx->default_tcg_memop_mask); - tcg_temp_free(t1); - break; -#if defined(TARGET_MIPS64) - case OPC_GSSDX: - t1 =3D tcg_temp_new(); - gen_load_gpr(t1, rt); - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - tcg_temp_free(t1); - break; -#endif - case OPC_GSSWXC1: - fp0 =3D tcg_temp_new_i32(); - gen_load_fpr32(ctx, fp0, rt); - tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | - ctx->default_tcg_memop_mask); - tcg_temp_free_i32(fp0); - break; -#if defined(TARGET_MIPS64) - case OPC_GSSDXC1: - t1 =3D tcg_temp_new(); - gen_load_fpr64(ctx, t1, rt); - tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ | - ctx->default_tcg_memop_mask); - tcg_temp_free(t1); - break; -#endif - default: - break; - } - - tcg_temp_free(t0); -} - /* Traps */ static void gen_trap(DisasContext *ctx, uint32_t opc, int rs, int rt, int16_t imm) @@ -12343,6 +11904,7 @@ out: =20 #include "vendor-vr54xx_translate.c.inc" #include "vendor-loong-simd_translate.c.inc" +#include "vendor-loong-lext_translate.c.inc" =20 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) { diff --git a/target/mips/vendor-loong-lext_translate.c.inc b/target/mips/ve= ndor-loong-lext_translate.c.inc new file mode 100644 index 00000000000..5ea82394587 --- /dev/null +++ b/target/mips/vendor-loong-lext_translate.c.inc @@ -0,0 +1,450 @@ +/* + * Loongson EXTensions translation routines. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +/* Loongson EXT load/store quad word opcodes */ +#define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x802= 0)) +enum { + OPC_GSLQ =3D 0x0020 | OPC_LWC2, + OPC_GSLQC1 =3D 0x8020 | OPC_LWC2, + OPC_GSSHFL =3D OPC_LWC2, + OPC_GSSQ =3D 0x0020 | OPC_SWC2, + OPC_GSSQC1 =3D 0x8020 | OPC_SWC2, + OPC_GSSHFS =3D OPC_SWC2, +}; + +/* Loongson EXT shifted load/store opcodes */ +#define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03= f)) +enum { + OPC_GSLWLC1 =3D 0x4 | OPC_GSSHFL, + OPC_GSLWRC1 =3D 0x5 | OPC_GSSHFL, + OPC_GSLDLC1 =3D 0x6 | OPC_GSSHFL, + OPC_GSLDRC1 =3D 0x7 | OPC_GSSHFL, + OPC_GSSWLC1 =3D 0x4 | OPC_GSSHFS, + OPC_GSSWRC1 =3D 0x5 | OPC_GSSHFS, + OPC_GSSDLC1 =3D 0x6 | OPC_GSSHFS, + OPC_GSSDRC1 =3D 0x7 | OPC_GSSHFS, +}; + +/* Loongson EXT LDC2/SDC2 opcodes */ +#define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) + +enum { + OPC_GSLBX =3D 0x0 | OPC_LDC2, + OPC_GSLHX =3D 0x1 | OPC_LDC2, + OPC_GSLWX =3D 0x2 | OPC_LDC2, + OPC_GSLDX =3D 0x3 | OPC_LDC2, + OPC_GSLWXC1 =3D 0x6 | OPC_LDC2, + OPC_GSLDXC1 =3D 0x7 | OPC_LDC2, + OPC_GSSBX =3D 0x0 | OPC_SDC2, + OPC_GSSHX =3D 0x1 | OPC_SDC2, + OPC_GSSWX =3D 0x2 | OPC_SDC2, + OPC_GSSDX =3D 0x3 | OPC_SDC2, + OPC_GSSWXC1 =3D 0x6 | OPC_SDC2, + OPC_GSSDXC1 =3D 0x7 | OPC_SDC2, +}; + +static void gen_loongson_lswc2(DisasContext *ctx, int rt, + int rs, int rd) +{ + TCGv t0, t1, t2; + TCGv_i32 fp0; +#if defined(TARGET_MIPS64) + int lsq_rt1 =3D ctx->opcode & 0x1f; + int lsq_offset =3D sextract32(ctx->opcode, 6, 9) << 4; +#endif + int shf_offset =3D sextract32(ctx->opcode, 6, 8); + + t0 =3D tcg_temp_new(); + + switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { +#if defined(TARGET_MIPS64) + case OPC_GSLQ: + t1 =3D tcg_temp_new(); + gen_base_offset_addr(ctx, t0, rs, lsq_offset); + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + gen_store_gpr(t1, rt); + gen_store_gpr(t0, lsq_rt1); + tcg_temp_free(t1); + break; + case OPC_GSLQC1: + check_cp1_enabled(ctx); + t1 =3D tcg_temp_new(); + gen_base_offset_addr(ctx, t0, rs, lsq_offset); + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + gen_store_fpr64(ctx, t1, rt); + gen_store_fpr64(ctx, t0, lsq_rt1); + tcg_temp_free(t1); + break; + case OPC_GSSQ: + t1 =3D tcg_temp_new(); + gen_base_offset_addr(ctx, t0, rs, lsq_offset); + gen_load_gpr(t1, rt); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); + gen_load_gpr(t1, lsq_rt1); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + tcg_temp_free(t1); + break; + case OPC_GSSQC1: + check_cp1_enabled(ctx); + t1 =3D tcg_temp_new(); + gen_base_offset_addr(ctx, t0, rs, lsq_offset); + gen_load_fpr64(ctx, t1, rt); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); + gen_load_fpr64(ctx, t1, lsq_rt1); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + tcg_temp_free(t1); + break; +#endif + case OPC_GSSHFL: + switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { + case OPC_GSLWLC1: + check_cp1_enabled(ctx); + gen_base_offset_addr(ctx, t0, rs, shf_offset); + t1 =3D tcg_temp_new(); + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + tcg_gen_andi_tl(t1, t0, 3); +#ifndef TARGET_WORDS_BIGENDIAN + tcg_gen_xori_tl(t1, t1, 3); +#endif + tcg_gen_shli_tl(t1, t1, 3); + tcg_gen_andi_tl(t0, t0, ~3); + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); + tcg_gen_shl_tl(t0, t0, t1); + t2 =3D tcg_const_tl(-1); + tcg_gen_shl_tl(t2, t2, t1); + fp0 =3D tcg_temp_new_i32(); + gen_load_fpr32(ctx, fp0, rt); + tcg_gen_ext_i32_tl(t1, fp0); + tcg_gen_andc_tl(t1, t1, t2); + tcg_temp_free(t2); + tcg_gen_or_tl(t0, t0, t1); + tcg_temp_free(t1); +#if defined(TARGET_MIPS64) + tcg_gen_extrl_i64_i32(fp0, t0); +#else + tcg_gen_ext32s_tl(fp0, t0); +#endif + gen_store_fpr32(ctx, fp0, rt); + tcg_temp_free_i32(fp0); + break; + case OPC_GSLWRC1: + check_cp1_enabled(ctx); + gen_base_offset_addr(ctx, t0, rs, shf_offset); + t1 =3D tcg_temp_new(); + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + tcg_gen_andi_tl(t1, t0, 3); +#ifdef TARGET_WORDS_BIGENDIAN + tcg_gen_xori_tl(t1, t1, 3); +#endif + tcg_gen_shli_tl(t1, t1, 3); + tcg_gen_andi_tl(t0, t0, ~3); + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); + tcg_gen_shr_tl(t0, t0, t1); + tcg_gen_xori_tl(t1, t1, 31); + t2 =3D tcg_const_tl(0xfffffffeull); + tcg_gen_shl_tl(t2, t2, t1); + fp0 =3D tcg_temp_new_i32(); + gen_load_fpr32(ctx, fp0, rt); + tcg_gen_ext_i32_tl(t1, fp0); + tcg_gen_and_tl(t1, t1, t2); + tcg_temp_free(t2); + tcg_gen_or_tl(t0, t0, t1); + tcg_temp_free(t1); +#if defined(TARGET_MIPS64) + tcg_gen_extrl_i64_i32(fp0, t0); +#else + tcg_gen_ext32s_tl(fp0, t0); +#endif + gen_store_fpr32(ctx, fp0, rt); + tcg_temp_free_i32(fp0); + break; +#if defined(TARGET_MIPS64) + case OPC_GSLDLC1: + check_cp1_enabled(ctx); + gen_base_offset_addr(ctx, t0, rs, shf_offset); + t1 =3D tcg_temp_new(); + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + tcg_gen_andi_tl(t1, t0, 7); +#ifndef TARGET_WORDS_BIGENDIAN + tcg_gen_xori_tl(t1, t1, 7); +#endif + tcg_gen_shli_tl(t1, t1, 3); + tcg_gen_andi_tl(t0, t0, ~7); + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); + tcg_gen_shl_tl(t0, t0, t1); + t2 =3D tcg_const_tl(-1); + tcg_gen_shl_tl(t2, t2, t1); + gen_load_fpr64(ctx, t1, rt); + tcg_gen_andc_tl(t1, t1, t2); + tcg_temp_free(t2); + tcg_gen_or_tl(t0, t0, t1); + tcg_temp_free(t1); + gen_store_fpr64(ctx, t0, rt); + break; + case OPC_GSLDRC1: + check_cp1_enabled(ctx); + gen_base_offset_addr(ctx, t0, rs, shf_offset); + t1 =3D tcg_temp_new(); + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + tcg_gen_andi_tl(t1, t0, 7); +#ifdef TARGET_WORDS_BIGENDIAN + tcg_gen_xori_tl(t1, t1, 7); +#endif + tcg_gen_shli_tl(t1, t1, 3); + tcg_gen_andi_tl(t0, t0, ~7); + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); + tcg_gen_shr_tl(t0, t0, t1); + tcg_gen_xori_tl(t1, t1, 63); + t2 =3D tcg_const_tl(0xfffffffffffffffeull); + tcg_gen_shl_tl(t2, t2, t1); + gen_load_fpr64(ctx, t1, rt); + tcg_gen_and_tl(t1, t1, t2); + tcg_temp_free(t2); + tcg_gen_or_tl(t0, t0, t1); + tcg_temp_free(t1); + gen_store_fpr64(ctx, t0, rt); + break; +#endif + default: + MIPS_INVAL("loongson_gsshfl"); + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + case OPC_GSSHFS: + switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { + case OPC_GSSWLC1: + check_cp1_enabled(ctx); + t1 =3D tcg_temp_new(); + gen_base_offset_addr(ctx, t0, rs, shf_offset); + fp0 =3D tcg_temp_new_i32(); + gen_load_fpr32(ctx, fp0, rt); + tcg_gen_ext_i32_tl(t1, fp0); + gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); + tcg_temp_free_i32(fp0); + tcg_temp_free(t1); + break; + case OPC_GSSWRC1: + check_cp1_enabled(ctx); + t1 =3D tcg_temp_new(); + gen_base_offset_addr(ctx, t0, rs, shf_offset); + fp0 =3D tcg_temp_new_i32(); + gen_load_fpr32(ctx, fp0, rt); + tcg_gen_ext_i32_tl(t1, fp0); + gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); + tcg_temp_free_i32(fp0); + tcg_temp_free(t1); + break; +#if defined(TARGET_MIPS64) + case OPC_GSSDLC1: + check_cp1_enabled(ctx); + t1 =3D tcg_temp_new(); + gen_base_offset_addr(ctx, t0, rs, shf_offset); + gen_load_fpr64(ctx, t1, rt); + gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); + tcg_temp_free(t1); + break; + case OPC_GSSDRC1: + check_cp1_enabled(ctx); + t1 =3D tcg_temp_new(); + gen_base_offset_addr(ctx, t0, rs, shf_offset); + gen_load_fpr64(ctx, t1, rt); + gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); + tcg_temp_free(t1); + break; +#endif + default: + MIPS_INVAL("loongson_gsshfs"); + generate_exception_end(ctx, EXCP_RI); + break; + } + break; + default: + MIPS_INVAL("loongson_gslsq"); + generate_exception_end(ctx, EXCP_RI); + break; + } + tcg_temp_free(t0); +} + +/* Loongson EXT LDC2/SDC2 */ +static void gen_loongson_lsdc2(DisasContext *ctx, int rt, + int rs, int rd) +{ + int offset =3D sextract32(ctx->opcode, 3, 8); + uint32_t opc =3D MASK_LOONGSON_LSDC2(ctx->opcode); + TCGv t0, t1; + TCGv_i32 fp0; + + /* Pre-conditions */ + switch (opc) { + case OPC_GSLBX: + case OPC_GSLHX: + case OPC_GSLWX: + case OPC_GSLDX: + /* prefetch, implement as NOP */ + if (rt =3D=3D 0) { + return; + } + break; + case OPC_GSSBX: + case OPC_GSSHX: + case OPC_GSSWX: + case OPC_GSSDX: + break; + case OPC_GSLWXC1: +#if defined(TARGET_MIPS64) + case OPC_GSLDXC1: +#endif + check_cp1_enabled(ctx); + /* prefetch, implement as NOP */ + if (rt =3D=3D 0) { + return; + } + break; + case OPC_GSSWXC1: +#if defined(TARGET_MIPS64) + case OPC_GSSDXC1: +#endif + check_cp1_enabled(ctx); + break; + default: + MIPS_INVAL("loongson_lsdc2"); + generate_exception_end(ctx, EXCP_RI); + return; + break; + } + + t0 =3D tcg_temp_new(); + + gen_base_offset_addr(ctx, t0, rs, offset); + gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); + + switch (opc) { + case OPC_GSLBX: + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); + gen_store_gpr(t0, rt); + break; + case OPC_GSLHX: + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | + ctx->default_tcg_memop_mask); + gen_store_gpr(t0, rt); + break; + case OPC_GSLWX: + gen_base_offset_addr(ctx, t0, rs, offset); + if (rd) { + gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); + } + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL | + ctx->default_tcg_memop_mask); + gen_store_gpr(t0, rt); + break; +#if defined(TARGET_MIPS64) + case OPC_GSLDX: + gen_base_offset_addr(ctx, t0, rs, offset); + if (rd) { + gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); + } + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + gen_store_gpr(t0, rt); + break; +#endif + case OPC_GSLWXC1: + check_cp1_enabled(ctx); + gen_base_offset_addr(ctx, t0, rs, offset); + if (rd) { + gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); + } + fp0 =3D tcg_temp_new_i32(); + tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | + ctx->default_tcg_memop_mask); + gen_store_fpr32(ctx, fp0, rt); + tcg_temp_free_i32(fp0); + break; +#if defined(TARGET_MIPS64) + case OPC_GSLDXC1: + check_cp1_enabled(ctx); + gen_base_offset_addr(ctx, t0, rs, offset); + if (rd) { + gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); + } + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + gen_store_fpr64(ctx, t0, rt); + break; +#endif + case OPC_GSSBX: + t1 =3D tcg_temp_new(); + gen_load_gpr(t1, rt); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); + tcg_temp_free(t1); + break; + case OPC_GSSHX: + t1 =3D tcg_temp_new(); + gen_load_gpr(t1, rt); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | + ctx->default_tcg_memop_mask); + tcg_temp_free(t1); + break; + case OPC_GSSWX: + t1 =3D tcg_temp_new(); + gen_load_gpr(t1, rt); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL | + ctx->default_tcg_memop_mask); + tcg_temp_free(t1); + break; +#if defined(TARGET_MIPS64) + case OPC_GSSDX: + t1 =3D tcg_temp_new(); + gen_load_gpr(t1, rt); + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + tcg_temp_free(t1); + break; +#endif + case OPC_GSSWXC1: + fp0 =3D tcg_temp_new_i32(); + gen_load_fpr32(ctx, fp0, rt); + tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | + ctx->default_tcg_memop_mask); + tcg_temp_free_i32(fp0); + break; +#if defined(TARGET_MIPS64) + case OPC_GSSDXC1: + t1 =3D tcg_temp_new(); + gen_load_fpr64(ctx, t1, rt); + tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ | + ctx->default_tcg_memop_mask); + tcg_temp_free(t1); + break; +#endif + default: + break; + } + + tcg_temp_free(t0); +} --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.48 as permitted sender) client-ip=209.85.128.48; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f48.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.48 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906635; cv=none; d=zohomail.com; s=zohoarc; b=lzCcqEwJpOQUMBi1s6qklA4+96nzIBrTUbOJ0Yo6ue8PzacX/RWIeuhom1Y/DlFiKg5i4eeO7EMERKtvdjr53AWFb153RBoWlGb5CYeiIvnM7Ttdi5nTRW2D5uQKVvbNZqfVMV9kTjXg7cmi4P0upFcACQz+eekw7RRUhaEGCac= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906635; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=PqPIQr/zScjTbTc4V5svY5SemWfpLyqb+32G+Ih6C3Q=; b=hhI8lhLMhKkz+Qpgyh4L11gaDxswzxHRQaXMcDUOekbJwoTEFkViY8GYKJd3kedD1zc7nGbZYOf4JUAbLkpDTy+jjpmAErl0SkNIsqefVllLPDlYWGbjcge12bdi1NF9poLbFxoxbZjc0mSZ86Szp4XVe/zaqLhEZVSnOwfrIqs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.48 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) by mx.zohomail.com with SMTPS id 1605906635888606.074332594846; Fri, 20 Nov 2020 13:10:35 -0800 (PST) Received: by mail-wm1-f48.google.com with SMTP id s13so11249191wmh.4 for ; Fri, 20 Nov 2020 13:10:34 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id s2sm5494411wmh.37.2020.11.20.13.10.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PqPIQr/zScjTbTc4V5svY5SemWfpLyqb+32G+Ih6C3Q=; b=a+5RJTPuUamp0TkuHiPOLEHOrARKDsn0hkEPGzBz6XkaGe9r9/6Maa2GlO4zfzxNyb zIqUHkpCpiqp/TuicKaFmmNmPuV7CpZa0Yl5vqMQgfKmc1TLDY8XQPZx1d/dmrE0QW5n U6WFLwD+rSp4VJUJ85Y3XtPs7KGzRXvBjgKznpAFWI5CNNy9XfglEZTCwIUlIfG10CLi zZ7ePvp7iWyKidgJQztRrSB/Sza78aXpdZ2EtzsvJOgbhQgfXyiiyR6x+mxGul8pqxJv +nM6+yssA0NUqCdkApqi7hF0Sux48u4CG6iM3BiEaKRlcxSqf/9fi/JlzXQ9jO67t9y4 eQkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=PqPIQr/zScjTbTc4V5svY5SemWfpLyqb+32G+Ih6C3Q=; b=GXUEnFqGq3E5awQDTIfxI/McaJvaRzc9y1R0tXR6QFPSrXvrLS0I5B0OwmKetWzmBz GXBK3mCTHAyoxoY2/nkUP7t+EMsbD9tdrQRhJtorfuxuneVaGjkraQaj/o3PamEDAKeT GVSZjKcypI/433UVonLzHFkMqwKb2nu4PLhmLKldt7nDOGDD8E6iOqcEt2ZobKR383mO Vt0zmQmi/YEDVa2y4ponlYRiAxMsMohFH2Njn+eOSJHjWES64YLWRj1+KJMqttXsX12s Y+z2Yvutx/b3lQkdH2XWd1CtmzCm2es11vTM8G7WYoWWheczDiekALz7+1b161LcWeiC Jgig== X-Gm-Message-State: AOAM532WxeQw7cTrwR2Hw/57rXzDuESu1250RI1p532JQEp8I3VUzkrD jBo/yM84uw3X/h4mqRQT/5Q= X-Google-Smtp-Source: ABdhPJxyHOVdQ28yJbbw9h5FuOdA1Y6S9wgvg5gRSLEybROkh3yFHe0Y+ps9JsjeypljoRQc9ANVTQ== X-Received: by 2002:a1c:e455:: with SMTP id b82mr11977931wmh.117.1605906632346; Fri, 20 Nov 2020 13:10:32 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 20/26] target/mips: Extract XBurst Media eXtension Unit translation routines Date: Fri, 20 Nov 2020 22:08:38 +0100 Message-Id: <20201120210844.2625602-21-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Media eXtension Unit is a SIMD extension from Ingenic. Extract 2900 lines from the huge translate.c to a new file, 'vendor-xburst_translate.c.inc'. As there are too many inter- dependencies we don't compile it as another object, but keep including it in the big translate.o. We gain in code maintainability. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/translate.c | 2890 +------------------- target/mips/vendor-xburst_translate.c.inc | 2893 +++++++++++++++++++++ 2 files changed, 2894 insertions(+), 2889 deletions(-) create mode 100644 target/mips/vendor-xburst_translate.c.inc diff --git a/target/mips/translate.c b/target/mips/translate.c index 46306ab7e9c..0914b89eae6 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -707,619 +707,6 @@ enum { }; =20 =20 -/* - * - * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET - * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - * - * - * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MI= PS32 - * instructions set. It is designed to fit the needs of signal, graphical = and - * video processing applications. MXU instruction set is used in Xburst fa= mily - * of microprocessors by Ingenic. - * - * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X1= 6 is - * the control register. - * - * - * The notation used in MXU assembler mnemonics - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * Register operands: - * - * XRa, XRb, XRc, XRd - MXU registers - * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers - * - * Non-register operands: - * - * aptn1 - 1-bit accumulate add/subtract pattern - * aptn2 - 2-bit accumulate add/subtract pattern - * eptn2 - 2-bit execute add/subtract pattern - * optn2 - 2-bit operand pattern - * optn3 - 3-bit operand pattern - * sft4 - 4-bit shift amount - * strd2 - 2-bit stride amount - * - * Prefixes: - * - * Level of parallelism: Operand size: - * S - single operation at a time 32 - word - * D - two operations in parallel 16 - half word - * Q - four operations in parallel 8 - byte - * - * Operations: - * - * ADD - Add or subtract - * ADDC - Add with carry-in - * ACC - Accumulate - * ASUM - Sum together then accumulate (add or subtract) - * ASUMC - Sum together then accumulate (add or subtract) with carry-in - * AVG - Average between 2 operands - * ABD - Absolute difference - * ALN - Align data - * AND - Logical bitwise 'and' operation - * CPS - Copy sign - * EXTR - Extract bits - * I2M - Move from GPR register to MXU register - * LDD - Load data from memory to XRF - * LDI - Load data from memory to XRF (and increase the address base) - * LUI - Load unsigned immediate - * MUL - Multiply - * MULU - Unsigned multiply - * MADD - 64-bit operand add 32x32 product - * MSUB - 64-bit operand subtract 32x32 product - * MAC - Multiply and accumulate (add or subtract) - * MAD - Multiply and add or subtract - * MAX - Maximum between 2 operands - * MIN - Minimum between 2 operands - * M2I - Move from MXU register to GPR register - * MOVZ - Move if zero - * MOVN - Move if non-zero - * NOR - Logical bitwise 'nor' operation - * OR - Logical bitwise 'or' operation - * STD - Store data from XRF to memory - * SDI - Store data from XRF to memory (and increase the address base) - * SLT - Set of less than comparison - * SAD - Sum of absolute differences - * SLL - Logical shift left - * SLR - Logical shift right - * SAR - Arithmetic shift right - * SAT - Saturation - * SFL - Shuffle - * SCOP - Calculate x=E2=80=99s scope (-1, means x<0; 0, means x=3D=3D0= ; 1, means x>0) - * XOR - Logical bitwise 'exclusive or' operation - * - * Suffixes: - * - * E - Expand results - * F - Fixed point multiplication - * L - Low part result - * R - Doing rounding - * V - Variable instead of immediate - * W - Combine above L and V - * - * - * The list of MXU instructions grouped by functionality - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * Load/Store instructions Multiplication instructions - * ----------------------- --------------------------- - * - * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt - * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt - * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt - * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt - * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt - * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt - * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2 - * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2 - * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2 - * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, op= tn2 - * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, o= ptn2 - * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, o= ptn2 - * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, o= ptn2 - * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, op= tn2 - * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd - * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd - * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2 - * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2 - * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2 - * S16SDI XRa, Rb, s10, eptn2 - * S8LDD XRa, Rb, s8, eptn3 - * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions - * S8LDI XRa, Rb, s8, eptn3 ------------------------------------- - * S8SDI XRa, Rb, s8, eptn3 - * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2 - * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd - * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2 - * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2 - * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2 - * S32CPS XRa, XRb, XRc - * Q16ADD XRa, XRb, XRc, XRd, eptn2, op= tn2 - * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2 - * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2 - * D16ASUM XRa, XRb, XRc, XRd, eptn2 - * S32MAX XRa, XRb, XRc D16CPS XRa, XRb, - * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc - * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc - * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2 - * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2 - * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2 - * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc - * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd - * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc - * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc - * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd - * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd - * Q8SLT XRa, XRb, XRc - * Q8SLTU XRa, XRb, XRc - * Q8MOVZ XRa, XRb, XRc Shift instructions - * Q8MOVN XRa, XRb, XRc ------------------ - * - * D32SLL XRa, XRb, XRc, XRd, sft4 - * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4 - * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4 - * D32SARL XRa, XRb, XRc, sft4 - * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb - * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb - * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb - * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb - * Q16SLL XRa, XRb, XRc, XRd, sft4 - * Q16SLR XRa, XRb, XRc, XRd, sft4 - * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4 - * ------------------------- Q16SLLV XRa, XRb, Rb - * Q16SLRV XRa, XRb, Rb - * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb - * S32ALN XRa, XRb, XRc, Rb - * S32ALNI XRa, XRb, XRc, s3 - * S32LUI XRa, s8, optn3 Move instructions - * S32EXTR XRa, XRb, Rb, bits5 ----------------- - * S32EXTRV XRa, XRb, Rs, Rt - * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb - * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb - * - * - * The opcode organization of MXU instructions - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred - * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning = of - * other bits up to the instruction level is as follows: - * - * bits - * 05..00 - * - * =E2=94=8C=E2=94=80 000000 =E2=94=80 OPC_MXU_S32MADD - * =E2=94=9C=E2=94=80 000001 =E2=94=80 OPC_MXU_S32MADDU - * =E2=94=9C=E2=94=80 000010 =E2=94=80 (non-MXU = OPC_MUL) - * =E2=94=82 - * =E2=94=82 20..18 - * =E2=94=9C=E2=94=80 000011 =E2=94=80 OPC_MXU__POOL00 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_S32MAX - * =E2=94=82 =E2=94=9C=E2=94=80 001 = =E2=94=80 OPC_MXU_S32MIN - * =E2=94=82 =E2=94=9C=E2=94=80 010 = =E2=94=80 OPC_MXU_D16MAX - * =E2=94=82 =E2=94=9C=E2=94=80 011 = =E2=94=80 OPC_MXU_D16MIN - * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_Q8MAX - * =E2=94=82 =E2=94=9C=E2=94=80 101 = =E2=94=80 OPC_MXU_Q8MIN - * =E2=94=82 =E2=94=9C=E2=94=80 110 = =E2=94=80 OPC_MXU_Q8SLT - * =E2=94=82 =E2=94=94=E2=94=80 111 = =E2=94=80 OPC_MXU_Q8SLTU - * =E2=94=9C=E2=94=80 000100 =E2=94=80 OPC_MXU_S32MSUB - * =E2=94=9C=E2=94=80 000101 =E2=94=80 OPC_MXU_S32MSUBU 20..18 - * =E2=94=9C=E2=94=80 000110 =E2=94=80 OPC_MXU__POOL01 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_S32SLT - * =E2=94=82 =E2=94=9C=E2=94=80 001 = =E2=94=80 OPC_MXU_D16SLT - * =E2=94=82 =E2=94=9C=E2=94=80 010 = =E2=94=80 OPC_MXU_D16AVG - * =E2=94=82 =E2=94=9C=E2=94=80 011 = =E2=94=80 OPC_MXU_D16AVGR - * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_Q8AVG - * =E2=94=82 =E2=94=9C=E2=94=80 101 = =E2=94=80 OPC_MXU_Q8AVGR - * =E2=94=82 =E2=94=94=E2=94=80 111 = =E2=94=80 OPC_MXU_Q8ADD - * =E2=94=82 - * =E2=94=82 20..18 - * =E2=94=9C=E2=94=80 000111 =E2=94=80 OPC_MXU__POOL02 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_S32CPS - * =E2=94=82 =E2=94=9C=E2=94=80 010 = =E2=94=80 OPC_MXU_D16CPS - * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_Q8ABD - * =E2=94=82 =E2=94=94=E2=94=80 110 = =E2=94=80 OPC_MXU_Q16SAT - * =E2=94=9C=E2=94=80 001000 =E2=94=80 OPC_MXU_D16MUL - * =E2=94=82 25..24 - * =E2=94=9C=E2=94=80 001001 =E2=94=80 OPC_MXU__POOL03 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_D16MULF - * =E2=94=82 =E2=94=94=E2=94=80 01 =E2= =94=80 OPC_MXU_D16MULE - * =E2=94=9C=E2=94=80 001010 =E2=94=80 OPC_MXU_D16MAC - * =E2=94=9C=E2=94=80 001011 =E2=94=80 OPC_MXU_D16MACF - * =E2=94=9C=E2=94=80 001100 =E2=94=80 OPC_MXU_D16MADL - * =E2=94=9C=E2=94=80 001101 =E2=94=80 OPC_MXU_S16MAD - * =E2=94=9C=E2=94=80 001110 =E2=94=80 OPC_MXU_Q16ADD - * =E2=94=9C=E2=94=80 001111 =E2=94=80 OPC_MXU_D16MACE 23 - * =E2=94=82 =E2=94=8C=E2=94=80 0 =E2= =94=80 OPC_MXU_S32LDD - * =E2=94=9C=E2=94=80 010000 =E2=94=80 OPC_MXU__POOL04 =E2=94=80= =E2=94=B4=E2=94=80 1 =E2=94=80 OPC_MXU_S32LDDR - * =E2=94=82 - * =E2=94=82 23 - * =E2=94=9C=E2=94=80 010001 =E2=94=80 OPC_MXU__POOL05 =E2=94=80= =E2=94=AC=E2=94=80 0 =E2=94=80 OPC_MXU_S32STD - * =E2=94=82 =E2=94=94=E2=94=80 1 =E2= =94=80 OPC_MXU_S32STDR - * =E2=94=82 - * =E2=94=82 13..10 - * =E2=94=9C=E2=94=80 010010 =E2=94=80 OPC_MXU__POOL06 =E2=94=80= =E2=94=AC=E2=94=80 0000 =E2=94=80 OPC_MXU_S32LDDV - * =E2=94=82 =E2=94=94=E2=94=80 0001 = =E2=94=80 OPC_MXU_S32LDDVR - * =E2=94=82 - * =E2=94=82 13..10 - * =E2=94=9C=E2=94=80 010011 =E2=94=80 OPC_MXU__POOL07 =E2=94=80= =E2=94=AC=E2=94=80 0000 =E2=94=80 OPC_MXU_S32STDV - * =E2=94=82 =E2=94=94=E2=94=80 0001 = =E2=94=80 OPC_MXU_S32STDVR - * =E2=94=82 - * =E2=94=82 23 - * =E2=94=9C=E2=94=80 010100 =E2=94=80 OPC_MXU__POOL08 =E2=94=80= =E2=94=AC=E2=94=80 0 =E2=94=80 OPC_MXU_S32LDI - * =E2=94=82 =E2=94=94=E2=94=80 1 =E2= =94=80 OPC_MXU_S32LDIR - * =E2=94=82 - * =E2=94=82 23 - * =E2=94=9C=E2=94=80 010101 =E2=94=80 OPC_MXU__POOL09 =E2=94=80= =E2=94=AC=E2=94=80 0 =E2=94=80 OPC_MXU_S32SDI - * =E2=94=82 =E2=94=94=E2=94=80 1 =E2= =94=80 OPC_MXU_S32SDIR - * =E2=94=82 - * =E2=94=82 13..10 - * =E2=94=9C=E2=94=80 010110 =E2=94=80 OPC_MXU__POOL10 =E2=94=80= =E2=94=AC=E2=94=80 0000 =E2=94=80 OPC_MXU_S32LDIV - * =E2=94=82 =E2=94=94=E2=94=80 0001 = =E2=94=80 OPC_MXU_S32LDIVR - * =E2=94=82 - * =E2=94=82 13..10 - * =E2=94=9C=E2=94=80 010111 =E2=94=80 OPC_MXU__POOL11 =E2=94=80= =E2=94=AC=E2=94=80 0000 =E2=94=80 OPC_MXU_S32SDIV - * =E2=94=82 =E2=94=94=E2=94=80 0001 = =E2=94=80 OPC_MXU_S32SDIVR - * =E2=94=9C=E2=94=80 011000 =E2=94=80 OPC_MXU_D32ADD - * =E2=94=82 23..22 - * MXU =E2=94=9C=E2=94=80 011001 =E2=94=80 OPC_MXU__POOL12 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_D32ACC - * opcodes =E2=94=80=E2=94=A4 =E2=94=9C=E2=94= =80 01 =E2=94=80 OPC_MXU_D32ACCM - * =E2=94=82 =E2=94=94=E2=94=80 10 =E2= =94=80 OPC_MXU_D32ASUM - * =E2=94=9C=E2=94=80 011010 =E2=94=80 - * =E2=94=82 23..22 - * =E2=94=9C=E2=94=80 011011 =E2=94=80 OPC_MXU__POOL13 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_Q16ACC - * =E2=94=82 =E2=94=9C=E2=94=80 01 =E2= =94=80 OPC_MXU_Q16ACCM - * =E2=94=82 =E2=94=94=E2=94=80 10 =E2= =94=80 OPC_MXU_Q16ASUM - * =E2=94=82 - * =E2=94=82 23..22 - * =E2=94=9C=E2=94=80 011100 =E2=94=80 OPC_MXU__POOL14 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_Q8ADDE - * =E2=94=82 =E2=94=9C=E2=94=80 01 =E2= =94=80 OPC_MXU_D8SUM - * =E2=94=9C=E2=94=80 011101 =E2=94=80 OPC_MXU_Q8ACCE =E2=94=94= =E2=94=80 10 =E2=94=80 OPC_MXU_D8SUMC - * =E2=94=9C=E2=94=80 011110 =E2=94=80 - * =E2=94=9C=E2=94=80 011111 =E2=94=80 - * =E2=94=9C=E2=94=80 100000 =E2=94=80 (overlaps= with CLZ) - * =E2=94=9C=E2=94=80 100001 =E2=94=80 (overlaps= with CLO) - * =E2=94=9C=E2=94=80 100010 =E2=94=80 OPC_MXU_S8LDD - * =E2=94=9C=E2=94=80 100011 =E2=94=80 OPC_MXU_S8STD 15..14 - * =E2=94=9C=E2=94=80 100100 =E2=94=80 OPC_MXU_S8LDI =E2=94=8C= =E2=94=80 00 =E2=94=80 OPC_MXU_S32MUL - * =E2=94=9C=E2=94=80 100101 =E2=94=80 OPC_MXU_S8SDI =E2=94=9C= =E2=94=80 00 =E2=94=80 OPC_MXU_S32MULU - * =E2=94=82 =E2=94=9C=E2=94=80 00 =E2= =94=80 OPC_MXU_S32EXTR - * =E2=94=9C=E2=94=80 100110 =E2=94=80 OPC_MXU__POOL15 =E2=94=80= =E2=94=B4=E2=94=80 00 =E2=94=80 OPC_MXU_S32EXTRV - * =E2=94=82 - * =E2=94=82 20..18 - * =E2=94=9C=E2=94=80 100111 =E2=94=80 OPC_MXU__POOL16 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_D32SARW - * =E2=94=82 =E2=94=9C=E2=94=80 001 = =E2=94=80 OPC_MXU_S32ALN - * =E2=94=82 =E2=94=9C=E2=94=80 010 = =E2=94=80 OPC_MXU_S32ALNI - * =E2=94=82 =E2=94=9C=E2=94=80 011 = =E2=94=80 OPC_MXU_S32LUI - * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_S32NOR - * =E2=94=82 =E2=94=9C=E2=94=80 101 = =E2=94=80 OPC_MXU_S32AND - * =E2=94=82 =E2=94=9C=E2=94=80 110 = =E2=94=80 OPC_MXU_S32OR - * =E2=94=82 =E2=94=94=E2=94=80 111 = =E2=94=80 OPC_MXU_S32XOR - * =E2=94=82 - * =E2=94=82 7..5 - * =E2=94=9C=E2=94=80 101000 =E2=94=80 OPC_MXU__POOL17 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_LXB - * =E2=94=82 =E2=94=9C=E2=94=80 001 = =E2=94=80 OPC_MXU_LXH - * =E2=94=9C=E2=94=80 101001 =E2=94=80 =E2=94=9C= =E2=94=80 011 =E2=94=80 OPC_MXU_LXW - * =E2=94=9C=E2=94=80 101010 =E2=94=80 OPC_MXU_S16LDD =E2=94=9C= =E2=94=80 100 =E2=94=80 OPC_MXU_LXBU - * =E2=94=9C=E2=94=80 101011 =E2=94=80 OPC_MXU_S16STD =E2=94=94= =E2=94=80 101 =E2=94=80 OPC_MXU_LXHU - * =E2=94=9C=E2=94=80 101100 =E2=94=80 OPC_MXU_S16LDI - * =E2=94=9C=E2=94=80 101101 =E2=94=80 OPC_MXU_S16SDI - * =E2=94=9C=E2=94=80 101110 =E2=94=80 OPC_MXU_S32M2I - * =E2=94=9C=E2=94=80 101111 =E2=94=80 OPC_MXU_S32I2M - * =E2=94=9C=E2=94=80 110000 =E2=94=80 OPC_MXU_D32SLL - * =E2=94=9C=E2=94=80 110001 =E2=94=80 OPC_MXU_D32SLR 20..18 - * =E2=94=9C=E2=94=80 110010 =E2=94=80 OPC_MXU_D32SARL =E2=94=8C= =E2=94=80 000 =E2=94=80 OPC_MXU_D32SLLV - * =E2=94=9C=E2=94=80 110011 =E2=94=80 OPC_MXU_D32SAR =E2=94=9C= =E2=94=80 001 =E2=94=80 OPC_MXU_D32SLRV - * =E2=94=9C=E2=94=80 110100 =E2=94=80 OPC_MXU_Q16SLL =E2=94=9C= =E2=94=80 010 =E2=94=80 OPC_MXU_D32SARV - * =E2=94=9C=E2=94=80 110101 =E2=94=80 OPC_MXU_Q16SLR =E2=94=9C= =E2=94=80 011 =E2=94=80 OPC_MXU_Q16SLLV - * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_Q16SLRV - * =E2=94=9C=E2=94=80 110110 =E2=94=80 OPC_MXU__POOL18 =E2=94=80= =E2=94=B4=E2=94=80 101 =E2=94=80 OPC_MXU_Q16SARV - * =E2=94=82 - * =E2=94=9C=E2=94=80 110111 =E2=94=80 OPC_MXU_Q16SAR - * =E2=94=82 23..22 - * =E2=94=9C=E2=94=80 111000 =E2=94=80 OPC_MXU__POOL19 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_Q8MUL - * =E2=94=82 =E2=94=94=E2=94=80 01 =E2= =94=80 OPC_MXU_Q8MULSU - * =E2=94=82 - * =E2=94=82 20..18 - * =E2=94=9C=E2=94=80 111001 =E2=94=80 OPC_MXU__POOL20 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_Q8MOVZ - * =E2=94=82 =E2=94=9C=E2=94=80 001 = =E2=94=80 OPC_MXU_Q8MOVN - * =E2=94=82 =E2=94=9C=E2=94=80 010 = =E2=94=80 OPC_MXU_D16MOVZ - * =E2=94=82 =E2=94=9C=E2=94=80 011 = =E2=94=80 OPC_MXU_D16MOVN - * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_S32MOVZ - * =E2=94=82 =E2=94=94=E2=94=80 101 = =E2=94=80 OPC_MXU_S32MOVN - * =E2=94=82 - * =E2=94=82 23..22 - * =E2=94=9C=E2=94=80 111010 =E2=94=80 OPC_MXU__POOL21 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_Q8MAC - * =E2=94=82 =E2=94=94=E2=94=80 10 =E2= =94=80 OPC_MXU_Q8MACSU - * =E2=94=9C=E2=94=80 111011 =E2=94=80 OPC_MXU_Q16SCOP - * =E2=94=9C=E2=94=80 111100 =E2=94=80 OPC_MXU_Q8MADL - * =E2=94=9C=E2=94=80 111101 =E2=94=80 OPC_MXU_S32SFL - * =E2=94=9C=E2=94=80 111110 =E2=94=80 OPC_MXU_Q8SAD - * =E2=94=94=E2=94=80 111111 =E2=94=80 (overlaps= with SDBBP) - * - * - * Compiled after: - * - * "XBurst=C2=AE Instruction Set Architecture MIPS eXtension/enhanced Un= it - * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2,= 2017 - */ - -enum { - OPC_MXU_S32MADD =3D 0x00, - OPC_MXU_S32MADDU =3D 0x01, - OPC__MXU_MUL =3D 0x02, - OPC_MXU__POOL00 =3D 0x03, - OPC_MXU_S32MSUB =3D 0x04, - OPC_MXU_S32MSUBU =3D 0x05, - OPC_MXU__POOL01 =3D 0x06, - OPC_MXU__POOL02 =3D 0x07, - OPC_MXU_D16MUL =3D 0x08, - OPC_MXU__POOL03 =3D 0x09, - OPC_MXU_D16MAC =3D 0x0A, - OPC_MXU_D16MACF =3D 0x0B, - OPC_MXU_D16MADL =3D 0x0C, - OPC_MXU_S16MAD =3D 0x0D, - OPC_MXU_Q16ADD =3D 0x0E, - OPC_MXU_D16MACE =3D 0x0F, - OPC_MXU__POOL04 =3D 0x10, - OPC_MXU__POOL05 =3D 0x11, - OPC_MXU__POOL06 =3D 0x12, - OPC_MXU__POOL07 =3D 0x13, - OPC_MXU__POOL08 =3D 0x14, - OPC_MXU__POOL09 =3D 0x15, - OPC_MXU__POOL10 =3D 0x16, - OPC_MXU__POOL11 =3D 0x17, - OPC_MXU_D32ADD =3D 0x18, - OPC_MXU__POOL12 =3D 0x19, - /* not assigned 0x1A */ - OPC_MXU__POOL13 =3D 0x1B, - OPC_MXU__POOL14 =3D 0x1C, - OPC_MXU_Q8ACCE =3D 0x1D, - /* not assigned 0x1E */ - /* not assigned 0x1F */ - /* not assigned 0x20 */ - /* not assigned 0x21 */ - OPC_MXU_S8LDD =3D 0x22, - OPC_MXU_S8STD =3D 0x23, - OPC_MXU_S8LDI =3D 0x24, - OPC_MXU_S8SDI =3D 0x25, - OPC_MXU__POOL15 =3D 0x26, - OPC_MXU__POOL16 =3D 0x27, - OPC_MXU__POOL17 =3D 0x28, - /* not assigned 0x29 */ - OPC_MXU_S16LDD =3D 0x2A, - OPC_MXU_S16STD =3D 0x2B, - OPC_MXU_S16LDI =3D 0x2C, - OPC_MXU_S16SDI =3D 0x2D, - OPC_MXU_S32M2I =3D 0x2E, - OPC_MXU_S32I2M =3D 0x2F, - OPC_MXU_D32SLL =3D 0x30, - OPC_MXU_D32SLR =3D 0x31, - OPC_MXU_D32SARL =3D 0x32, - OPC_MXU_D32SAR =3D 0x33, - OPC_MXU_Q16SLL =3D 0x34, - OPC_MXU_Q16SLR =3D 0x35, - OPC_MXU__POOL18 =3D 0x36, - OPC_MXU_Q16SAR =3D 0x37, - OPC_MXU__POOL19 =3D 0x38, - OPC_MXU__POOL20 =3D 0x39, - OPC_MXU__POOL21 =3D 0x3A, - OPC_MXU_Q16SCOP =3D 0x3B, - OPC_MXU_Q8MADL =3D 0x3C, - OPC_MXU_S32SFL =3D 0x3D, - OPC_MXU_Q8SAD =3D 0x3E, - /* not assigned 0x3F */ -}; - - -/* - * MXU pool 00 - */ -enum { - OPC_MXU_S32MAX =3D 0x00, - OPC_MXU_S32MIN =3D 0x01, - OPC_MXU_D16MAX =3D 0x02, - OPC_MXU_D16MIN =3D 0x03, - OPC_MXU_Q8MAX =3D 0x04, - OPC_MXU_Q8MIN =3D 0x05, - OPC_MXU_Q8SLT =3D 0x06, - OPC_MXU_Q8SLTU =3D 0x07, -}; - -/* - * MXU pool 01 - */ -enum { - OPC_MXU_S32SLT =3D 0x00, - OPC_MXU_D16SLT =3D 0x01, - OPC_MXU_D16AVG =3D 0x02, - OPC_MXU_D16AVGR =3D 0x03, - OPC_MXU_Q8AVG =3D 0x04, - OPC_MXU_Q8AVGR =3D 0x05, - OPC_MXU_Q8ADD =3D 0x07, -}; - -/* - * MXU pool 02 - */ -enum { - OPC_MXU_S32CPS =3D 0x00, - OPC_MXU_D16CPS =3D 0x02, - OPC_MXU_Q8ABD =3D 0x04, - OPC_MXU_Q16SAT =3D 0x06, -}; - -/* - * MXU pool 03 - */ -enum { - OPC_MXU_D16MULF =3D 0x00, - OPC_MXU_D16MULE =3D 0x01, -}; - -/* - * MXU pool 04 - */ -enum { - OPC_MXU_S32LDD =3D 0x00, - OPC_MXU_S32LDDR =3D 0x01, -}; - -/* - * MXU pool 05 - */ -enum { - OPC_MXU_S32STD =3D 0x00, - OPC_MXU_S32STDR =3D 0x01, -}; - -/* - * MXU pool 06 - */ -enum { - OPC_MXU_S32LDDV =3D 0x00, - OPC_MXU_S32LDDVR =3D 0x01, -}; - -/* - * MXU pool 07 - */ -enum { - OPC_MXU_S32STDV =3D 0x00, - OPC_MXU_S32STDVR =3D 0x01, -}; - -/* - * MXU pool 08 - */ -enum { - OPC_MXU_S32LDI =3D 0x00, - OPC_MXU_S32LDIR =3D 0x01, -}; - -/* - * MXU pool 09 - */ -enum { - OPC_MXU_S32SDI =3D 0x00, - OPC_MXU_S32SDIR =3D 0x01, -}; - -/* - * MXU pool 10 - */ -enum { - OPC_MXU_S32LDIV =3D 0x00, - OPC_MXU_S32LDIVR =3D 0x01, -}; - -/* - * MXU pool 11 - */ -enum { - OPC_MXU_S32SDIV =3D 0x00, - OPC_MXU_S32SDIVR =3D 0x01, -}; - -/* - * MXU pool 12 - */ -enum { - OPC_MXU_D32ACC =3D 0x00, - OPC_MXU_D32ACCM =3D 0x01, - OPC_MXU_D32ASUM =3D 0x02, -}; - -/* - * MXU pool 13 - */ -enum { - OPC_MXU_Q16ACC =3D 0x00, - OPC_MXU_Q16ACCM =3D 0x01, - OPC_MXU_Q16ASUM =3D 0x02, -}; - -/* - * MXU pool 14 - */ -enum { - OPC_MXU_Q8ADDE =3D 0x00, - OPC_MXU_D8SUM =3D 0x01, - OPC_MXU_D8SUMC =3D 0x02, -}; - -/* - * MXU pool 15 - */ -enum { - OPC_MXU_S32MUL =3D 0x00, - OPC_MXU_S32MULU =3D 0x01, - OPC_MXU_S32EXTR =3D 0x02, - OPC_MXU_S32EXTRV =3D 0x03, -}; - -/* - * MXU pool 16 - */ -enum { - OPC_MXU_D32SARW =3D 0x00, - OPC_MXU_S32ALN =3D 0x01, - OPC_MXU_S32ALNI =3D 0x02, - OPC_MXU_S32LUI =3D 0x03, - OPC_MXU_S32NOR =3D 0x04, - OPC_MXU_S32AND =3D 0x05, - OPC_MXU_S32OR =3D 0x06, - OPC_MXU_S32XOR =3D 0x07, -}; - -/* - * MXU pool 17 - */ -enum { - OPC_MXU_LXB =3D 0x00, - OPC_MXU_LXH =3D 0x01, - OPC_MXU_LXW =3D 0x03, - OPC_MXU_LXBU =3D 0x04, - OPC_MXU_LXHU =3D 0x05, -}; - -/* - * MXU pool 18 - */ -enum { - OPC_MXU_D32SLLV =3D 0x00, - OPC_MXU_D32SLRV =3D 0x01, - OPC_MXU_D32SARV =3D 0x03, - OPC_MXU_Q16SLLV =3D 0x04, - OPC_MXU_Q16SLRV =3D 0x05, - OPC_MXU_Q16SARV =3D 0x07, -}; - -/* - * MXU pool 19 - */ -enum { - OPC_MXU_Q8MUL =3D 0x00, - OPC_MXU_Q8MULSU =3D 0x01, -}; - -/* - * MXU pool 20 - */ -enum { - OPC_MXU_Q8MOVZ =3D 0x00, - OPC_MXU_Q8MOVN =3D 0x01, - OPC_MXU_D16MOVZ =3D 0x02, - OPC_MXU_D16MOVN =3D 0x03, - OPC_MXU_S32MOVZ =3D 0x04, - OPC_MXU_S32MOVN =3D 0x05, -}; - -/* - * MXU pool 21 - */ -enum { - OPC_MXU_Q8MAC =3D 0x00, - OPC_MXU_Q8MACSU =3D 0x01, -}; - /* * Overview of the TX79-specific instruction set * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D @@ -1769,12 +1156,6 @@ static TCGv_i64 fpu_f64[32]; static TCGv_i64 cpu_mmr[32]; #endif =20 -#if !defined(TARGET_MIPS64) -/* MXU registers */ -static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1]; -static TCGv mxu_CR; -#endif - #include "exec/gen-icount.h" =20 #define gen_helper_0e0i(name, arg) do { \ @@ -1881,13 +1262,6 @@ static const char * const fregnames[] =3D { "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", }; =20 -#if !defined(TARGET_MIPS64) -static const char * const mxuregnames[] =3D { - "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8", - "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR", -}; -#endif - #define LOG_DISAS(...) = \ do { = \ if (MIPS_DEBUG_DISAS) { = \ @@ -1971,37 +1345,6 @@ static inline void gen_store_srsgpr(int from, int to) } } =20 -#if !defined(TARGET_MIPS64) -/* MXU General purpose registers moves. */ -static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg) -{ - if (reg =3D=3D 0) { - tcg_gen_movi_tl(t, 0); - } else if (reg <=3D 15) { - tcg_gen_mov_tl(t, mxu_gpr[reg - 1]); - } -} - -static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg) -{ - if (reg > 0 && reg <=3D 15) { - tcg_gen_mov_tl(mxu_gpr[reg - 1], t); - } -} - -/* MXU control register moves. */ -static inline void gen_load_mxu_cr(TCGv t) -{ - tcg_gen_mov_tl(t, mxu_CR); -} - -static inline void gen_store_mxu_cr(TCGv t) -{ - /* TODO: Add handling of RW rules for MXU_CR. */ - tcg_gen_mov_tl(mxu_CR, t); -} -#endif - =20 /* Tests */ static inline void gen_save_pc(target_ulong pc) @@ -11905,6 +11248,7 @@ out: #include "vendor-vr54xx_translate.c.inc" #include "vendor-loong-simd_translate.c.inc" #include "vendor-loong-lext_translate.c.inc" +#include "vendor-xburst_translate.c.inc" =20 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) { @@ -12520,2238 +11864,6 @@ static void gen_mmi_pcpyud(DisasContext *ctx) =20 #endif =20 - -#if !defined(TARGET_MIPS64) - -/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */ -#define MXU_APTN1_A 0 -#define MXU_APTN1_S 1 - -/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */ -#define MXU_APTN2_AA 0 -#define MXU_APTN2_AS 1 -#define MXU_APTN2_SA 2 -#define MXU_APTN2_SS 3 - -/* MXU execute add/subtract 2-bit pattern 'eptn2' */ -#define MXU_EPTN2_AA 0 -#define MXU_EPTN2_AS 1 -#define MXU_EPTN2_SA 2 -#define MXU_EPTN2_SS 3 - -/* MXU operand getting pattern 'optn2' */ -#define MXU_OPTN2_PTN0 0 -#define MXU_OPTN2_PTN1 1 -#define MXU_OPTN2_PTN2 2 -#define MXU_OPTN2_PTN3 3 -/* alternative naming scheme for 'optn2' */ -#define MXU_OPTN2_WW 0 -#define MXU_OPTN2_LW 1 -#define MXU_OPTN2_HW 2 -#define MXU_OPTN2_XW 3 - -/* MXU operand getting pattern 'optn3' */ -#define MXU_OPTN3_PTN0 0 -#define MXU_OPTN3_PTN1 1 -#define MXU_OPTN3_PTN2 2 -#define MXU_OPTN3_PTN3 3 -#define MXU_OPTN3_PTN4 4 -#define MXU_OPTN3_PTN5 5 -#define MXU_OPTN3_PTN6 6 -#define MXU_OPTN3_PTN7 7 - - -/* - * S32I2M XRa, rb - Register move from GRF to XRF - */ -static void gen_mxu_s32i2m(DisasContext *ctx) -{ - TCGv t0; - uint32_t XRa, Rb; - - t0 =3D tcg_temp_new(); - - XRa =3D extract32(ctx->opcode, 6, 5); - Rb =3D extract32(ctx->opcode, 16, 5); - - gen_load_gpr(t0, Rb); - if (XRa <=3D 15) { - gen_store_mxu_gpr(t0, XRa); - } else if (XRa =3D=3D 16) { - gen_store_mxu_cr(t0); - } - - tcg_temp_free(t0); -} - -/* - * S32M2I XRa, rb - Register move from XRF to GRF - */ -static void gen_mxu_s32m2i(DisasContext *ctx) -{ - TCGv t0; - uint32_t XRa, Rb; - - t0 =3D tcg_temp_new(); - - XRa =3D extract32(ctx->opcode, 6, 5); - Rb =3D extract32(ctx->opcode, 16, 5); - - if (XRa <=3D 15) { - gen_load_mxu_gpr(t0, XRa); - } else if (XRa =3D=3D 16) { - gen_load_mxu_cr(t0); - } - - gen_store_gpr(t0, Rb); - - tcg_temp_free(t0); -} - -/* - * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF - */ -static void gen_mxu_s8ldd(DisasContext *ctx) -{ - TCGv t0, t1; - uint32_t XRa, Rb, s8, optn3; - - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - - XRa =3D extract32(ctx->opcode, 6, 4); - s8 =3D extract32(ctx->opcode, 10, 8); - optn3 =3D extract32(ctx->opcode, 18, 3); - Rb =3D extract32(ctx->opcode, 21, 5); - - gen_load_gpr(t0, Rb); - tcg_gen_addi_tl(t0, t0, (int8_t)s8); - - switch (optn3) { - /* XRa[7:0] =3D tmp8 */ - case MXU_OPTN3_PTN0: - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - gen_load_mxu_gpr(t0, XRa); - tcg_gen_deposit_tl(t0, t0, t1, 0, 8); - break; - /* XRa[15:8] =3D tmp8 */ - case MXU_OPTN3_PTN1: - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - gen_load_mxu_gpr(t0, XRa); - tcg_gen_deposit_tl(t0, t0, t1, 8, 8); - break; - /* XRa[23:16] =3D tmp8 */ - case MXU_OPTN3_PTN2: - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - gen_load_mxu_gpr(t0, XRa); - tcg_gen_deposit_tl(t0, t0, t1, 16, 8); - break; - /* XRa[31:24] =3D tmp8 */ - case MXU_OPTN3_PTN3: - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - gen_load_mxu_gpr(t0, XRa); - tcg_gen_deposit_tl(t0, t0, t1, 24, 8); - break; - /* XRa =3D {8'b0, tmp8, 8'b0, tmp8} */ - case MXU_OPTN3_PTN4: - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - tcg_gen_deposit_tl(t0, t1, t1, 16, 16); - break; - /* XRa =3D {tmp8, 8'b0, tmp8, 8'b0} */ - case MXU_OPTN3_PTN5: - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - tcg_gen_shli_tl(t1, t1, 8); - tcg_gen_deposit_tl(t0, t1, t1, 16, 16); - break; - /* XRa =3D {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */ - case MXU_OPTN3_PTN6: - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB); - tcg_gen_mov_tl(t0, t1); - tcg_gen_andi_tl(t0, t0, 0xFF00FFFF); - tcg_gen_shli_tl(t1, t1, 16); - tcg_gen_or_tl(t0, t0, t1); - break; - /* XRa =3D {tmp8, tmp8, tmp8, tmp8} */ - case MXU_OPTN3_PTN7: - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); - tcg_gen_deposit_tl(t1, t1, t1, 8, 8); - tcg_gen_deposit_tl(t0, t1, t1, 16, 16); - break; - } - - gen_store_mxu_gpr(t0, XRa); - - tcg_temp_free(t0); - tcg_temp_free(t1); -} - -/* - * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication - */ -static void gen_mxu_d16mul(DisasContext *ctx) -{ - TCGv t0, t1, t2, t3; - uint32_t XRa, XRb, XRc, XRd, optn2; - - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - t2 =3D tcg_temp_new(); - t3 =3D tcg_temp_new(); - - XRa =3D extract32(ctx->opcode, 6, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRc =3D extract32(ctx->opcode, 14, 4); - XRd =3D extract32(ctx->opcode, 18, 4); - optn2 =3D extract32(ctx->opcode, 22, 2); - - gen_load_mxu_gpr(t1, XRb); - tcg_gen_sextract_tl(t0, t1, 0, 16); - tcg_gen_sextract_tl(t1, t1, 16, 16); - gen_load_mxu_gpr(t3, XRc); - tcg_gen_sextract_tl(t2, t3, 0, 16); - tcg_gen_sextract_tl(t3, t3, 16, 16); - - switch (optn2) { - case MXU_OPTN2_WW: /* XRB.H*XRC.H =3D=3D lop, XRB.L*XRC.L =3D=3D rop */ - tcg_gen_mul_tl(t3, t1, t3); - tcg_gen_mul_tl(t2, t0, t2); - break; - case MXU_OPTN2_LW: /* XRB.L*XRC.H =3D=3D lop, XRB.L*XRC.L =3D=3D rop */ - tcg_gen_mul_tl(t3, t0, t3); - tcg_gen_mul_tl(t2, t0, t2); - break; - case MXU_OPTN2_HW: /* XRB.H*XRC.H =3D=3D lop, XRB.H*XRC.L =3D=3D rop */ - tcg_gen_mul_tl(t3, t1, t3); - tcg_gen_mul_tl(t2, t1, t2); - break; - case MXU_OPTN2_XW: /* XRB.L*XRC.H =3D=3D lop, XRB.H*XRC.L =3D=3D rop */ - tcg_gen_mul_tl(t3, t0, t3); - tcg_gen_mul_tl(t2, t1, t2); - break; - } - gen_store_mxu_gpr(t3, XRa); - gen_store_mxu_gpr(t2, XRd); - - tcg_temp_free(t0); - tcg_temp_free(t1); - tcg_temp_free(t2); - tcg_temp_free(t3); -} - -/* - * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply - * and accumulate - */ -static void gen_mxu_d16mac(DisasContext *ctx) -{ - TCGv t0, t1, t2, t3; - uint32_t XRa, XRb, XRc, XRd, optn2, aptn2; - - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - t2 =3D tcg_temp_new(); - t3 =3D tcg_temp_new(); - - XRa =3D extract32(ctx->opcode, 6, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRc =3D extract32(ctx->opcode, 14, 4); - XRd =3D extract32(ctx->opcode, 18, 4); - optn2 =3D extract32(ctx->opcode, 22, 2); - aptn2 =3D extract32(ctx->opcode, 24, 2); - - gen_load_mxu_gpr(t1, XRb); - tcg_gen_sextract_tl(t0, t1, 0, 16); - tcg_gen_sextract_tl(t1, t1, 16, 16); - - gen_load_mxu_gpr(t3, XRc); - tcg_gen_sextract_tl(t2, t3, 0, 16); - tcg_gen_sextract_tl(t3, t3, 16, 16); - - switch (optn2) { - case MXU_OPTN2_WW: /* XRB.H*XRC.H =3D=3D lop, XRB.L*XRC.L =3D=3D rop */ - tcg_gen_mul_tl(t3, t1, t3); - tcg_gen_mul_tl(t2, t0, t2); - break; - case MXU_OPTN2_LW: /* XRB.L*XRC.H =3D=3D lop, XRB.L*XRC.L =3D=3D rop */ - tcg_gen_mul_tl(t3, t0, t3); - tcg_gen_mul_tl(t2, t0, t2); - break; - case MXU_OPTN2_HW: /* XRB.H*XRC.H =3D=3D lop, XRB.H*XRC.L =3D=3D rop */ - tcg_gen_mul_tl(t3, t1, t3); - tcg_gen_mul_tl(t2, t1, t2); - break; - case MXU_OPTN2_XW: /* XRB.L*XRC.H =3D=3D lop, XRB.H*XRC.L =3D=3D rop */ - tcg_gen_mul_tl(t3, t0, t3); - tcg_gen_mul_tl(t2, t1, t2); - break; - } - gen_load_mxu_gpr(t0, XRa); - gen_load_mxu_gpr(t1, XRd); - - switch (aptn2) { - case MXU_APTN2_AA: - tcg_gen_add_tl(t3, t0, t3); - tcg_gen_add_tl(t2, t1, t2); - break; - case MXU_APTN2_AS: - tcg_gen_add_tl(t3, t0, t3); - tcg_gen_sub_tl(t2, t1, t2); - break; - case MXU_APTN2_SA: - tcg_gen_sub_tl(t3, t0, t3); - tcg_gen_add_tl(t2, t1, t2); - break; - case MXU_APTN2_SS: - tcg_gen_sub_tl(t3, t0, t3); - tcg_gen_sub_tl(t2, t1, t2); - break; - } - gen_store_mxu_gpr(t3, XRa); - gen_store_mxu_gpr(t2, XRd); - - tcg_temp_free(t0); - tcg_temp_free(t1); - tcg_temp_free(t2); - tcg_temp_free(t3); -} - -/* - * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply - * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply - */ -static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx) -{ - TCGv t0, t1, t2, t3, t4, t5, t6, t7; - uint32_t XRa, XRb, XRc, XRd, sel; - - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - t2 =3D tcg_temp_new(); - t3 =3D tcg_temp_new(); - t4 =3D tcg_temp_new(); - t5 =3D tcg_temp_new(); - t6 =3D tcg_temp_new(); - t7 =3D tcg_temp_new(); - - XRa =3D extract32(ctx->opcode, 6, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRc =3D extract32(ctx->opcode, 14, 4); - XRd =3D extract32(ctx->opcode, 18, 4); - sel =3D extract32(ctx->opcode, 22, 2); - - gen_load_mxu_gpr(t3, XRb); - gen_load_mxu_gpr(t7, XRc); - - if (sel =3D=3D 0x2) { - /* Q8MULSU */ - tcg_gen_ext8s_tl(t0, t3); - tcg_gen_shri_tl(t3, t3, 8); - tcg_gen_ext8s_tl(t1, t3); - tcg_gen_shri_tl(t3, t3, 8); - tcg_gen_ext8s_tl(t2, t3); - tcg_gen_shri_tl(t3, t3, 8); - tcg_gen_ext8s_tl(t3, t3); - } else { - /* Q8MUL */ - tcg_gen_ext8u_tl(t0, t3); - tcg_gen_shri_tl(t3, t3, 8); - tcg_gen_ext8u_tl(t1, t3); - tcg_gen_shri_tl(t3, t3, 8); - tcg_gen_ext8u_tl(t2, t3); - tcg_gen_shri_tl(t3, t3, 8); - tcg_gen_ext8u_tl(t3, t3); - } - - tcg_gen_ext8u_tl(t4, t7); - tcg_gen_shri_tl(t7, t7, 8); - tcg_gen_ext8u_tl(t5, t7); - tcg_gen_shri_tl(t7, t7, 8); - tcg_gen_ext8u_tl(t6, t7); - tcg_gen_shri_tl(t7, t7, 8); - tcg_gen_ext8u_tl(t7, t7); - - tcg_gen_mul_tl(t0, t0, t4); - tcg_gen_mul_tl(t1, t1, t5); - tcg_gen_mul_tl(t2, t2, t6); - tcg_gen_mul_tl(t3, t3, t7); - - tcg_gen_andi_tl(t0, t0, 0xFFFF); - tcg_gen_andi_tl(t1, t1, 0xFFFF); - tcg_gen_andi_tl(t2, t2, 0xFFFF); - tcg_gen_andi_tl(t3, t3, 0xFFFF); - - tcg_gen_shli_tl(t1, t1, 16); - tcg_gen_shli_tl(t3, t3, 16); - - tcg_gen_or_tl(t0, t0, t1); - tcg_gen_or_tl(t1, t2, t3); - - gen_store_mxu_gpr(t0, XRd); - gen_store_mxu_gpr(t1, XRa); - - tcg_temp_free(t0); - tcg_temp_free(t1); - tcg_temp_free(t2); - tcg_temp_free(t3); - tcg_temp_free(t4); - tcg_temp_free(t5); - tcg_temp_free(t6); - tcg_temp_free(t7); -} - -/* - * S32LDD XRa, Rb, S12 - Load a word from memory to XRF - * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte se= q. - */ -static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx) -{ - TCGv t0, t1; - uint32_t XRa, Rb, s12, sel; - - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - - XRa =3D extract32(ctx->opcode, 6, 4); - s12 =3D extract32(ctx->opcode, 10, 10); - sel =3D extract32(ctx->opcode, 20, 1); - Rb =3D extract32(ctx->opcode, 21, 5); - - gen_load_gpr(t0, Rb); - - tcg_gen_movi_tl(t1, s12); - tcg_gen_shli_tl(t1, t1, 2); - if (s12 & 0x200) { - tcg_gen_ori_tl(t1, t1, 0xFFFFF000); - } - tcg_gen_add_tl(t1, t0, t1); - tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL); - - if (sel =3D=3D 1) { - /* S32LDDR */ - tcg_gen_bswap32_tl(t1, t1); - } - gen_store_mxu_gpr(t1, XRa); - - tcg_temp_free(t0); - tcg_temp_free(t1); -} - - -/* - * MXU instruction category: logic - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * S32NOR S32AND S32OR S32XOR - */ - -/* - * S32NOR XRa, XRb, XRc - * Update XRa with the result of logical bitwise 'nor' operation - * applied to the content of XRb and XRc. - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16| - * +-----------+---------+-----+-------+-------+-------+-----------+ - */ -static void gen_mxu_S32NOR(DisasContext *ctx) -{ - uint32_t pad, XRc, XRb, XRa; - - pad =3D extract32(ctx->opcode, 21, 5); - XRc =3D extract32(ctx->opcode, 14, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRa =3D extract32(ctx->opcode, 6, 4); - - if (unlikely(pad !=3D 0)) { - /* opcode padding incorrect -> do nothing */ - } else if (unlikely(XRa =3D=3D 0)) { - /* destination is zero register -> do nothing */ - } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { - /* both operands zero registers -> just set destination to all 1s = */ - tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF); - } else if (unlikely(XRb =3D=3D 0)) { - /* XRb zero register -> just set destination to the negation of XR= c */ - tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]); - } else if (unlikely(XRc =3D=3D 0)) { - /* XRa zero register -> just set destination to the negation of XR= b */ - tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - } else if (unlikely(XRb =3D=3D XRc)) { - /* both operands same -> just set destination to the negation of X= Rb */ - tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - } else { - /* the most general case */ - tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - = 1]); - } -} - -/* - * S32AND XRa, XRb, XRc - * Update XRa with the result of logical bitwise 'and' operation - * applied to the content of XRb and XRc. - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16| - * +-----------+---------+-----+-------+-------+-------+-----------+ - */ -static void gen_mxu_S32AND(DisasContext *ctx) -{ - uint32_t pad, XRc, XRb, XRa; - - pad =3D extract32(ctx->opcode, 21, 5); - XRc =3D extract32(ctx->opcode, 14, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRa =3D extract32(ctx->opcode, 6, 4); - - if (unlikely(pad !=3D 0)) { - /* opcode padding incorrect -> do nothing */ - } else if (unlikely(XRa =3D=3D 0)) { - /* destination is zero register -> do nothing */ - } else if (unlikely((XRb =3D=3D 0) || (XRc =3D=3D 0))) { - /* one of operands zero register -> just set destination to all 0s= */ - tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); - } else if (unlikely(XRb =3D=3D XRc)) { - /* both operands same -> just set destination to one of them */ - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - } else { - /* the most general case */ - tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - = 1]); - } -} - -/* - * S32OR XRa, XRb, XRc - * Update XRa with the result of logical bitwise 'or' operation - * applied to the content of XRb and XRc. - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16| - * +-----------+---------+-----+-------+-------+-------+-----------+ - */ -static void gen_mxu_S32OR(DisasContext *ctx) -{ - uint32_t pad, XRc, XRb, XRa; - - pad =3D extract32(ctx->opcode, 21, 5); - XRc =3D extract32(ctx->opcode, 14, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRa =3D extract32(ctx->opcode, 6, 4); - - if (unlikely(pad !=3D 0)) { - /* opcode padding incorrect -> do nothing */ - } else if (unlikely(XRa =3D=3D 0)) { - /* destination is zero register -> do nothing */ - } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { - /* both operands zero registers -> just set destination to all 0s = */ - tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); - } else if (unlikely(XRb =3D=3D 0)) { - /* XRb zero register -> just set destination to the content of XRc= */ - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]); - } else if (unlikely(XRc =3D=3D 0)) { - /* XRc zero register -> just set destination to the content of XRb= */ - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - } else if (unlikely(XRb =3D=3D XRc)) { - /* both operands same -> just set destination to one of them */ - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - } else { - /* the most general case */ - tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1= ]); - } -} - -/* - * S32XOR XRa, XRb, XRc - * Update XRa with the result of logical bitwise 'xor' operation - * applied to the content of XRb and XRc. - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16| - * +-----------+---------+-----+-------+-------+-------+-----------+ - */ -static void gen_mxu_S32XOR(DisasContext *ctx) -{ - uint32_t pad, XRc, XRb, XRa; - - pad =3D extract32(ctx->opcode, 21, 5); - XRc =3D extract32(ctx->opcode, 14, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRa =3D extract32(ctx->opcode, 6, 4); - - if (unlikely(pad !=3D 0)) { - /* opcode padding incorrect -> do nothing */ - } else if (unlikely(XRa =3D=3D 0)) { - /* destination is zero register -> do nothing */ - } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { - /* both operands zero registers -> just set destination to all 0s = */ - tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); - } else if (unlikely(XRb =3D=3D 0)) { - /* XRb zero register -> just set destination to the content of XRc= */ - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]); - } else if (unlikely(XRc =3D=3D 0)) { - /* XRc zero register -> just set destination to the content of XRb= */ - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - } else if (unlikely(XRb =3D=3D XRc)) { - /* both operands same -> just set destination to all 0s */ - tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); - } else { - /* the most general case */ - tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - = 1]); - } -} - - -/* - * MXU instruction category max/min - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * S32MAX D16MAX Q8MAX - * S32MIN D16MIN Q8MIN - */ - -/* - * S32MAX XRa, XRb, XRc - * Update XRa with the maximum of signed 32-bit integers contained - * in XRb and XRc. - * - * S32MIN XRa, XRb, XRc - * Update XRa with the minimum of signed 32-bit integers contained - * in XRb and XRc. - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00| - * +-----------+---------+-----+-------+-------+-------+-----------+ - */ -static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx) -{ - uint32_t pad, opc, XRc, XRb, XRa; - - pad =3D extract32(ctx->opcode, 21, 5); - opc =3D extract32(ctx->opcode, 18, 3); - XRc =3D extract32(ctx->opcode, 14, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRa =3D extract32(ctx->opcode, 6, 4); - - if (unlikely(pad !=3D 0)) { - /* opcode padding incorrect -> do nothing */ - } else if (unlikely(XRa =3D=3D 0)) { - /* destination is zero register -> do nothing */ - } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { - /* both operands zero registers -> just set destination to zero */ - tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); - } else if (unlikely((XRb =3D=3D 0) || (XRc =3D=3D 0))) { - /* exactly one operand is zero register - find which one is not...= */ - uint32_t XRx =3D XRb ? XRb : XRc; - /* ...and do max/min operation with one operand 0 */ - if (opc =3D=3D OPC_MXU_S32MAX) { - tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0); - } else { - tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0); - } - } else if (unlikely(XRb =3D=3D XRc)) { - /* both operands same -> just set destination to one of them */ - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - } else { - /* the most general case */ - if (opc =3D=3D OPC_MXU_S32MAX) { - tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], - mxu_gpr[XRc - 1]); - } else { - tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], - mxu_gpr[XRc - 1]); - } - } -} - -/* - * D16MAX - * Update XRa with the 16-bit-wise maximums of signed integers - * contained in XRb and XRc. - * - * D16MIN - * Update XRa with the 16-bit-wise minimums of signed integers - * contained in XRb and XRc. - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00| - * +-----------+---------+-----+-------+-------+-------+-----------+ - */ -static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx) -{ - uint32_t pad, opc, XRc, XRb, XRa; - - pad =3D extract32(ctx->opcode, 21, 5); - opc =3D extract32(ctx->opcode, 18, 3); - XRc =3D extract32(ctx->opcode, 14, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRa =3D extract32(ctx->opcode, 6, 4); - - if (unlikely(pad !=3D 0)) { - /* opcode padding incorrect -> do nothing */ - } else if (unlikely(XRc =3D=3D 0)) { - /* destination is zero register -> do nothing */ - } else if (unlikely((XRb =3D=3D 0) && (XRa =3D=3D 0))) { - /* both operands zero registers -> just set destination to zero */ - tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0); - } else if (unlikely((XRb =3D=3D 0) || (XRa =3D=3D 0))) { - /* exactly one operand is zero register - find which one is not...= */ - uint32_t XRx =3D XRb ? XRb : XRc; - /* ...and do half-word-wise max/min with one operand 0 */ - TCGv_i32 t0 =3D tcg_temp_new(); - TCGv_i32 t1 =3D tcg_const_i32(0); - - /* the left half-word first */ - tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000); - if (opc =3D=3D OPC_MXU_D16MAX) { - tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1); - } else { - tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1); - } - - /* the right half-word */ - tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF); - /* move half-words to the leftmost position */ - tcg_gen_shli_i32(t0, t0, 16); - /* t0 will be max/min of t0 and t1 */ - if (opc =3D=3D OPC_MXU_D16MAX) { - tcg_gen_smax_i32(t0, t0, t1); - } else { - tcg_gen_smin_i32(t0, t0, t1); - } - /* return resulting half-words to its original position */ - tcg_gen_shri_i32(t0, t0, 16); - /* finally update the destination */ - tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0); - - tcg_temp_free(t1); - tcg_temp_free(t0); - } else if (unlikely(XRb =3D=3D XRc)) { - /* both operands same -> just set destination to one of them */ - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - } else { - /* the most general case */ - TCGv_i32 t0 =3D tcg_temp_new(); - TCGv_i32 t1 =3D tcg_temp_new(); - - /* the left half-word first */ - tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000); - tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000); - if (opc =3D=3D OPC_MXU_D16MAX) { - tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1); - } else { - tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1); - } - - /* the right half-word */ - tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF); - tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF); - /* move half-words to the leftmost position */ - tcg_gen_shli_i32(t0, t0, 16); - tcg_gen_shli_i32(t1, t1, 16); - /* t0 will be max/min of t0 and t1 */ - if (opc =3D=3D OPC_MXU_D16MAX) { - tcg_gen_smax_i32(t0, t0, t1); - } else { - tcg_gen_smin_i32(t0, t0, t1); - } - /* return resulting half-words to its original position */ - tcg_gen_shri_i32(t0, t0, 16); - /* finally update the destination */ - tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0); - - tcg_temp_free(t1); - tcg_temp_free(t0); - } -} - -/* - * Q8MAX - * Update XRa with the 8-bit-wise maximums of signed integers - * contained in XRb and XRc. - * - * Q8MIN - * Update XRa with the 8-bit-wise minimums of signed integers - * contained in XRb and XRc. - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00| - * +-----------+---------+-----+-------+-------+-------+-----------+ - */ -static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx) -{ - uint32_t pad, opc, XRc, XRb, XRa; - - pad =3D extract32(ctx->opcode, 21, 5); - opc =3D extract32(ctx->opcode, 18, 3); - XRc =3D extract32(ctx->opcode, 14, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRa =3D extract32(ctx->opcode, 6, 4); - - if (unlikely(pad !=3D 0)) { - /* opcode padding incorrect -> do nothing */ - } else if (unlikely(XRa =3D=3D 0)) { - /* destination is zero register -> do nothing */ - } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { - /* both operands zero registers -> just set destination to zero */ - tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); - } else if (unlikely((XRb =3D=3D 0) || (XRc =3D=3D 0))) { - /* exactly one operand is zero register - make it be the first...*/ - uint32_t XRx =3D XRb ? XRb : XRc; - /* ...and do byte-wise max/min with one operand 0 */ - TCGv_i32 t0 =3D tcg_temp_new(); - TCGv_i32 t1 =3D tcg_const_i32(0); - int32_t i; - - /* the leftmost byte (byte 3) first */ - tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000); - if (opc =3D=3D OPC_MXU_Q8MAX) { - tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1); - } else { - tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1); - } - - /* bytes 2, 1, 0 */ - for (i =3D 2; i >=3D 0; i--) { - /* extract the byte */ - tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i)); - /* move the byte to the leftmost position */ - tcg_gen_shli_i32(t0, t0, 8 * (3 - i)); - /* t0 will be max/min of t0 and t1 */ - if (opc =3D=3D OPC_MXU_Q8MAX) { - tcg_gen_smax_i32(t0, t0, t1); - } else { - tcg_gen_smin_i32(t0, t0, t1); - } - /* return resulting byte to its original position */ - tcg_gen_shri_i32(t0, t0, 8 * (3 - i)); - /* finally update the destination */ - tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0); - } - - tcg_temp_free(t1); - tcg_temp_free(t0); - } else if (unlikely(XRb =3D=3D XRc)) { - /* both operands same -> just set destination to one of them */ - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - } else { - /* the most general case */ - TCGv_i32 t0 =3D tcg_temp_new(); - TCGv_i32 t1 =3D tcg_temp_new(); - int32_t i; - - /* the leftmost bytes (bytes 3) first */ - tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000); - tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000); - if (opc =3D=3D OPC_MXU_Q8MAX) { - tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1); - } else { - tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1); - } - - /* bytes 2, 1, 0 */ - for (i =3D 2; i >=3D 0; i--) { - /* extract corresponding bytes */ - tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i)); - tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i)); - /* move the bytes to the leftmost position */ - tcg_gen_shli_i32(t0, t0, 8 * (3 - i)); - tcg_gen_shli_i32(t1, t1, 8 * (3 - i)); - /* t0 will be max/min of t0 and t1 */ - if (opc =3D=3D OPC_MXU_Q8MAX) { - tcg_gen_smax_i32(t0, t0, t1); - } else { - tcg_gen_smin_i32(t0, t0, t1); - } - /* return resulting byte to its original position */ - tcg_gen_shri_i32(t0, t0, 8 * (3 - i)); - /* finally update the destination */ - tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0); - } - - tcg_temp_free(t1); - tcg_temp_free(t0); - } -} - - -/* - * MXU instruction category: align - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * S32ALN S32ALNI - */ - -/* - * S32ALNI XRc, XRb, XRa, optn3 - * Arrange bytes from XRb and XRc according to one of five sets of - * rules determined by optn3, and place the result in XRa. - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+-----+---+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16| - * +-----------+-----+---+-----+-------+-------+-------+-----------+ - * - */ -static void gen_mxu_S32ALNI(DisasContext *ctx) -{ - uint32_t optn3, pad, XRc, XRb, XRa; - - optn3 =3D extract32(ctx->opcode, 23, 3); - pad =3D extract32(ctx->opcode, 21, 2); - XRc =3D extract32(ctx->opcode, 14, 4); - XRb =3D extract32(ctx->opcode, 10, 4); - XRa =3D extract32(ctx->opcode, 6, 4); - - if (unlikely(pad !=3D 0)) { - /* opcode padding incorrect -> do nothing */ - } else if (unlikely(XRa =3D=3D 0)) { - /* destination is zero register -> do nothing */ - } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { - /* both operands zero registers -> just set destination to all 0s = */ - tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); - } else if (unlikely(XRb =3D=3D 0)) { - /* XRb zero register -> just appropriatelly shift XRc into XRa */ - switch (optn3) { - case MXU_OPTN3_PTN0: - tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); - break; - case MXU_OPTN3_PTN1: - case MXU_OPTN3_PTN2: - case MXU_OPTN3_PTN3: - tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1], - 8 * (4 - optn3)); - break; - case MXU_OPTN3_PTN4: - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]); - break; - } - } else if (unlikely(XRc =3D=3D 0)) { - /* XRc zero register -> just appropriatelly shift XRb into XRa */ - switch (optn3) { - case MXU_OPTN3_PTN0: - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - break; - case MXU_OPTN3_PTN1: - case MXU_OPTN3_PTN2: - case MXU_OPTN3_PTN3: - tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3= ); - break; - case MXU_OPTN3_PTN4: - tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); - break; - } - } else if (unlikely(XRb =3D=3D XRc)) { - /* both operands same -> just rotation or moving from any of them = */ - switch (optn3) { - case MXU_OPTN3_PTN0: - case MXU_OPTN3_PTN4: - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - break; - case MXU_OPTN3_PTN1: - case MXU_OPTN3_PTN2: - case MXU_OPTN3_PTN3: - tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn= 3); - break; - } - } else { - /* the most general case */ - switch (optn3) { - case MXU_OPTN3_PTN0: - { - /* */ - /* XRb XRc */ - /* +---------------+ */ - /* | A B C D | E F G H */ - /* +-------+-------+ */ - /* | */ - /* XRa */ - /* */ - - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); - } - break; - case MXU_OPTN3_PTN1: - { - /* */ - /* XRb XRc */ - /* +-------------------+ */ - /* A | B C D E | F G H */ - /* +---------+---------+ */ - /* | */ - /* XRa */ - /* */ - - TCGv_i32 t0 =3D tcg_temp_new(); - TCGv_i32 t1 =3D tcg_temp_new(); - - tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF); - tcg_gen_shli_i32(t0, t0, 8); - - tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000); - tcg_gen_shri_i32(t1, t1, 24); - - tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1); - - tcg_temp_free(t1); - tcg_temp_free(t0); - } - break; - case MXU_OPTN3_PTN2: - { - /* */ - /* XRb XRc */ - /* +-------------------+ */ - /* A B | C D E F | G H */ - /* +---------+---------+ */ - /* | */ - /* XRa */ - /* */ - - TCGv_i32 t0 =3D tcg_temp_new(); - TCGv_i32 t1 =3D tcg_temp_new(); - - tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF); - tcg_gen_shli_i32(t0, t0, 16); - - tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000); - tcg_gen_shri_i32(t1, t1, 16); - - tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1); - - tcg_temp_free(t1); - tcg_temp_free(t0); - } - break; - case MXU_OPTN3_PTN3: - { - /* */ - /* XRb XRc */ - /* +-------------------+ */ - /* A B C | D E F G | H */ - /* +---------+---------+ */ - /* | */ - /* XRa */ - /* */ - - TCGv_i32 t0 =3D tcg_temp_new(); - TCGv_i32 t1 =3D tcg_temp_new(); - - tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF); - tcg_gen_shli_i32(t0, t0, 24); - - tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00); - tcg_gen_shri_i32(t1, t1, 8); - - tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1); - - tcg_temp_free(t1); - tcg_temp_free(t0); - } - break; - case MXU_OPTN3_PTN4: - { - /* */ - /* XRb XRc */ - /* +---------------+ */ - /* A B C D | E F G H | */ - /* +-------+-------+ */ - /* | */ - /* XRa */ - /* */ - - tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]); - } - break; - } - } -} - - -/* - * Decoding engine for MXU - * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - */ - -/* - * - * Decode MXU pool00 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00| - * +-----------+---------+-----+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 18, 3); - - switch (opcode) { - case OPC_MXU_S32MAX: - case OPC_MXU_S32MIN: - gen_mxu_S32MAX_S32MIN(ctx); - break; - case OPC_MXU_D16MAX: - case OPC_MXU_D16MIN: - gen_mxu_D16MAX_D16MIN(ctx); - break; - case OPC_MXU_Q8MAX: - case OPC_MXU_Q8MIN: - gen_mxu_Q8MAX_Q8MIN(ctx); - break; - case OPC_MXU_Q8SLT: - /* TODO: Implement emulation of Q8SLT instruction. */ - MIPS_INVAL("OPC_MXU_Q8SLT"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q8SLTU: - /* TODO: Implement emulation of Q8SLTU instruction. */ - MIPS_INVAL("OPC_MXU_Q8SLTU"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool01 - * - * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01| - * +-----------+---------+-----+-------+-------+-------+-----------+ - * - * Q8ADD: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---+-----+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01| - * +-----------+---+-----+-----+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 18, 3); - - switch (opcode) { - case OPC_MXU_S32SLT: - /* TODO: Implement emulation of S32SLT instruction. */ - MIPS_INVAL("OPC_MXU_S32SLT"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D16SLT: - /* TODO: Implement emulation of D16SLT instruction. */ - MIPS_INVAL("OPC_MXU_D16SLT"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D16AVG: - /* TODO: Implement emulation of D16AVG instruction. */ - MIPS_INVAL("OPC_MXU_D16AVG"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D16AVGR: - /* TODO: Implement emulation of D16AVGR instruction. */ - MIPS_INVAL("OPC_MXU_D16AVGR"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q8AVG: - /* TODO: Implement emulation of Q8AVG instruction. */ - MIPS_INVAL("OPC_MXU_Q8AVG"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q8AVGR: - /* TODO: Implement emulation of Q8AVGR instruction. */ - MIPS_INVAL("OPC_MXU_Q8AVGR"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q8ADD: - /* TODO: Implement emulation of Q8ADD instruction. */ - MIPS_INVAL("OPC_MXU_Q8ADD"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool02 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02| - * +-----------+---------+-----+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 18, 3); - - switch (opcode) { - case OPC_MXU_S32CPS: - /* TODO: Implement emulation of S32CPS instruction. */ - MIPS_INVAL("OPC_MXU_S32CPS"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D16CPS: - /* TODO: Implement emulation of D16CPS instruction. */ - MIPS_INVAL("OPC_MXU_D16CPS"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q8ABD: - /* TODO: Implement emulation of Q8ABD instruction. */ - MIPS_INVAL("OPC_MXU_Q8ABD"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q16SAT: - /* TODO: Implement emulation of Q16SAT instruction. */ - MIPS_INVAL("OPC_MXU_Q16SAT"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool03 - * - * D16MULF: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03| - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * - * D16MULE: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03| - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 24, 2); - - switch (opcode) { - case OPC_MXU_D16MULF: - /* TODO: Implement emulation of D16MULF instruction. */ - MIPS_INVAL("OPC_MXU_D16MULF"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D16MULE: - /* TODO: Implement emulation of D16MULE instruction. */ - MIPS_INVAL("OPC_MXU_D16MULE"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool04 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-+-------------------+-------+-----------+ - * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04| - * +-----------+---------+-+-------------------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 20, 1); - - switch (opcode) { - case OPC_MXU_S32LDD: - case OPC_MXU_S32LDDR: - gen_mxu_s32ldd_s32lddr(ctx); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool05 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-+-------------------+-------+-----------+ - * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05| - * +-----------+---------+-+-------------------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 20, 1); - - switch (opcode) { - case OPC_MXU_S32STD: - /* TODO: Implement emulation of S32STD instruction. */ - MIPS_INVAL("OPC_MXU_S32STD"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32STDR: - /* TODO: Implement emulation of S32STDR instruction. */ - MIPS_INVAL("OPC_MXU_S32STDR"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool06 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+---------+---+-------+-------+-----------+ - * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06| - * +-----------+---------+---------+---+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 10, 4); - - switch (opcode) { - case OPC_MXU_S32LDDV: - /* TODO: Implement emulation of S32LDDV instruction. */ - MIPS_INVAL("OPC_MXU_S32LDDV"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32LDDVR: - /* TODO: Implement emulation of S32LDDVR instruction. */ - MIPS_INVAL("OPC_MXU_S32LDDVR"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool07 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+---------+---+-------+-------+-----------+ - * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07| - * +-----------+---------+---------+---+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 10, 4); - - switch (opcode) { - case OPC_MXU_S32STDV: - /* TODO: Implement emulation of S32TDV instruction. */ - MIPS_INVAL("OPC_MXU_S32TDV"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32STDVR: - /* TODO: Implement emulation of S32TDVR instruction. */ - MIPS_INVAL("OPC_MXU_S32TDVR"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool08 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-+-------------------+-------+-----------+ - * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08| - * +-----------+---------+-+-------------------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 20, 1); - - switch (opcode) { - case OPC_MXU_S32LDI: - /* TODO: Implement emulation of S32LDI instruction. */ - MIPS_INVAL("OPC_MXU_S32LDI"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32LDIR: - /* TODO: Implement emulation of S32LDIR instruction. */ - MIPS_INVAL("OPC_MXU_S32LDIR"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool09 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-+-------------------+-------+-----------+ - * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09| - * +-----------+---------+-+-------------------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 5, 0); - - switch (opcode) { - case OPC_MXU_S32SDI: - /* TODO: Implement emulation of S32SDI instruction. */ - MIPS_INVAL("OPC_MXU_S32SDI"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32SDIR: - /* TODO: Implement emulation of S32SDIR instruction. */ - MIPS_INVAL("OPC_MXU_S32SDIR"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool10 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+---------+---+-------+-------+-----------+ - * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10| - * +-----------+---------+---------+---+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 5, 0); - - switch (opcode) { - case OPC_MXU_S32LDIV: - /* TODO: Implement emulation of S32LDIV instruction. */ - MIPS_INVAL("OPC_MXU_S32LDIV"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32LDIVR: - /* TODO: Implement emulation of S32LDIVR instruction. */ - MIPS_INVAL("OPC_MXU_S32LDIVR"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool11 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+---------+---+-------+-------+-----------+ - * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11| - * +-----------+---------+---------+---+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 10, 4); - - switch (opcode) { - case OPC_MXU_S32SDIV: - /* TODO: Implement emulation of S32SDIV instruction. */ - MIPS_INVAL("OPC_MXU_S32SDIV"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32SDIVR: - /* TODO: Implement emulation of S32SDIVR instruction. */ - MIPS_INVAL("OPC_MXU_S32SDIVR"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool12 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12| - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 22, 2); - - switch (opcode) { - case OPC_MXU_D32ACC: - /* TODO: Implement emulation of D32ACC instruction. */ - MIPS_INVAL("OPC_MXU_D32ACC"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D32ACCM: - /* TODO: Implement emulation of D32ACCM instruction. */ - MIPS_INVAL("OPC_MXU_D32ACCM"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D32ASUM: - /* TODO: Implement emulation of D32ASUM instruction. */ - MIPS_INVAL("OPC_MXU_D32ASUM"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool13 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13| - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 22, 2); - - switch (opcode) { - case OPC_MXU_Q16ACC: - /* TODO: Implement emulation of Q16ACC instruction. */ - MIPS_INVAL("OPC_MXU_Q16ACC"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q16ACCM: - /* TODO: Implement emulation of Q16ACCM instruction. */ - MIPS_INVAL("OPC_MXU_Q16ACCM"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q16ASUM: - /* TODO: Implement emulation of Q16ASUM instruction. */ - MIPS_INVAL("OPC_MXU_Q16ASUM"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool14 - * - * Q8ADDE, Q8ACCE: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14| - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * - * D8SUM, D8SUMC: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14| - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 22, 2); - - switch (opcode) { - case OPC_MXU_Q8ADDE: - /* TODO: Implement emulation of Q8ADDE instruction. */ - MIPS_INVAL("OPC_MXU_Q8ADDE"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D8SUM: - /* TODO: Implement emulation of D8SUM instruction. */ - MIPS_INVAL("OPC_MXU_D8SUM"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D8SUMC: - /* TODO: Implement emulation of D8SUMC instruction. */ - MIPS_INVAL("OPC_MXU_D8SUMC"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool15 - * - * S32MUL, S32MULU, S32EXTRV: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+---------+---+-------+-------+-----------+ - * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15| - * +-----------+---------+---------+---+-------+-------+-----------+ - * - * S32EXTR: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+---------+---+-------+-------+-----------+ - * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15| - * +-----------+---------+---------+---+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 14, 2); - - switch (opcode) { - case OPC_MXU_S32MUL: - /* TODO: Implement emulation of S32MUL instruction. */ - MIPS_INVAL("OPC_MXU_S32MUL"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32MULU: - /* TODO: Implement emulation of S32MULU instruction. */ - MIPS_INVAL("OPC_MXU_S32MULU"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32EXTR: - /* TODO: Implement emulation of S32EXTR instruction. */ - MIPS_INVAL("OPC_MXU_S32EXTR"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32EXTRV: - /* TODO: Implement emulation of S32EXTRV instruction. */ - MIPS_INVAL("OPC_MXU_S32EXTRV"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool16 - * - * D32SARW: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16| - * +-----------+---------+-----+-------+-------+-------+-----------+ - * - * S32ALN: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16| - * +-----------+---------+-----+-------+-------+-------+-----------+ - * - * S32ALNI: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+-----+---+-----+-------+-------+-------+-----------+ - * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16| - * +-----------+-----+---+-----+-------+-------+-------+-----------+ - * - * S32LUI: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+-----+---+-----+-------+---------------+-----------+ - * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16| - * +-----------+-----+---+-----+-------+---------------+-----------+ - * - * S32NOR, S32AND, S32OR, S32XOR: - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16| - * +-----------+---------+-----+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 18, 3); - - switch (opcode) { - case OPC_MXU_D32SARW: - /* TODO: Implement emulation of D32SARW instruction. */ - MIPS_INVAL("OPC_MXU_D32SARW"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32ALN: - /* TODO: Implement emulation of S32ALN instruction. */ - MIPS_INVAL("OPC_MXU_S32ALN"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32ALNI: - gen_mxu_S32ALNI(ctx); - break; - case OPC_MXU_S32LUI: - /* TODO: Implement emulation of S32LUI instruction. */ - MIPS_INVAL("OPC_MXU_S32LUI"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32NOR: - gen_mxu_S32NOR(ctx); - break; - case OPC_MXU_S32AND: - gen_mxu_S32AND(ctx); - break; - case OPC_MXU_S32OR: - gen_mxu_S32OR(ctx); - break; - case OPC_MXU_S32XOR: - gen_mxu_S32XOR(ctx); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool17 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+---------+---+---------+-----+-----------+ - * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15| - * +-----------+---------+---------+---+---------+-----+-----------+ - * - */ -static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 6, 2); - - switch (opcode) { - case OPC_MXU_LXW: - /* TODO: Implement emulation of LXW instruction. */ - MIPS_INVAL("OPC_MXU_LXW"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_LXH: - /* TODO: Implement emulation of LXH instruction. */ - MIPS_INVAL("OPC_MXU_LXH"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_LXHU: - /* TODO: Implement emulation of LXHU instruction. */ - MIPS_INVAL("OPC_MXU_LXHU"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_LXB: - /* TODO: Implement emulation of LXB instruction. */ - MIPS_INVAL("OPC_MXU_LXB"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_LXBU: - /* TODO: Implement emulation of LXBU instruction. */ - MIPS_INVAL("OPC_MXU_LXBU"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} -/* - * - * Decode MXU pool18 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18| - * +-----------+---------+-----+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 18, 3); - - switch (opcode) { - case OPC_MXU_D32SLLV: - /* TODO: Implement emulation of D32SLLV instruction. */ - MIPS_INVAL("OPC_MXU_D32SLLV"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D32SLRV: - /* TODO: Implement emulation of D32SLRV instruction. */ - MIPS_INVAL("OPC_MXU_D32SLRV"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D32SARV: - /* TODO: Implement emulation of D32SARV instruction. */ - MIPS_INVAL("OPC_MXU_D32SARV"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q16SLLV: - /* TODO: Implement emulation of Q16SLLV instruction. */ - MIPS_INVAL("OPC_MXU_Q16SLLV"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q16SLRV: - /* TODO: Implement emulation of Q16SLRV instruction. */ - MIPS_INVAL("OPC_MXU_Q16SLRV"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q16SARV: - /* TODO: Implement emulation of Q16SARV instruction. */ - MIPS_INVAL("OPC_MXU_Q16SARV"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool19 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19| - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 22, 2); - - switch (opcode) { - case OPC_MXU_Q8MUL: - case OPC_MXU_Q8MULSU: - gen_mxu_q8mul_q8mulsu(ctx); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool20 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+-----+-------+-------+-------+-----------+ - * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20| - * +-----------+---------+-----+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 18, 3); - - switch (opcode) { - case OPC_MXU_Q8MOVZ: - /* TODO: Implement emulation of Q8MOVZ instruction. */ - MIPS_INVAL("OPC_MXU_Q8MOVZ"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q8MOVN: - /* TODO: Implement emulation of Q8MOVN instruction. */ - MIPS_INVAL("OPC_MXU_Q8MOVN"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D16MOVZ: - /* TODO: Implement emulation of D16MOVZ instruction. */ - MIPS_INVAL("OPC_MXU_D16MOVZ"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D16MOVN: - /* TODO: Implement emulation of D16MOVN instruction. */ - MIPS_INVAL("OPC_MXU_D16MOVN"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32MOVZ: - /* TODO: Implement emulation of S32MOVZ instruction. */ - MIPS_INVAL("OPC_MXU_S32MOVZ"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32MOVN: - /* TODO: Implement emulation of S32MOVN instruction. */ - MIPS_INVAL("OPC_MXU_S32MOVN"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - -/* - * - * Decode MXU pool21 - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21| - * +-----------+---+---+-------+-------+-------+-------+-----------+ - * - */ -static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx) -{ - uint32_t opcode =3D extract32(ctx->opcode, 22, 2); - - switch (opcode) { - case OPC_MXU_Q8MAC: - /* TODO: Implement emulation of Q8MAC instruction. */ - MIPS_INVAL("OPC_MXU_Q8MAC"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q8MACSU: - /* TODO: Implement emulation of Q8MACSU instruction. */ - MIPS_INVAL("OPC_MXU_Q8MACSU"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - - -/* - * Main MXU decoding function - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------------------------------------+-----------+ - * | SPECIAL2 | |x x x x x x| - * +-----------+---------------------------------------+-----------+ - * - */ -static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) -{ - /* - * TODO: Investigate necessity of including handling of - * CLZ, CLO, SDBB in this function, as they belong to - * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs. - */ - uint32_t opcode =3D extract32(ctx->opcode, 0, 6); - - if (opcode =3D=3D OPC__MXU_MUL) { - uint32_t rs, rt, rd, op1; - - rs =3D extract32(ctx->opcode, 21, 5); - rt =3D extract32(ctx->opcode, 16, 5); - rd =3D extract32(ctx->opcode, 11, 5); - op1 =3D MASK_SPECIAL2(ctx->opcode); - - gen_arith(ctx, op1, rd, rs, rt); - - return; - } - - if (opcode =3D=3D OPC_MXU_S32M2I) { - gen_mxu_s32m2i(ctx); - return; - } - - if (opcode =3D=3D OPC_MXU_S32I2M) { - gen_mxu_s32i2m(ctx); - return; - } - - { - TCGv t_mxu_cr =3D tcg_temp_new(); - TCGLabel *l_exit =3D gen_new_label(); - - gen_load_mxu_cr(t_mxu_cr); - tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN); - tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit); - - switch (opcode) { - case OPC_MXU_S32MADD: - /* TODO: Implement emulation of S32MADD instruction. */ - MIPS_INVAL("OPC_MXU_S32MADD"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32MADDU: - /* TODO: Implement emulation of S32MADDU instruction. */ - MIPS_INVAL("OPC_MXU_S32MADDU"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU__POOL00: - decode_opc_mxu__pool00(env, ctx); - break; - case OPC_MXU_S32MSUB: - /* TODO: Implement emulation of S32MSUB instruction. */ - MIPS_INVAL("OPC_MXU_S32MSUB"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32MSUBU: - /* TODO: Implement emulation of S32MSUBU instruction. */ - MIPS_INVAL("OPC_MXU_S32MSUBU"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU__POOL01: - decode_opc_mxu__pool01(env, ctx); - break; - case OPC_MXU__POOL02: - decode_opc_mxu__pool02(env, ctx); - break; - case OPC_MXU_D16MUL: - gen_mxu_d16mul(ctx); - break; - case OPC_MXU__POOL03: - decode_opc_mxu__pool03(env, ctx); - break; - case OPC_MXU_D16MAC: - gen_mxu_d16mac(ctx); - break; - case OPC_MXU_D16MACF: - /* TODO: Implement emulation of D16MACF instruction. */ - MIPS_INVAL("OPC_MXU_D16MACF"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D16MADL: - /* TODO: Implement emulation of D16MADL instruction. */ - MIPS_INVAL("OPC_MXU_D16MADL"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S16MAD: - /* TODO: Implement emulation of S16MAD instruction. */ - MIPS_INVAL("OPC_MXU_S16MAD"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q16ADD: - /* TODO: Implement emulation of Q16ADD instruction. */ - MIPS_INVAL("OPC_MXU_Q16ADD"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D16MACE: - /* TODO: Implement emulation of D16MACE instruction. */ - MIPS_INVAL("OPC_MXU_D16MACE"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU__POOL04: - decode_opc_mxu__pool04(env, ctx); - break; - case OPC_MXU__POOL05: - decode_opc_mxu__pool05(env, ctx); - break; - case OPC_MXU__POOL06: - decode_opc_mxu__pool06(env, ctx); - break; - case OPC_MXU__POOL07: - decode_opc_mxu__pool07(env, ctx); - break; - case OPC_MXU__POOL08: - decode_opc_mxu__pool08(env, ctx); - break; - case OPC_MXU__POOL09: - decode_opc_mxu__pool09(env, ctx); - break; - case OPC_MXU__POOL10: - decode_opc_mxu__pool10(env, ctx); - break; - case OPC_MXU__POOL11: - decode_opc_mxu__pool11(env, ctx); - break; - case OPC_MXU_D32ADD: - /* TODO: Implement emulation of D32ADD instruction. */ - MIPS_INVAL("OPC_MXU_D32ADD"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU__POOL12: - decode_opc_mxu__pool12(env, ctx); - break; - case OPC_MXU__POOL13: - decode_opc_mxu__pool13(env, ctx); - break; - case OPC_MXU__POOL14: - decode_opc_mxu__pool14(env, ctx); - break; - case OPC_MXU_Q8ACCE: - /* TODO: Implement emulation of Q8ACCE instruction. */ - MIPS_INVAL("OPC_MXU_Q8ACCE"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S8LDD: - gen_mxu_s8ldd(ctx); - break; - case OPC_MXU_S8STD: - /* TODO: Implement emulation of S8STD instruction. */ - MIPS_INVAL("OPC_MXU_S8STD"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S8LDI: - /* TODO: Implement emulation of S8LDI instruction. */ - MIPS_INVAL("OPC_MXU_S8LDI"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S8SDI: - /* TODO: Implement emulation of S8SDI instruction. */ - MIPS_INVAL("OPC_MXU_S8SDI"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU__POOL15: - decode_opc_mxu__pool15(env, ctx); - break; - case OPC_MXU__POOL16: - decode_opc_mxu__pool16(env, ctx); - break; - case OPC_MXU__POOL17: - decode_opc_mxu__pool17(env, ctx); - break; - case OPC_MXU_S16LDD: - /* TODO: Implement emulation of S16LDD instruction. */ - MIPS_INVAL("OPC_MXU_S16LDD"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S16STD: - /* TODO: Implement emulation of S16STD instruction. */ - MIPS_INVAL("OPC_MXU_S16STD"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S16LDI: - /* TODO: Implement emulation of S16LDI instruction. */ - MIPS_INVAL("OPC_MXU_S16LDI"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S16SDI: - /* TODO: Implement emulation of S16SDI instruction. */ - MIPS_INVAL("OPC_MXU_S16SDI"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D32SLL: - /* TODO: Implement emulation of D32SLL instruction. */ - MIPS_INVAL("OPC_MXU_D32SLL"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D32SLR: - /* TODO: Implement emulation of D32SLR instruction. */ - MIPS_INVAL("OPC_MXU_D32SLR"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D32SARL: - /* TODO: Implement emulation of D32SARL instruction. */ - MIPS_INVAL("OPC_MXU_D32SARL"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_D32SAR: - /* TODO: Implement emulation of D32SAR instruction. */ - MIPS_INVAL("OPC_MXU_D32SAR"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q16SLL: - /* TODO: Implement emulation of Q16SLL instruction. */ - MIPS_INVAL("OPC_MXU_Q16SLL"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q16SLR: - /* TODO: Implement emulation of Q16SLR instruction. */ - MIPS_INVAL("OPC_MXU_Q16SLR"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU__POOL18: - decode_opc_mxu__pool18(env, ctx); - break; - case OPC_MXU_Q16SAR: - /* TODO: Implement emulation of Q16SAR instruction. */ - MIPS_INVAL("OPC_MXU_Q16SAR"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU__POOL19: - decode_opc_mxu__pool19(env, ctx); - break; - case OPC_MXU__POOL20: - decode_opc_mxu__pool20(env, ctx); - break; - case OPC_MXU__POOL21: - decode_opc_mxu__pool21(env, ctx); - break; - case OPC_MXU_Q16SCOP: - /* TODO: Implement emulation of Q16SCOP instruction. */ - MIPS_INVAL("OPC_MXU_Q16SCOP"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q8MADL: - /* TODO: Implement emulation of Q8MADL instruction. */ - MIPS_INVAL("OPC_MXU_Q8MADL"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_S32SFL: - /* TODO: Implement emulation of S32SFL instruction. */ - MIPS_INVAL("OPC_MXU_S32SFL"); - generate_exception_end(ctx, EXCP_RI); - break; - case OPC_MXU_Q8SAD: - /* TODO: Implement emulation of Q8SAD instruction. */ - MIPS_INVAL("OPC_MXU_Q8SAD"); - generate_exception_end(ctx, EXCP_RI); - break; - default: - MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); - } - - gen_set_label(l_exit); - tcg_temp_free(t_mxu_cr); - } -} - -#endif /* !defined(TARGET_MIPS64) */ - - static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ct= x) { int rs, rt, rd; diff --git a/target/mips/vendor-xburst_translate.c.inc b/target/mips/vendor= -xburst_translate.c.inc new file mode 100644 index 00000000000..ce9c63aa8f5 --- /dev/null +++ b/target/mips/vendor-xburst_translate.c.inc @@ -0,0 +1,2893 @@ +/* + * Ingenic Xburst XBurst Media eXtension Unit translation routines. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * + * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + * + * + * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MI= PS32 + * instructions set. It is designed to fit the needs of signal, graphical = and + * video processing applications. MXU instruction set is used in Xburst fa= mily + * of microprocessors by Ingenic. + * + * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X1= 6 is + * the control register. + * + * + * The notation used in MXU assembler mnemonics + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Register operands: + * + * XRa, XRb, XRc, XRd - MXU registers + * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers + * + * Non-register operands: + * + * aptn1 - 1-bit accumulate add/subtract pattern + * aptn2 - 2-bit accumulate add/subtract pattern + * eptn2 - 2-bit execute add/subtract pattern + * optn2 - 2-bit operand pattern + * optn3 - 3-bit operand pattern + * sft4 - 4-bit shift amount + * strd2 - 2-bit stride amount + * + * Prefixes: + * + * Level of parallelism: Operand size: + * S - single operation at a time 32 - word + * D - two operations in parallel 16 - half word + * Q - four operations in parallel 8 - byte + * + * Operations: + * + * ADD - Add or subtract + * ADDC - Add with carry-in + * ACC - Accumulate + * ASUM - Sum together then accumulate (add or subtract) + * ASUMC - Sum together then accumulate (add or subtract) with carry-in + * AVG - Average between 2 operands + * ABD - Absolute difference + * ALN - Align data + * AND - Logical bitwise 'and' operation + * CPS - Copy sign + * EXTR - Extract bits + * I2M - Move from GPR register to MXU register + * LDD - Load data from memory to XRF + * LDI - Load data from memory to XRF (and increase the address base) + * LUI - Load unsigned immediate + * MUL - Multiply + * MULU - Unsigned multiply + * MADD - 64-bit operand add 32x32 product + * MSUB - 64-bit operand subtract 32x32 product + * MAC - Multiply and accumulate (add or subtract) + * MAD - Multiply and add or subtract + * MAX - Maximum between 2 operands + * MIN - Minimum between 2 operands + * M2I - Move from MXU register to GPR register + * MOVZ - Move if zero + * MOVN - Move if non-zero + * NOR - Logical bitwise 'nor' operation + * OR - Logical bitwise 'or' operation + * STD - Store data from XRF to memory + * SDI - Store data from XRF to memory (and increase the address base) + * SLT - Set of less than comparison + * SAD - Sum of absolute differences + * SLL - Logical shift left + * SLR - Logical shift right + * SAR - Arithmetic shift right + * SAT - Saturation + * SFL - Shuffle + * SCOP - Calculate x=E2=80=99s scope (-1, means x<0; 0, means x=3D=3D0= ; 1, means x>0) + * XOR - Logical bitwise 'exclusive or' operation + * + * Suffixes: + * + * E - Expand results + * F - Fixed point multiplication + * L - Low part result + * R - Doing rounding + * V - Variable instead of immediate + * W - Combine above L and V + * + * + * The list of MXU instructions grouped by functionality + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Load/Store instructions Multiplication instructions + * ----------------------- --------------------------- + * + * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt + * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt + * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt + * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt + * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt + * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt + * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2 + * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2 + * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2 + * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, op= tn2 + * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, o= ptn2 + * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, o= ptn2 + * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, o= ptn2 + * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, op= tn2 + * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd + * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd + * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2 + * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2 + * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2 + * S16SDI XRa, Rb, s10, eptn2 + * S8LDD XRa, Rb, s8, eptn3 + * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions + * S8LDI XRa, Rb, s8, eptn3 ------------------------------------- + * S8SDI XRa, Rb, s8, eptn3 + * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2 + * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd + * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2 + * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2 + * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2 + * S32CPS XRa, XRb, XRc + * Q16ADD XRa, XRb, XRc, XRd, eptn2, op= tn2 + * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2 + * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2 + * D16ASUM XRa, XRb, XRc, XRd, eptn2 + * S32MAX XRa, XRb, XRc D16CPS XRa, XRb, + * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc + * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc + * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2 + * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2 + * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2 + * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc + * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd + * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc + * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc + * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd + * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd + * Q8SLT XRa, XRb, XRc + * Q8SLTU XRa, XRb, XRc + * Q8MOVZ XRa, XRb, XRc Shift instructions + * Q8MOVN XRa, XRb, XRc ------------------ + * + * D32SLL XRa, XRb, XRc, XRd, sft4 + * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4 + * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4 + * D32SARL XRa, XRb, XRc, sft4 + * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb + * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb + * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb + * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb + * Q16SLL XRa, XRb, XRc, XRd, sft4 + * Q16SLR XRa, XRb, XRc, XRd, sft4 + * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4 + * ------------------------- Q16SLLV XRa, XRb, Rb + * Q16SLRV XRa, XRb, Rb + * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb + * S32ALN XRa, XRb, XRc, Rb + * S32ALNI XRa, XRb, XRc, s3 + * S32LUI XRa, s8, optn3 Move instructions + * S32EXTR XRa, XRb, Rb, bits5 ----------------- + * S32EXTRV XRa, XRb, Rs, Rt + * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb + * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb + * + * + * The opcode organization of MXU instructions + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred + * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning = of + * other bits up to the instruction level is as follows: + * + * bits + * 05..00 + * + * =E2=94=8C=E2=94=80 000000 =E2=94=80 OPC_MXU_S32MADD + * =E2=94=9C=E2=94=80 000001 =E2=94=80 OPC_MXU_S32MADDU + * =E2=94=9C=E2=94=80 000010 =E2=94=80 (non-MXU = OPC_MUL) + * =E2=94=82 + * =E2=94=82 20..18 + * =E2=94=9C=E2=94=80 000011 =E2=94=80 OPC_MXU__POOL00 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_S32MAX + * =E2=94=82 =E2=94=9C=E2=94=80 001 = =E2=94=80 OPC_MXU_S32MIN + * =E2=94=82 =E2=94=9C=E2=94=80 010 = =E2=94=80 OPC_MXU_D16MAX + * =E2=94=82 =E2=94=9C=E2=94=80 011 = =E2=94=80 OPC_MXU_D16MIN + * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_Q8MAX + * =E2=94=82 =E2=94=9C=E2=94=80 101 = =E2=94=80 OPC_MXU_Q8MIN + * =E2=94=82 =E2=94=9C=E2=94=80 110 = =E2=94=80 OPC_MXU_Q8SLT + * =E2=94=82 =E2=94=94=E2=94=80 111 = =E2=94=80 OPC_MXU_Q8SLTU + * =E2=94=9C=E2=94=80 000100 =E2=94=80 OPC_MXU_S32MSUB + * =E2=94=9C=E2=94=80 000101 =E2=94=80 OPC_MXU_S32MSUBU 20..18 + * =E2=94=9C=E2=94=80 000110 =E2=94=80 OPC_MXU__POOL01 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_S32SLT + * =E2=94=82 =E2=94=9C=E2=94=80 001 = =E2=94=80 OPC_MXU_D16SLT + * =E2=94=82 =E2=94=9C=E2=94=80 010 = =E2=94=80 OPC_MXU_D16AVG + * =E2=94=82 =E2=94=9C=E2=94=80 011 = =E2=94=80 OPC_MXU_D16AVGR + * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_Q8AVG + * =E2=94=82 =E2=94=9C=E2=94=80 101 = =E2=94=80 OPC_MXU_Q8AVGR + * =E2=94=82 =E2=94=94=E2=94=80 111 = =E2=94=80 OPC_MXU_Q8ADD + * =E2=94=82 + * =E2=94=82 20..18 + * =E2=94=9C=E2=94=80 000111 =E2=94=80 OPC_MXU__POOL02 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_S32CPS + * =E2=94=82 =E2=94=9C=E2=94=80 010 = =E2=94=80 OPC_MXU_D16CPS + * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_Q8ABD + * =E2=94=82 =E2=94=94=E2=94=80 110 = =E2=94=80 OPC_MXU_Q16SAT + * =E2=94=9C=E2=94=80 001000 =E2=94=80 OPC_MXU_D16MUL + * =E2=94=82 25..24 + * =E2=94=9C=E2=94=80 001001 =E2=94=80 OPC_MXU__POOL03 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_D16MULF + * =E2=94=82 =E2=94=94=E2=94=80 01 =E2= =94=80 OPC_MXU_D16MULE + * =E2=94=9C=E2=94=80 001010 =E2=94=80 OPC_MXU_D16MAC + * =E2=94=9C=E2=94=80 001011 =E2=94=80 OPC_MXU_D16MACF + * =E2=94=9C=E2=94=80 001100 =E2=94=80 OPC_MXU_D16MADL + * =E2=94=9C=E2=94=80 001101 =E2=94=80 OPC_MXU_S16MAD + * =E2=94=9C=E2=94=80 001110 =E2=94=80 OPC_MXU_Q16ADD + * =E2=94=9C=E2=94=80 001111 =E2=94=80 OPC_MXU_D16MACE 23 + * =E2=94=82 =E2=94=8C=E2=94=80 0 =E2= =94=80 OPC_MXU_S32LDD + * =E2=94=9C=E2=94=80 010000 =E2=94=80 OPC_MXU__POOL04 =E2=94=80= =E2=94=B4=E2=94=80 1 =E2=94=80 OPC_MXU_S32LDDR + * =E2=94=82 + * =E2=94=82 23 + * =E2=94=9C=E2=94=80 010001 =E2=94=80 OPC_MXU__POOL05 =E2=94=80= =E2=94=AC=E2=94=80 0 =E2=94=80 OPC_MXU_S32STD + * =E2=94=82 =E2=94=94=E2=94=80 1 =E2= =94=80 OPC_MXU_S32STDR + * =E2=94=82 + * =E2=94=82 13..10 + * =E2=94=9C=E2=94=80 010010 =E2=94=80 OPC_MXU__POOL06 =E2=94=80= =E2=94=AC=E2=94=80 0000 =E2=94=80 OPC_MXU_S32LDDV + * =E2=94=82 =E2=94=94=E2=94=80 0001 = =E2=94=80 OPC_MXU_S32LDDVR + * =E2=94=82 + * =E2=94=82 13..10 + * =E2=94=9C=E2=94=80 010011 =E2=94=80 OPC_MXU__POOL07 =E2=94=80= =E2=94=AC=E2=94=80 0000 =E2=94=80 OPC_MXU_S32STDV + * =E2=94=82 =E2=94=94=E2=94=80 0001 = =E2=94=80 OPC_MXU_S32STDVR + * =E2=94=82 + * =E2=94=82 23 + * =E2=94=9C=E2=94=80 010100 =E2=94=80 OPC_MXU__POOL08 =E2=94=80= =E2=94=AC=E2=94=80 0 =E2=94=80 OPC_MXU_S32LDI + * =E2=94=82 =E2=94=94=E2=94=80 1 =E2= =94=80 OPC_MXU_S32LDIR + * =E2=94=82 + * =E2=94=82 23 + * =E2=94=9C=E2=94=80 010101 =E2=94=80 OPC_MXU__POOL09 =E2=94=80= =E2=94=AC=E2=94=80 0 =E2=94=80 OPC_MXU_S32SDI + * =E2=94=82 =E2=94=94=E2=94=80 1 =E2= =94=80 OPC_MXU_S32SDIR + * =E2=94=82 + * =E2=94=82 13..10 + * =E2=94=9C=E2=94=80 010110 =E2=94=80 OPC_MXU__POOL10 =E2=94=80= =E2=94=AC=E2=94=80 0000 =E2=94=80 OPC_MXU_S32LDIV + * =E2=94=82 =E2=94=94=E2=94=80 0001 = =E2=94=80 OPC_MXU_S32LDIVR + * =E2=94=82 + * =E2=94=82 13..10 + * =E2=94=9C=E2=94=80 010111 =E2=94=80 OPC_MXU__POOL11 =E2=94=80= =E2=94=AC=E2=94=80 0000 =E2=94=80 OPC_MXU_S32SDIV + * =E2=94=82 =E2=94=94=E2=94=80 0001 = =E2=94=80 OPC_MXU_S32SDIVR + * =E2=94=9C=E2=94=80 011000 =E2=94=80 OPC_MXU_D32ADD + * =E2=94=82 23..22 + * MXU =E2=94=9C=E2=94=80 011001 =E2=94=80 OPC_MXU__POOL12 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_D32ACC + * opcodes =E2=94=80=E2=94=A4 =E2=94=9C=E2=94= =80 01 =E2=94=80 OPC_MXU_D32ACCM + * =E2=94=82 =E2=94=94=E2=94=80 10 =E2= =94=80 OPC_MXU_D32ASUM + * =E2=94=9C=E2=94=80 011010 =E2=94=80 + * =E2=94=82 23..22 + * =E2=94=9C=E2=94=80 011011 =E2=94=80 OPC_MXU__POOL13 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_Q16ACC + * =E2=94=82 =E2=94=9C=E2=94=80 01 =E2= =94=80 OPC_MXU_Q16ACCM + * =E2=94=82 =E2=94=94=E2=94=80 10 =E2= =94=80 OPC_MXU_Q16ASUM + * =E2=94=82 + * =E2=94=82 23..22 + * =E2=94=9C=E2=94=80 011100 =E2=94=80 OPC_MXU__POOL14 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_Q8ADDE + * =E2=94=82 =E2=94=9C=E2=94=80 01 =E2= =94=80 OPC_MXU_D8SUM + * =E2=94=9C=E2=94=80 011101 =E2=94=80 OPC_MXU_Q8ACCE =E2=94=94= =E2=94=80 10 =E2=94=80 OPC_MXU_D8SUMC + * =E2=94=9C=E2=94=80 011110 =E2=94=80 + * =E2=94=9C=E2=94=80 011111 =E2=94=80 + * =E2=94=9C=E2=94=80 100000 =E2=94=80 (overlaps= with CLZ) + * =E2=94=9C=E2=94=80 100001 =E2=94=80 (overlaps= with CLO) + * =E2=94=9C=E2=94=80 100010 =E2=94=80 OPC_MXU_S8LDD + * =E2=94=9C=E2=94=80 100011 =E2=94=80 OPC_MXU_S8STD 15..14 + * =E2=94=9C=E2=94=80 100100 =E2=94=80 OPC_MXU_S8LDI =E2=94=8C= =E2=94=80 00 =E2=94=80 OPC_MXU_S32MUL + * =E2=94=9C=E2=94=80 100101 =E2=94=80 OPC_MXU_S8SDI =E2=94=9C= =E2=94=80 00 =E2=94=80 OPC_MXU_S32MULU + * =E2=94=82 =E2=94=9C=E2=94=80 00 =E2= =94=80 OPC_MXU_S32EXTR + * =E2=94=9C=E2=94=80 100110 =E2=94=80 OPC_MXU__POOL15 =E2=94=80= =E2=94=B4=E2=94=80 00 =E2=94=80 OPC_MXU_S32EXTRV + * =E2=94=82 + * =E2=94=82 20..18 + * =E2=94=9C=E2=94=80 100111 =E2=94=80 OPC_MXU__POOL16 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_D32SARW + * =E2=94=82 =E2=94=9C=E2=94=80 001 = =E2=94=80 OPC_MXU_S32ALN + * =E2=94=82 =E2=94=9C=E2=94=80 010 = =E2=94=80 OPC_MXU_S32ALNI + * =E2=94=82 =E2=94=9C=E2=94=80 011 = =E2=94=80 OPC_MXU_S32LUI + * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_S32NOR + * =E2=94=82 =E2=94=9C=E2=94=80 101 = =E2=94=80 OPC_MXU_S32AND + * =E2=94=82 =E2=94=9C=E2=94=80 110 = =E2=94=80 OPC_MXU_S32OR + * =E2=94=82 =E2=94=94=E2=94=80 111 = =E2=94=80 OPC_MXU_S32XOR + * =E2=94=82 + * =E2=94=82 7..5 + * =E2=94=9C=E2=94=80 101000 =E2=94=80 OPC_MXU__POOL17 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_LXB + * =E2=94=82 =E2=94=9C=E2=94=80 001 = =E2=94=80 OPC_MXU_LXH + * =E2=94=9C=E2=94=80 101001 =E2=94=80 =E2=94=9C= =E2=94=80 011 =E2=94=80 OPC_MXU_LXW + * =E2=94=9C=E2=94=80 101010 =E2=94=80 OPC_MXU_S16LDD =E2=94=9C= =E2=94=80 100 =E2=94=80 OPC_MXU_LXBU + * =E2=94=9C=E2=94=80 101011 =E2=94=80 OPC_MXU_S16STD =E2=94=94= =E2=94=80 101 =E2=94=80 OPC_MXU_LXHU + * =E2=94=9C=E2=94=80 101100 =E2=94=80 OPC_MXU_S16LDI + * =E2=94=9C=E2=94=80 101101 =E2=94=80 OPC_MXU_S16SDI + * =E2=94=9C=E2=94=80 101110 =E2=94=80 OPC_MXU_S32M2I + * =E2=94=9C=E2=94=80 101111 =E2=94=80 OPC_MXU_S32I2M + * =E2=94=9C=E2=94=80 110000 =E2=94=80 OPC_MXU_D32SLL + * =E2=94=9C=E2=94=80 110001 =E2=94=80 OPC_MXU_D32SLR 20..18 + * =E2=94=9C=E2=94=80 110010 =E2=94=80 OPC_MXU_D32SARL =E2=94=8C= =E2=94=80 000 =E2=94=80 OPC_MXU_D32SLLV + * =E2=94=9C=E2=94=80 110011 =E2=94=80 OPC_MXU_D32SAR =E2=94=9C= =E2=94=80 001 =E2=94=80 OPC_MXU_D32SLRV + * =E2=94=9C=E2=94=80 110100 =E2=94=80 OPC_MXU_Q16SLL =E2=94=9C= =E2=94=80 010 =E2=94=80 OPC_MXU_D32SARV + * =E2=94=9C=E2=94=80 110101 =E2=94=80 OPC_MXU_Q16SLR =E2=94=9C= =E2=94=80 011 =E2=94=80 OPC_MXU_Q16SLLV + * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_Q16SLRV + * =E2=94=9C=E2=94=80 110110 =E2=94=80 OPC_MXU__POOL18 =E2=94=80= =E2=94=B4=E2=94=80 101 =E2=94=80 OPC_MXU_Q16SARV + * =E2=94=82 + * =E2=94=9C=E2=94=80 110111 =E2=94=80 OPC_MXU_Q16SAR + * =E2=94=82 23..22 + * =E2=94=9C=E2=94=80 111000 =E2=94=80 OPC_MXU__POOL19 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_Q8MUL + * =E2=94=82 =E2=94=94=E2=94=80 01 =E2= =94=80 OPC_MXU_Q8MULSU + * =E2=94=82 + * =E2=94=82 20..18 + * =E2=94=9C=E2=94=80 111001 =E2=94=80 OPC_MXU__POOL20 =E2=94=80= =E2=94=AC=E2=94=80 000 =E2=94=80 OPC_MXU_Q8MOVZ + * =E2=94=82 =E2=94=9C=E2=94=80 001 = =E2=94=80 OPC_MXU_Q8MOVN + * =E2=94=82 =E2=94=9C=E2=94=80 010 = =E2=94=80 OPC_MXU_D16MOVZ + * =E2=94=82 =E2=94=9C=E2=94=80 011 = =E2=94=80 OPC_MXU_D16MOVN + * =E2=94=82 =E2=94=9C=E2=94=80 100 = =E2=94=80 OPC_MXU_S32MOVZ + * =E2=94=82 =E2=94=94=E2=94=80 101 = =E2=94=80 OPC_MXU_S32MOVN + * =E2=94=82 + * =E2=94=82 23..22 + * =E2=94=9C=E2=94=80 111010 =E2=94=80 OPC_MXU__POOL21 =E2=94=80= =E2=94=AC=E2=94=80 00 =E2=94=80 OPC_MXU_Q8MAC + * =E2=94=82 =E2=94=94=E2=94=80 10 =E2= =94=80 OPC_MXU_Q8MACSU + * =E2=94=9C=E2=94=80 111011 =E2=94=80 OPC_MXU_Q16SCOP + * =E2=94=9C=E2=94=80 111100 =E2=94=80 OPC_MXU_Q8MADL + * =E2=94=9C=E2=94=80 111101 =E2=94=80 OPC_MXU_S32SFL + * =E2=94=9C=E2=94=80 111110 =E2=94=80 OPC_MXU_Q8SAD + * =E2=94=94=E2=94=80 111111 =E2=94=80 (overlaps= with SDBBP) + * + * + * Compiled after: + * + * "XBurst=C2=AE Instruction Set Architecture MIPS eXtension/enhanced Un= it + * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2,= 2017 + */ + +enum { + OPC_MXU_S32MADD =3D 0x00, + OPC_MXU_S32MADDU =3D 0x01, + OPC__MXU_MUL =3D 0x02, + OPC_MXU__POOL00 =3D 0x03, + OPC_MXU_S32MSUB =3D 0x04, + OPC_MXU_S32MSUBU =3D 0x05, + OPC_MXU__POOL01 =3D 0x06, + OPC_MXU__POOL02 =3D 0x07, + OPC_MXU_D16MUL =3D 0x08, + OPC_MXU__POOL03 =3D 0x09, + OPC_MXU_D16MAC =3D 0x0A, + OPC_MXU_D16MACF =3D 0x0B, + OPC_MXU_D16MADL =3D 0x0C, + OPC_MXU_S16MAD =3D 0x0D, + OPC_MXU_Q16ADD =3D 0x0E, + OPC_MXU_D16MACE =3D 0x0F, + OPC_MXU__POOL04 =3D 0x10, + OPC_MXU__POOL05 =3D 0x11, + OPC_MXU__POOL06 =3D 0x12, + OPC_MXU__POOL07 =3D 0x13, + OPC_MXU__POOL08 =3D 0x14, + OPC_MXU__POOL09 =3D 0x15, + OPC_MXU__POOL10 =3D 0x16, + OPC_MXU__POOL11 =3D 0x17, + OPC_MXU_D32ADD =3D 0x18, + OPC_MXU__POOL12 =3D 0x19, + /* not assigned 0x1A */ + OPC_MXU__POOL13 =3D 0x1B, + OPC_MXU__POOL14 =3D 0x1C, + OPC_MXU_Q8ACCE =3D 0x1D, + /* not assigned 0x1E */ + /* not assigned 0x1F */ + /* not assigned 0x20 */ + /* not assigned 0x21 */ + OPC_MXU_S8LDD =3D 0x22, + OPC_MXU_S8STD =3D 0x23, + OPC_MXU_S8LDI =3D 0x24, + OPC_MXU_S8SDI =3D 0x25, + OPC_MXU__POOL15 =3D 0x26, + OPC_MXU__POOL16 =3D 0x27, + OPC_MXU__POOL17 =3D 0x28, + /* not assigned 0x29 */ + OPC_MXU_S16LDD =3D 0x2A, + OPC_MXU_S16STD =3D 0x2B, + OPC_MXU_S16LDI =3D 0x2C, + OPC_MXU_S16SDI =3D 0x2D, + OPC_MXU_S32M2I =3D 0x2E, + OPC_MXU_S32I2M =3D 0x2F, + OPC_MXU_D32SLL =3D 0x30, + OPC_MXU_D32SLR =3D 0x31, + OPC_MXU_D32SARL =3D 0x32, + OPC_MXU_D32SAR =3D 0x33, + OPC_MXU_Q16SLL =3D 0x34, + OPC_MXU_Q16SLR =3D 0x35, + OPC_MXU__POOL18 =3D 0x36, + OPC_MXU_Q16SAR =3D 0x37, + OPC_MXU__POOL19 =3D 0x38, + OPC_MXU__POOL20 =3D 0x39, + OPC_MXU__POOL21 =3D 0x3A, + OPC_MXU_Q16SCOP =3D 0x3B, + OPC_MXU_Q8MADL =3D 0x3C, + OPC_MXU_S32SFL =3D 0x3D, + OPC_MXU_Q8SAD =3D 0x3E, + /* not assigned 0x3F */ +}; + + +/* + * MXU pool 00 + */ +enum { + OPC_MXU_S32MAX =3D 0x00, + OPC_MXU_S32MIN =3D 0x01, + OPC_MXU_D16MAX =3D 0x02, + OPC_MXU_D16MIN =3D 0x03, + OPC_MXU_Q8MAX =3D 0x04, + OPC_MXU_Q8MIN =3D 0x05, + OPC_MXU_Q8SLT =3D 0x06, + OPC_MXU_Q8SLTU =3D 0x07, +}; + +/* + * MXU pool 01 + */ +enum { + OPC_MXU_S32SLT =3D 0x00, + OPC_MXU_D16SLT =3D 0x01, + OPC_MXU_D16AVG =3D 0x02, + OPC_MXU_D16AVGR =3D 0x03, + OPC_MXU_Q8AVG =3D 0x04, + OPC_MXU_Q8AVGR =3D 0x05, + OPC_MXU_Q8ADD =3D 0x07, +}; + +/* + * MXU pool 02 + */ +enum { + OPC_MXU_S32CPS =3D 0x00, + OPC_MXU_D16CPS =3D 0x02, + OPC_MXU_Q8ABD =3D 0x04, + OPC_MXU_Q16SAT =3D 0x06, +}; + +/* + * MXU pool 03 + */ +enum { + OPC_MXU_D16MULF =3D 0x00, + OPC_MXU_D16MULE =3D 0x01, +}; + +/* + * MXU pool 04 + */ +enum { + OPC_MXU_S32LDD =3D 0x00, + OPC_MXU_S32LDDR =3D 0x01, +}; + +/* + * MXU pool 05 + */ +enum { + OPC_MXU_S32STD =3D 0x00, + OPC_MXU_S32STDR =3D 0x01, +}; + +/* + * MXU pool 06 + */ +enum { + OPC_MXU_S32LDDV =3D 0x00, + OPC_MXU_S32LDDVR =3D 0x01, +}; + +/* + * MXU pool 07 + */ +enum { + OPC_MXU_S32STDV =3D 0x00, + OPC_MXU_S32STDVR =3D 0x01, +}; + +/* + * MXU pool 08 + */ +enum { + OPC_MXU_S32LDI =3D 0x00, + OPC_MXU_S32LDIR =3D 0x01, +}; + +/* + * MXU pool 09 + */ +enum { + OPC_MXU_S32SDI =3D 0x00, + OPC_MXU_S32SDIR =3D 0x01, +}; + +/* + * MXU pool 10 + */ +enum { + OPC_MXU_S32LDIV =3D 0x00, + OPC_MXU_S32LDIVR =3D 0x01, +}; + +/* + * MXU pool 11 + */ +enum { + OPC_MXU_S32SDIV =3D 0x00, + OPC_MXU_S32SDIVR =3D 0x01, +}; + +/* + * MXU pool 12 + */ +enum { + OPC_MXU_D32ACC =3D 0x00, + OPC_MXU_D32ACCM =3D 0x01, + OPC_MXU_D32ASUM =3D 0x02, +}; + +/* + * MXU pool 13 + */ +enum { + OPC_MXU_Q16ACC =3D 0x00, + OPC_MXU_Q16ACCM =3D 0x01, + OPC_MXU_Q16ASUM =3D 0x02, +}; + +/* + * MXU pool 14 + */ +enum { + OPC_MXU_Q8ADDE =3D 0x00, + OPC_MXU_D8SUM =3D 0x01, + OPC_MXU_D8SUMC =3D 0x02, +}; + +/* + * MXU pool 15 + */ +enum { + OPC_MXU_S32MUL =3D 0x00, + OPC_MXU_S32MULU =3D 0x01, + OPC_MXU_S32EXTR =3D 0x02, + OPC_MXU_S32EXTRV =3D 0x03, +}; + +/* + * MXU pool 16 + */ +enum { + OPC_MXU_D32SARW =3D 0x00, + OPC_MXU_S32ALN =3D 0x01, + OPC_MXU_S32ALNI =3D 0x02, + OPC_MXU_S32LUI =3D 0x03, + OPC_MXU_S32NOR =3D 0x04, + OPC_MXU_S32AND =3D 0x05, + OPC_MXU_S32OR =3D 0x06, + OPC_MXU_S32XOR =3D 0x07, +}; + +/* + * MXU pool 17 + */ +enum { + OPC_MXU_LXB =3D 0x00, + OPC_MXU_LXH =3D 0x01, + OPC_MXU_LXW =3D 0x03, + OPC_MXU_LXBU =3D 0x04, + OPC_MXU_LXHU =3D 0x05, +}; + +/* + * MXU pool 18 + */ +enum { + OPC_MXU_D32SLLV =3D 0x00, + OPC_MXU_D32SLRV =3D 0x01, + OPC_MXU_D32SARV =3D 0x03, + OPC_MXU_Q16SLLV =3D 0x04, + OPC_MXU_Q16SLRV =3D 0x05, + OPC_MXU_Q16SARV =3D 0x07, +}; + +/* + * MXU pool 19 + */ +enum { + OPC_MXU_Q8MUL =3D 0x00, + OPC_MXU_Q8MULSU =3D 0x01, +}; + +/* + * MXU pool 20 + */ +enum { + OPC_MXU_Q8MOVZ =3D 0x00, + OPC_MXU_Q8MOVN =3D 0x01, + OPC_MXU_D16MOVZ =3D 0x02, + OPC_MXU_D16MOVN =3D 0x03, + OPC_MXU_S32MOVZ =3D 0x04, + OPC_MXU_S32MOVN =3D 0x05, +}; + +/* + * MXU pool 21 + */ +enum { + OPC_MXU_Q8MAC =3D 0x00, + OPC_MXU_Q8MACSU =3D 0x01, +}; + +#if !defined(TARGET_MIPS64) + +/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */ +#define MXU_APTN1_A 0 +#define MXU_APTN1_S 1 + +/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */ +#define MXU_APTN2_AA 0 +#define MXU_APTN2_AS 1 +#define MXU_APTN2_SA 2 +#define MXU_APTN2_SS 3 + +/* MXU execute add/subtract 2-bit pattern 'eptn2' */ +#define MXU_EPTN2_AA 0 +#define MXU_EPTN2_AS 1 +#define MXU_EPTN2_SA 2 +#define MXU_EPTN2_SS 3 + +/* MXU operand getting pattern 'optn2' */ +#define MXU_OPTN2_PTN0 0 +#define MXU_OPTN2_PTN1 1 +#define MXU_OPTN2_PTN2 2 +#define MXU_OPTN2_PTN3 3 +/* alternative naming scheme for 'optn2' */ +#define MXU_OPTN2_WW 0 +#define MXU_OPTN2_LW 1 +#define MXU_OPTN2_HW 2 +#define MXU_OPTN2_XW 3 + +/* MXU operand getting pattern 'optn3' */ +#define MXU_OPTN3_PTN0 0 +#define MXU_OPTN3_PTN1 1 +#define MXU_OPTN3_PTN2 2 +#define MXU_OPTN3_PTN3 3 +#define MXU_OPTN3_PTN4 4 +#define MXU_OPTN3_PTN5 5 +#define MXU_OPTN3_PTN6 6 +#define MXU_OPTN3_PTN7 7 + + +static const char * const mxuregnames[] =3D { + "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8", + "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR", +}; + +static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1]; +static TCGv mxu_CR; + + +/* MXU General purpose registers moves. */ +static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg) +{ + if (reg =3D=3D 0) { + tcg_gen_movi_tl(t, 0); + } else if (reg <=3D 15) { + tcg_gen_mov_tl(t, mxu_gpr[reg - 1]); + } +} + +static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg) +{ + if (reg > 0 && reg <=3D 15) { + tcg_gen_mov_tl(mxu_gpr[reg - 1], t); + } +} + +/* MXU control register moves. */ +static inline void gen_load_mxu_cr(TCGv t) +{ + tcg_gen_mov_tl(t, mxu_CR); +} + +static inline void gen_store_mxu_cr(TCGv t) +{ + /* TODO: Add handling of RW rules for MXU_CR. */ + tcg_gen_mov_tl(mxu_CR, t); +} + + +/* + * S32I2M XRa, rb - Register move from GRF to XRF + */ +static void gen_mxu_s32i2m(DisasContext *ctx) +{ + TCGv t0; + uint32_t XRa, Rb; + + t0 =3D tcg_temp_new(); + + XRa =3D extract32(ctx->opcode, 6, 5); + Rb =3D extract32(ctx->opcode, 16, 5); + + gen_load_gpr(t0, Rb); + if (XRa <=3D 15) { + gen_store_mxu_gpr(t0, XRa); + } else if (XRa =3D=3D 16) { + gen_store_mxu_cr(t0); + } + + tcg_temp_free(t0); +} + +/* + * S32M2I XRa, rb - Register move from XRF to GRF + */ +static void gen_mxu_s32m2i(DisasContext *ctx) +{ + TCGv t0; + uint32_t XRa, Rb; + + t0 =3D tcg_temp_new(); + + XRa =3D extract32(ctx->opcode, 6, 5); + Rb =3D extract32(ctx->opcode, 16, 5); + + if (XRa <=3D 15) { + gen_load_mxu_gpr(t0, XRa); + } else if (XRa =3D=3D 16) { + gen_load_mxu_cr(t0); + } + + gen_store_gpr(t0, Rb); + + tcg_temp_free(t0); +} + +/* + * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF + */ +static void gen_mxu_s8ldd(DisasContext *ctx) +{ + TCGv t0, t1; + uint32_t XRa, Rb, s8, optn3; + + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + + XRa =3D extract32(ctx->opcode, 6, 4); + s8 =3D extract32(ctx->opcode, 10, 8); + optn3 =3D extract32(ctx->opcode, 18, 3); + Rb =3D extract32(ctx->opcode, 21, 5); + + gen_load_gpr(t0, Rb); + tcg_gen_addi_tl(t0, t0, (int8_t)s8); + + switch (optn3) { + /* XRa[7:0] =3D tmp8 */ + case MXU_OPTN3_PTN0: + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + gen_load_mxu_gpr(t0, XRa); + tcg_gen_deposit_tl(t0, t0, t1, 0, 8); + break; + /* XRa[15:8] =3D tmp8 */ + case MXU_OPTN3_PTN1: + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + gen_load_mxu_gpr(t0, XRa); + tcg_gen_deposit_tl(t0, t0, t1, 8, 8); + break; + /* XRa[23:16] =3D tmp8 */ + case MXU_OPTN3_PTN2: + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + gen_load_mxu_gpr(t0, XRa); + tcg_gen_deposit_tl(t0, t0, t1, 16, 8); + break; + /* XRa[31:24] =3D tmp8 */ + case MXU_OPTN3_PTN3: + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + gen_load_mxu_gpr(t0, XRa); + tcg_gen_deposit_tl(t0, t0, t1, 24, 8); + break; + /* XRa =3D {8'b0, tmp8, 8'b0, tmp8} */ + case MXU_OPTN3_PTN4: + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + tcg_gen_deposit_tl(t0, t1, t1, 16, 16); + break; + /* XRa =3D {tmp8, 8'b0, tmp8, 8'b0} */ + case MXU_OPTN3_PTN5: + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + tcg_gen_shli_tl(t1, t1, 8); + tcg_gen_deposit_tl(t0, t1, t1, 16, 16); + break; + /* XRa =3D {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */ + case MXU_OPTN3_PTN6: + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB); + tcg_gen_mov_tl(t0, t1); + tcg_gen_andi_tl(t0, t0, 0xFF00FFFF); + tcg_gen_shli_tl(t1, t1, 16); + tcg_gen_or_tl(t0, t0, t1); + break; + /* XRa =3D {tmp8, tmp8, tmp8, tmp8} */ + case MXU_OPTN3_PTN7: + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); + tcg_gen_deposit_tl(t1, t1, t1, 8, 8); + tcg_gen_deposit_tl(t0, t1, t1, 16, 16); + break; + } + + gen_store_mxu_gpr(t0, XRa); + + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +/* + * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication + */ +static void gen_mxu_d16mul(DisasContext *ctx) +{ + TCGv t0, t1, t2, t3; + uint32_t XRa, XRb, XRc, XRd, optn2; + + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + t2 =3D tcg_temp_new(); + t3 =3D tcg_temp_new(); + + XRa =3D extract32(ctx->opcode, 6, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRc =3D extract32(ctx->opcode, 14, 4); + XRd =3D extract32(ctx->opcode, 18, 4); + optn2 =3D extract32(ctx->opcode, 22, 2); + + gen_load_mxu_gpr(t1, XRb); + tcg_gen_sextract_tl(t0, t1, 0, 16); + tcg_gen_sextract_tl(t1, t1, 16, 16); + gen_load_mxu_gpr(t3, XRc); + tcg_gen_sextract_tl(t2, t3, 0, 16); + tcg_gen_sextract_tl(t3, t3, 16, 16); + + switch (optn2) { + case MXU_OPTN2_WW: /* XRB.H*XRC.H =3D=3D lop, XRB.L*XRC.L =3D=3D rop */ + tcg_gen_mul_tl(t3, t1, t3); + tcg_gen_mul_tl(t2, t0, t2); + break; + case MXU_OPTN2_LW: /* XRB.L*XRC.H =3D=3D lop, XRB.L*XRC.L =3D=3D rop */ + tcg_gen_mul_tl(t3, t0, t3); + tcg_gen_mul_tl(t2, t0, t2); + break; + case MXU_OPTN2_HW: /* XRB.H*XRC.H =3D=3D lop, XRB.H*XRC.L =3D=3D rop */ + tcg_gen_mul_tl(t3, t1, t3); + tcg_gen_mul_tl(t2, t1, t2); + break; + case MXU_OPTN2_XW: /* XRB.L*XRC.H =3D=3D lop, XRB.H*XRC.L =3D=3D rop */ + tcg_gen_mul_tl(t3, t0, t3); + tcg_gen_mul_tl(t2, t1, t2); + break; + } + gen_store_mxu_gpr(t3, XRa); + gen_store_mxu_gpr(t2, XRd); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); + tcg_temp_free(t3); +} + +/* + * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply + * and accumulate + */ +static void gen_mxu_d16mac(DisasContext *ctx) +{ + TCGv t0, t1, t2, t3; + uint32_t XRa, XRb, XRc, XRd, optn2, aptn2; + + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + t2 =3D tcg_temp_new(); + t3 =3D tcg_temp_new(); + + XRa =3D extract32(ctx->opcode, 6, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRc =3D extract32(ctx->opcode, 14, 4); + XRd =3D extract32(ctx->opcode, 18, 4); + optn2 =3D extract32(ctx->opcode, 22, 2); + aptn2 =3D extract32(ctx->opcode, 24, 2); + + gen_load_mxu_gpr(t1, XRb); + tcg_gen_sextract_tl(t0, t1, 0, 16); + tcg_gen_sextract_tl(t1, t1, 16, 16); + + gen_load_mxu_gpr(t3, XRc); + tcg_gen_sextract_tl(t2, t3, 0, 16); + tcg_gen_sextract_tl(t3, t3, 16, 16); + + switch (optn2) { + case MXU_OPTN2_WW: /* XRB.H*XRC.H =3D=3D lop, XRB.L*XRC.L =3D=3D rop */ + tcg_gen_mul_tl(t3, t1, t3); + tcg_gen_mul_tl(t2, t0, t2); + break; + case MXU_OPTN2_LW: /* XRB.L*XRC.H =3D=3D lop, XRB.L*XRC.L =3D=3D rop */ + tcg_gen_mul_tl(t3, t0, t3); + tcg_gen_mul_tl(t2, t0, t2); + break; + case MXU_OPTN2_HW: /* XRB.H*XRC.H =3D=3D lop, XRB.H*XRC.L =3D=3D rop */ + tcg_gen_mul_tl(t3, t1, t3); + tcg_gen_mul_tl(t2, t1, t2); + break; + case MXU_OPTN2_XW: /* XRB.L*XRC.H =3D=3D lop, XRB.H*XRC.L =3D=3D rop */ + tcg_gen_mul_tl(t3, t0, t3); + tcg_gen_mul_tl(t2, t1, t2); + break; + } + gen_load_mxu_gpr(t0, XRa); + gen_load_mxu_gpr(t1, XRd); + + switch (aptn2) { + case MXU_APTN2_AA: + tcg_gen_add_tl(t3, t0, t3); + tcg_gen_add_tl(t2, t1, t2); + break; + case MXU_APTN2_AS: + tcg_gen_add_tl(t3, t0, t3); + tcg_gen_sub_tl(t2, t1, t2); + break; + case MXU_APTN2_SA: + tcg_gen_sub_tl(t3, t0, t3); + tcg_gen_add_tl(t2, t1, t2); + break; + case MXU_APTN2_SS: + tcg_gen_sub_tl(t3, t0, t3); + tcg_gen_sub_tl(t2, t1, t2); + break; + } + gen_store_mxu_gpr(t3, XRa); + gen_store_mxu_gpr(t2, XRd); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); + tcg_temp_free(t3); +} + +/* + * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply + * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply + */ +static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx) +{ + TCGv t0, t1, t2, t3, t4, t5, t6, t7; + uint32_t XRa, XRb, XRc, XRd, sel; + + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + t2 =3D tcg_temp_new(); + t3 =3D tcg_temp_new(); + t4 =3D tcg_temp_new(); + t5 =3D tcg_temp_new(); + t6 =3D tcg_temp_new(); + t7 =3D tcg_temp_new(); + + XRa =3D extract32(ctx->opcode, 6, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRc =3D extract32(ctx->opcode, 14, 4); + XRd =3D extract32(ctx->opcode, 18, 4); + sel =3D extract32(ctx->opcode, 22, 2); + + gen_load_mxu_gpr(t3, XRb); + gen_load_mxu_gpr(t7, XRc); + + if (sel =3D=3D 0x2) { + /* Q8MULSU */ + tcg_gen_ext8s_tl(t0, t3); + tcg_gen_shri_tl(t3, t3, 8); + tcg_gen_ext8s_tl(t1, t3); + tcg_gen_shri_tl(t3, t3, 8); + tcg_gen_ext8s_tl(t2, t3); + tcg_gen_shri_tl(t3, t3, 8); + tcg_gen_ext8s_tl(t3, t3); + } else { + /* Q8MUL */ + tcg_gen_ext8u_tl(t0, t3); + tcg_gen_shri_tl(t3, t3, 8); + tcg_gen_ext8u_tl(t1, t3); + tcg_gen_shri_tl(t3, t3, 8); + tcg_gen_ext8u_tl(t2, t3); + tcg_gen_shri_tl(t3, t3, 8); + tcg_gen_ext8u_tl(t3, t3); + } + + tcg_gen_ext8u_tl(t4, t7); + tcg_gen_shri_tl(t7, t7, 8); + tcg_gen_ext8u_tl(t5, t7); + tcg_gen_shri_tl(t7, t7, 8); + tcg_gen_ext8u_tl(t6, t7); + tcg_gen_shri_tl(t7, t7, 8); + tcg_gen_ext8u_tl(t7, t7); + + tcg_gen_mul_tl(t0, t0, t4); + tcg_gen_mul_tl(t1, t1, t5); + tcg_gen_mul_tl(t2, t2, t6); + tcg_gen_mul_tl(t3, t3, t7); + + tcg_gen_andi_tl(t0, t0, 0xFFFF); + tcg_gen_andi_tl(t1, t1, 0xFFFF); + tcg_gen_andi_tl(t2, t2, 0xFFFF); + tcg_gen_andi_tl(t3, t3, 0xFFFF); + + tcg_gen_shli_tl(t1, t1, 16); + tcg_gen_shli_tl(t3, t3, 16); + + tcg_gen_or_tl(t0, t0, t1); + tcg_gen_or_tl(t1, t2, t3); + + gen_store_mxu_gpr(t0, XRd); + gen_store_mxu_gpr(t1, XRa); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); + tcg_temp_free(t3); + tcg_temp_free(t4); + tcg_temp_free(t5); + tcg_temp_free(t6); + tcg_temp_free(t7); +} + +/* + * S32LDD XRa, Rb, S12 - Load a word from memory to XRF + * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte se= q. + */ +static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx) +{ + TCGv t0, t1; + uint32_t XRa, Rb, s12, sel; + + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + + XRa =3D extract32(ctx->opcode, 6, 4); + s12 =3D extract32(ctx->opcode, 10, 10); + sel =3D extract32(ctx->opcode, 20, 1); + Rb =3D extract32(ctx->opcode, 21, 5); + + gen_load_gpr(t0, Rb); + + tcg_gen_movi_tl(t1, s12); + tcg_gen_shli_tl(t1, t1, 2); + if (s12 & 0x200) { + tcg_gen_ori_tl(t1, t1, 0xFFFFF000); + } + tcg_gen_add_tl(t1, t0, t1); + tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL); + + if (sel =3D=3D 1) { + /* S32LDDR */ + tcg_gen_bswap32_tl(t1, t1); + } + gen_store_mxu_gpr(t1, XRa); + + tcg_temp_free(t0); + tcg_temp_free(t1); +} + + +/* + * MXU instruction category: logic + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * S32NOR S32AND S32OR S32XOR + */ + +/* + * S32NOR XRa, XRb, XRc + * Update XRa with the result of logical bitwise 'nor' operation + * applied to the content of XRb and XRc. + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16| + * +-----------+---------+-----+-------+-------+-------+-----------+ + */ +static void gen_mxu_S32NOR(DisasContext *ctx) +{ + uint32_t pad, XRc, XRb, XRa; + + pad =3D extract32(ctx->opcode, 21, 5); + XRc =3D extract32(ctx->opcode, 14, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRa =3D extract32(ctx->opcode, 6, 4); + + if (unlikely(pad !=3D 0)) { + /* opcode padding incorrect -> do nothing */ + } else if (unlikely(XRa =3D=3D 0)) { + /* destination is zero register -> do nothing */ + } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { + /* both operands zero registers -> just set destination to all 1s = */ + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF); + } else if (unlikely(XRb =3D=3D 0)) { + /* XRb zero register -> just set destination to the negation of XR= c */ + tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]); + } else if (unlikely(XRc =3D=3D 0)) { + /* XRa zero register -> just set destination to the negation of XR= b */ + tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + } else if (unlikely(XRb =3D=3D XRc)) { + /* both operands same -> just set destination to the negation of X= Rb */ + tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + } else { + /* the most general case */ + tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - = 1]); + } +} + +/* + * S32AND XRa, XRb, XRc + * Update XRa with the result of logical bitwise 'and' operation + * applied to the content of XRb and XRc. + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16| + * +-----------+---------+-----+-------+-------+-------+-----------+ + */ +static void gen_mxu_S32AND(DisasContext *ctx) +{ + uint32_t pad, XRc, XRb, XRa; + + pad =3D extract32(ctx->opcode, 21, 5); + XRc =3D extract32(ctx->opcode, 14, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRa =3D extract32(ctx->opcode, 6, 4); + + if (unlikely(pad !=3D 0)) { + /* opcode padding incorrect -> do nothing */ + } else if (unlikely(XRa =3D=3D 0)) { + /* destination is zero register -> do nothing */ + } else if (unlikely((XRb =3D=3D 0) || (XRc =3D=3D 0))) { + /* one of operands zero register -> just set destination to all 0s= */ + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); + } else if (unlikely(XRb =3D=3D XRc)) { + /* both operands same -> just set destination to one of them */ + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + } else { + /* the most general case */ + tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - = 1]); + } +} + +/* + * S32OR XRa, XRb, XRc + * Update XRa with the result of logical bitwise 'or' operation + * applied to the content of XRb and XRc. + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16| + * +-----------+---------+-----+-------+-------+-------+-----------+ + */ +static void gen_mxu_S32OR(DisasContext *ctx) +{ + uint32_t pad, XRc, XRb, XRa; + + pad =3D extract32(ctx->opcode, 21, 5); + XRc =3D extract32(ctx->opcode, 14, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRa =3D extract32(ctx->opcode, 6, 4); + + if (unlikely(pad !=3D 0)) { + /* opcode padding incorrect -> do nothing */ + } else if (unlikely(XRa =3D=3D 0)) { + /* destination is zero register -> do nothing */ + } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { + /* both operands zero registers -> just set destination to all 0s = */ + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); + } else if (unlikely(XRb =3D=3D 0)) { + /* XRb zero register -> just set destination to the content of XRc= */ + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]); + } else if (unlikely(XRc =3D=3D 0)) { + /* XRc zero register -> just set destination to the content of XRb= */ + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + } else if (unlikely(XRb =3D=3D XRc)) { + /* both operands same -> just set destination to one of them */ + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + } else { + /* the most general case */ + tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1= ]); + } +} + +/* + * S32XOR XRa, XRb, XRc + * Update XRa with the result of logical bitwise 'xor' operation + * applied to the content of XRb and XRc. + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16| + * +-----------+---------+-----+-------+-------+-------+-----------+ + */ +static void gen_mxu_S32XOR(DisasContext *ctx) +{ + uint32_t pad, XRc, XRb, XRa; + + pad =3D extract32(ctx->opcode, 21, 5); + XRc =3D extract32(ctx->opcode, 14, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRa =3D extract32(ctx->opcode, 6, 4); + + if (unlikely(pad !=3D 0)) { + /* opcode padding incorrect -> do nothing */ + } else if (unlikely(XRa =3D=3D 0)) { + /* destination is zero register -> do nothing */ + } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { + /* both operands zero registers -> just set destination to all 0s = */ + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); + } else if (unlikely(XRb =3D=3D 0)) { + /* XRb zero register -> just set destination to the content of XRc= */ + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]); + } else if (unlikely(XRc =3D=3D 0)) { + /* XRc zero register -> just set destination to the content of XRb= */ + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + } else if (unlikely(XRb =3D=3D XRc)) { + /* both operands same -> just set destination to all 0s */ + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); + } else { + /* the most general case */ + tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - = 1]); + } +} + + +/* + * MXU instruction category max/min + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * S32MAX D16MAX Q8MAX + * S32MIN D16MIN Q8MIN + */ + +/* + * S32MAX XRa, XRb, XRc + * Update XRa with the maximum of signed 32-bit integers contained + * in XRb and XRc. + * + * S32MIN XRa, XRb, XRc + * Update XRa with the minimum of signed 32-bit integers contained + * in XRb and XRc. + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00| + * +-----------+---------+-----+-------+-------+-------+-----------+ + */ +static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx) +{ + uint32_t pad, opc, XRc, XRb, XRa; + + pad =3D extract32(ctx->opcode, 21, 5); + opc =3D extract32(ctx->opcode, 18, 3); + XRc =3D extract32(ctx->opcode, 14, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRa =3D extract32(ctx->opcode, 6, 4); + + if (unlikely(pad !=3D 0)) { + /* opcode padding incorrect -> do nothing */ + } else if (unlikely(XRa =3D=3D 0)) { + /* destination is zero register -> do nothing */ + } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { + /* both operands zero registers -> just set destination to zero */ + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); + } else if (unlikely((XRb =3D=3D 0) || (XRc =3D=3D 0))) { + /* exactly one operand is zero register - find which one is not...= */ + uint32_t XRx =3D XRb ? XRb : XRc; + /* ...and do max/min operation with one operand 0 */ + if (opc =3D=3D OPC_MXU_S32MAX) { + tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0); + } else { + tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0); + } + } else if (unlikely(XRb =3D=3D XRc)) { + /* both operands same -> just set destination to one of them */ + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + } else { + /* the most general case */ + if (opc =3D=3D OPC_MXU_S32MAX) { + tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], + mxu_gpr[XRc - 1]); + } else { + tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], + mxu_gpr[XRc - 1]); + } + } +} + +/* + * D16MAX + * Update XRa with the 16-bit-wise maximums of signed integers + * contained in XRb and XRc. + * + * D16MIN + * Update XRa with the 16-bit-wise minimums of signed integers + * contained in XRb and XRc. + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00| + * +-----------+---------+-----+-------+-------+-------+-----------+ + */ +static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx) +{ + uint32_t pad, opc, XRc, XRb, XRa; + + pad =3D extract32(ctx->opcode, 21, 5); + opc =3D extract32(ctx->opcode, 18, 3); + XRc =3D extract32(ctx->opcode, 14, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRa =3D extract32(ctx->opcode, 6, 4); + + if (unlikely(pad !=3D 0)) { + /* opcode padding incorrect -> do nothing */ + } else if (unlikely(XRc =3D=3D 0)) { + /* destination is zero register -> do nothing */ + } else if (unlikely((XRb =3D=3D 0) && (XRa =3D=3D 0))) { + /* both operands zero registers -> just set destination to zero */ + tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0); + } else if (unlikely((XRb =3D=3D 0) || (XRa =3D=3D 0))) { + /* exactly one operand is zero register - find which one is not...= */ + uint32_t XRx =3D XRb ? XRb : XRc; + /* ...and do half-word-wise max/min with one operand 0 */ + TCGv_i32 t0 =3D tcg_temp_new(); + TCGv_i32 t1 =3D tcg_const_i32(0); + + /* the left half-word first */ + tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000); + if (opc =3D=3D OPC_MXU_D16MAX) { + tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1); + } else { + tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1); + } + + /* the right half-word */ + tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF); + /* move half-words to the leftmost position */ + tcg_gen_shli_i32(t0, t0, 16); + /* t0 will be max/min of t0 and t1 */ + if (opc =3D=3D OPC_MXU_D16MAX) { + tcg_gen_smax_i32(t0, t0, t1); + } else { + tcg_gen_smin_i32(t0, t0, t1); + } + /* return resulting half-words to its original position */ + tcg_gen_shri_i32(t0, t0, 16); + /* finally update the destination */ + tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0); + + tcg_temp_free(t1); + tcg_temp_free(t0); + } else if (unlikely(XRb =3D=3D XRc)) { + /* both operands same -> just set destination to one of them */ + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + } else { + /* the most general case */ + TCGv_i32 t0 =3D tcg_temp_new(); + TCGv_i32 t1 =3D tcg_temp_new(); + + /* the left half-word first */ + tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000); + tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000); + if (opc =3D=3D OPC_MXU_D16MAX) { + tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1); + } else { + tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1); + } + + /* the right half-word */ + tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF); + tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF); + /* move half-words to the leftmost position */ + tcg_gen_shli_i32(t0, t0, 16); + tcg_gen_shli_i32(t1, t1, 16); + /* t0 will be max/min of t0 and t1 */ + if (opc =3D=3D OPC_MXU_D16MAX) { + tcg_gen_smax_i32(t0, t0, t1); + } else { + tcg_gen_smin_i32(t0, t0, t1); + } + /* return resulting half-words to its original position */ + tcg_gen_shri_i32(t0, t0, 16); + /* finally update the destination */ + tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0); + + tcg_temp_free(t1); + tcg_temp_free(t0); + } +} + +/* + * Q8MAX + * Update XRa with the 8-bit-wise maximums of signed integers + * contained in XRb and XRc. + * + * Q8MIN + * Update XRa with the 8-bit-wise minimums of signed integers + * contained in XRb and XRc. + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00| + * +-----------+---------+-----+-------+-------+-------+-----------+ + */ +static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx) +{ + uint32_t pad, opc, XRc, XRb, XRa; + + pad =3D extract32(ctx->opcode, 21, 5); + opc =3D extract32(ctx->opcode, 18, 3); + XRc =3D extract32(ctx->opcode, 14, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRa =3D extract32(ctx->opcode, 6, 4); + + if (unlikely(pad !=3D 0)) { + /* opcode padding incorrect -> do nothing */ + } else if (unlikely(XRa =3D=3D 0)) { + /* destination is zero register -> do nothing */ + } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { + /* both operands zero registers -> just set destination to zero */ + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); + } else if (unlikely((XRb =3D=3D 0) || (XRc =3D=3D 0))) { + /* exactly one operand is zero register - make it be the first...*/ + uint32_t XRx =3D XRb ? XRb : XRc; + /* ...and do byte-wise max/min with one operand 0 */ + TCGv_i32 t0 =3D tcg_temp_new(); + TCGv_i32 t1 =3D tcg_const_i32(0); + int32_t i; + + /* the leftmost byte (byte 3) first */ + tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000); + if (opc =3D=3D OPC_MXU_Q8MAX) { + tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1); + } else { + tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1); + } + + /* bytes 2, 1, 0 */ + for (i =3D 2; i >=3D 0; i--) { + /* extract the byte */ + tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i)); + /* move the byte to the leftmost position */ + tcg_gen_shli_i32(t0, t0, 8 * (3 - i)); + /* t0 will be max/min of t0 and t1 */ + if (opc =3D=3D OPC_MXU_Q8MAX) { + tcg_gen_smax_i32(t0, t0, t1); + } else { + tcg_gen_smin_i32(t0, t0, t1); + } + /* return resulting byte to its original position */ + tcg_gen_shri_i32(t0, t0, 8 * (3 - i)); + /* finally update the destination */ + tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0); + } + + tcg_temp_free(t1); + tcg_temp_free(t0); + } else if (unlikely(XRb =3D=3D XRc)) { + /* both operands same -> just set destination to one of them */ + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + } else { + /* the most general case */ + TCGv_i32 t0 =3D tcg_temp_new(); + TCGv_i32 t1 =3D tcg_temp_new(); + int32_t i; + + /* the leftmost bytes (bytes 3) first */ + tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000); + tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000); + if (opc =3D=3D OPC_MXU_Q8MAX) { + tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1); + } else { + tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1); + } + + /* bytes 2, 1, 0 */ + for (i =3D 2; i >=3D 0; i--) { + /* extract corresponding bytes */ + tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i)); + tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i)); + /* move the bytes to the leftmost position */ + tcg_gen_shli_i32(t0, t0, 8 * (3 - i)); + tcg_gen_shli_i32(t1, t1, 8 * (3 - i)); + /* t0 will be max/min of t0 and t1 */ + if (opc =3D=3D OPC_MXU_Q8MAX) { + tcg_gen_smax_i32(t0, t0, t1); + } else { + tcg_gen_smin_i32(t0, t0, t1); + } + /* return resulting byte to its original position */ + tcg_gen_shri_i32(t0, t0, 8 * (3 - i)); + /* finally update the destination */ + tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0); + } + + tcg_temp_free(t1); + tcg_temp_free(t0); + } +} + + +/* + * MXU instruction category: align + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * S32ALN S32ALNI + */ + +/* + * S32ALNI XRc, XRb, XRa, optn3 + * Arrange bytes from XRb and XRc according to one of five sets of + * rules determined by optn3, and place the result in XRa. + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+-----+---+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16| + * +-----------+-----+---+-----+-------+-------+-------+-----------+ + * + */ +static void gen_mxu_S32ALNI(DisasContext *ctx) +{ + uint32_t optn3, pad, XRc, XRb, XRa; + + optn3 =3D extract32(ctx->opcode, 23, 3); + pad =3D extract32(ctx->opcode, 21, 2); + XRc =3D extract32(ctx->opcode, 14, 4); + XRb =3D extract32(ctx->opcode, 10, 4); + XRa =3D extract32(ctx->opcode, 6, 4); + + if (unlikely(pad !=3D 0)) { + /* opcode padding incorrect -> do nothing */ + } else if (unlikely(XRa =3D=3D 0)) { + /* destination is zero register -> do nothing */ + } else if (unlikely((XRb =3D=3D 0) && (XRc =3D=3D 0))) { + /* both operands zero registers -> just set destination to all 0s = */ + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); + } else if (unlikely(XRb =3D=3D 0)) { + /* XRb zero register -> just appropriatelly shift XRc into XRa */ + switch (optn3) { + case MXU_OPTN3_PTN0: + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); + break; + case MXU_OPTN3_PTN1: + case MXU_OPTN3_PTN2: + case MXU_OPTN3_PTN3: + tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1], + 8 * (4 - optn3)); + break; + case MXU_OPTN3_PTN4: + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]); + break; + } + } else if (unlikely(XRc =3D=3D 0)) { + /* XRc zero register -> just appropriatelly shift XRb into XRa */ + switch (optn3) { + case MXU_OPTN3_PTN0: + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + break; + case MXU_OPTN3_PTN1: + case MXU_OPTN3_PTN2: + case MXU_OPTN3_PTN3: + tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3= ); + break; + case MXU_OPTN3_PTN4: + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); + break; + } + } else if (unlikely(XRb =3D=3D XRc)) { + /* both operands same -> just rotation or moving from any of them = */ + switch (optn3) { + case MXU_OPTN3_PTN0: + case MXU_OPTN3_PTN4: + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + break; + case MXU_OPTN3_PTN1: + case MXU_OPTN3_PTN2: + case MXU_OPTN3_PTN3: + tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn= 3); + break; + } + } else { + /* the most general case */ + switch (optn3) { + case MXU_OPTN3_PTN0: + { + /* */ + /* XRb XRc */ + /* +---------------+ */ + /* | A B C D | E F G H */ + /* +-------+-------+ */ + /* | */ + /* XRa */ + /* */ + + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]); + } + break; + case MXU_OPTN3_PTN1: + { + /* */ + /* XRb XRc */ + /* +-------------------+ */ + /* A | B C D E | F G H */ + /* +---------+---------+ */ + /* | */ + /* XRa */ + /* */ + + TCGv_i32 t0 =3D tcg_temp_new(); + TCGv_i32 t1 =3D tcg_temp_new(); + + tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF); + tcg_gen_shli_i32(t0, t0, 8); + + tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000); + tcg_gen_shri_i32(t1, t1, 24); + + tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1); + + tcg_temp_free(t1); + tcg_temp_free(t0); + } + break; + case MXU_OPTN3_PTN2: + { + /* */ + /* XRb XRc */ + /* +-------------------+ */ + /* A B | C D E F | G H */ + /* +---------+---------+ */ + /* | */ + /* XRa */ + /* */ + + TCGv_i32 t0 =3D tcg_temp_new(); + TCGv_i32 t1 =3D tcg_temp_new(); + + tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF); + tcg_gen_shli_i32(t0, t0, 16); + + tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000); + tcg_gen_shri_i32(t1, t1, 16); + + tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1); + + tcg_temp_free(t1); + tcg_temp_free(t0); + } + break; + case MXU_OPTN3_PTN3: + { + /* */ + /* XRb XRc */ + /* +-------------------+ */ + /* A B C | D E F G | H */ + /* +---------+---------+ */ + /* | */ + /* XRa */ + /* */ + + TCGv_i32 t0 =3D tcg_temp_new(); + TCGv_i32 t1 =3D tcg_temp_new(); + + tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF); + tcg_gen_shli_i32(t0, t0, 24); + + tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00); + tcg_gen_shri_i32(t1, t1, 8); + + tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1); + + tcg_temp_free(t1); + tcg_temp_free(t0); + } + break; + case MXU_OPTN3_PTN4: + { + /* */ + /* XRb XRc */ + /* +---------------+ */ + /* A B C D | E F G H | */ + /* +-------+-------+ */ + /* | */ + /* XRa */ + /* */ + + tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]); + } + break; + } + } +} + + +/* + * Decoding engine for MXU + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + */ + +/* + * + * Decode MXU pool00 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00| + * +-----------+---------+-----+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 18, 3); + + switch (opcode) { + case OPC_MXU_S32MAX: + case OPC_MXU_S32MIN: + gen_mxu_S32MAX_S32MIN(ctx); + break; + case OPC_MXU_D16MAX: + case OPC_MXU_D16MIN: + gen_mxu_D16MAX_D16MIN(ctx); + break; + case OPC_MXU_Q8MAX: + case OPC_MXU_Q8MIN: + gen_mxu_Q8MAX_Q8MIN(ctx); + break; + case OPC_MXU_Q8SLT: + /* TODO: Implement emulation of Q8SLT instruction. */ + MIPS_INVAL("OPC_MXU_Q8SLT"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q8SLTU: + /* TODO: Implement emulation of Q8SLTU instruction. */ + MIPS_INVAL("OPC_MXU_Q8SLTU"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool01 + * + * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01| + * +-----------+---------+-----+-------+-------+-------+-----------+ + * + * Q8ADD: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---+-----+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01| + * +-----------+---+-----+-----+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 18, 3); + + switch (opcode) { + case OPC_MXU_S32SLT: + /* TODO: Implement emulation of S32SLT instruction. */ + MIPS_INVAL("OPC_MXU_S32SLT"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D16SLT: + /* TODO: Implement emulation of D16SLT instruction. */ + MIPS_INVAL("OPC_MXU_D16SLT"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D16AVG: + /* TODO: Implement emulation of D16AVG instruction. */ + MIPS_INVAL("OPC_MXU_D16AVG"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D16AVGR: + /* TODO: Implement emulation of D16AVGR instruction. */ + MIPS_INVAL("OPC_MXU_D16AVGR"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q8AVG: + /* TODO: Implement emulation of Q8AVG instruction. */ + MIPS_INVAL("OPC_MXU_Q8AVG"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q8AVGR: + /* TODO: Implement emulation of Q8AVGR instruction. */ + MIPS_INVAL("OPC_MXU_Q8AVGR"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q8ADD: + /* TODO: Implement emulation of Q8ADD instruction. */ + MIPS_INVAL("OPC_MXU_Q8ADD"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool02 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02| + * +-----------+---------+-----+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 18, 3); + + switch (opcode) { + case OPC_MXU_S32CPS: + /* TODO: Implement emulation of S32CPS instruction. */ + MIPS_INVAL("OPC_MXU_S32CPS"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D16CPS: + /* TODO: Implement emulation of D16CPS instruction. */ + MIPS_INVAL("OPC_MXU_D16CPS"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q8ABD: + /* TODO: Implement emulation of Q8ABD instruction. */ + MIPS_INVAL("OPC_MXU_Q8ABD"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q16SAT: + /* TODO: Implement emulation of Q16SAT instruction. */ + MIPS_INVAL("OPC_MXU_Q16SAT"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool03 + * + * D16MULF: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03| + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * + * D16MULE: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03| + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 24, 2); + + switch (opcode) { + case OPC_MXU_D16MULF: + /* TODO: Implement emulation of D16MULF instruction. */ + MIPS_INVAL("OPC_MXU_D16MULF"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D16MULE: + /* TODO: Implement emulation of D16MULE instruction. */ + MIPS_INVAL("OPC_MXU_D16MULE"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool04 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-+-------------------+-------+-----------+ + * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04| + * +-----------+---------+-+-------------------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 20, 1); + + switch (opcode) { + case OPC_MXU_S32LDD: + case OPC_MXU_S32LDDR: + gen_mxu_s32ldd_s32lddr(ctx); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool05 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-+-------------------+-------+-----------+ + * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05| + * +-----------+---------+-+-------------------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 20, 1); + + switch (opcode) { + case OPC_MXU_S32STD: + /* TODO: Implement emulation of S32STD instruction. */ + MIPS_INVAL("OPC_MXU_S32STD"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32STDR: + /* TODO: Implement emulation of S32STDR instruction. */ + MIPS_INVAL("OPC_MXU_S32STDR"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool06 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---+-------+-------+-----------+ + * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06| + * +-----------+---------+---------+---+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 10, 4); + + switch (opcode) { + case OPC_MXU_S32LDDV: + /* TODO: Implement emulation of S32LDDV instruction. */ + MIPS_INVAL("OPC_MXU_S32LDDV"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32LDDVR: + /* TODO: Implement emulation of S32LDDVR instruction. */ + MIPS_INVAL("OPC_MXU_S32LDDVR"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool07 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---+-------+-------+-----------+ + * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07| + * +-----------+---------+---------+---+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 10, 4); + + switch (opcode) { + case OPC_MXU_S32STDV: + /* TODO: Implement emulation of S32TDV instruction. */ + MIPS_INVAL("OPC_MXU_S32TDV"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32STDVR: + /* TODO: Implement emulation of S32TDVR instruction. */ + MIPS_INVAL("OPC_MXU_S32TDVR"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool08 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-+-------------------+-------+-----------+ + * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08| + * +-----------+---------+-+-------------------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 20, 1); + + switch (opcode) { + case OPC_MXU_S32LDI: + /* TODO: Implement emulation of S32LDI instruction. */ + MIPS_INVAL("OPC_MXU_S32LDI"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32LDIR: + /* TODO: Implement emulation of S32LDIR instruction. */ + MIPS_INVAL("OPC_MXU_S32LDIR"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool09 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-+-------------------+-------+-----------+ + * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09| + * +-----------+---------+-+-------------------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 5, 0); + + switch (opcode) { + case OPC_MXU_S32SDI: + /* TODO: Implement emulation of S32SDI instruction. */ + MIPS_INVAL("OPC_MXU_S32SDI"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32SDIR: + /* TODO: Implement emulation of S32SDIR instruction. */ + MIPS_INVAL("OPC_MXU_S32SDIR"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool10 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---+-------+-------+-----------+ + * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10| + * +-----------+---------+---------+---+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 5, 0); + + switch (opcode) { + case OPC_MXU_S32LDIV: + /* TODO: Implement emulation of S32LDIV instruction. */ + MIPS_INVAL("OPC_MXU_S32LDIV"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32LDIVR: + /* TODO: Implement emulation of S32LDIVR instruction. */ + MIPS_INVAL("OPC_MXU_S32LDIVR"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool11 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---+-------+-------+-----------+ + * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11| + * +-----------+---------+---------+---+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 10, 4); + + switch (opcode) { + case OPC_MXU_S32SDIV: + /* TODO: Implement emulation of S32SDIV instruction. */ + MIPS_INVAL("OPC_MXU_S32SDIV"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32SDIVR: + /* TODO: Implement emulation of S32SDIVR instruction. */ + MIPS_INVAL("OPC_MXU_S32SDIVR"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool12 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12| + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 22, 2); + + switch (opcode) { + case OPC_MXU_D32ACC: + /* TODO: Implement emulation of D32ACC instruction. */ + MIPS_INVAL("OPC_MXU_D32ACC"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D32ACCM: + /* TODO: Implement emulation of D32ACCM instruction. */ + MIPS_INVAL("OPC_MXU_D32ACCM"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D32ASUM: + /* TODO: Implement emulation of D32ASUM instruction. */ + MIPS_INVAL("OPC_MXU_D32ASUM"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool13 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13| + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 22, 2); + + switch (opcode) { + case OPC_MXU_Q16ACC: + /* TODO: Implement emulation of Q16ACC instruction. */ + MIPS_INVAL("OPC_MXU_Q16ACC"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q16ACCM: + /* TODO: Implement emulation of Q16ACCM instruction. */ + MIPS_INVAL("OPC_MXU_Q16ACCM"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q16ASUM: + /* TODO: Implement emulation of Q16ASUM instruction. */ + MIPS_INVAL("OPC_MXU_Q16ASUM"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool14 + * + * Q8ADDE, Q8ACCE: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14| + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * + * D8SUM, D8SUMC: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14| + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 22, 2); + + switch (opcode) { + case OPC_MXU_Q8ADDE: + /* TODO: Implement emulation of Q8ADDE instruction. */ + MIPS_INVAL("OPC_MXU_Q8ADDE"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D8SUM: + /* TODO: Implement emulation of D8SUM instruction. */ + MIPS_INVAL("OPC_MXU_D8SUM"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D8SUMC: + /* TODO: Implement emulation of D8SUMC instruction. */ + MIPS_INVAL("OPC_MXU_D8SUMC"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool15 + * + * S32MUL, S32MULU, S32EXTRV: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---+-------+-------+-----------+ + * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15| + * +-----------+---------+---------+---+-------+-------+-----------+ + * + * S32EXTR: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---+-------+-------+-----------+ + * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15| + * +-----------+---------+---------+---+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 14, 2); + + switch (opcode) { + case OPC_MXU_S32MUL: + /* TODO: Implement emulation of S32MUL instruction. */ + MIPS_INVAL("OPC_MXU_S32MUL"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32MULU: + /* TODO: Implement emulation of S32MULU instruction. */ + MIPS_INVAL("OPC_MXU_S32MULU"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32EXTR: + /* TODO: Implement emulation of S32EXTR instruction. */ + MIPS_INVAL("OPC_MXU_S32EXTR"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32EXTRV: + /* TODO: Implement emulation of S32EXTRV instruction. */ + MIPS_INVAL("OPC_MXU_S32EXTRV"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool16 + * + * D32SARW: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16| + * +-----------+---------+-----+-------+-------+-------+-----------+ + * + * S32ALN: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16| + * +-----------+---------+-----+-------+-------+-------+-----------+ + * + * S32ALNI: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+-----+---+-----+-------+-------+-------+-----------+ + * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16| + * +-----------+-----+---+-----+-------+-------+-------+-----------+ + * + * S32LUI: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+-----+---+-----+-------+---------------+-----------+ + * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16| + * +-----------+-----+---+-----+-------+---------------+-----------+ + * + * S32NOR, S32AND, S32OR, S32XOR: + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16| + * +-----------+---------+-----+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 18, 3); + + switch (opcode) { + case OPC_MXU_D32SARW: + /* TODO: Implement emulation of D32SARW instruction. */ + MIPS_INVAL("OPC_MXU_D32SARW"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32ALN: + /* TODO: Implement emulation of S32ALN instruction. */ + MIPS_INVAL("OPC_MXU_S32ALN"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32ALNI: + gen_mxu_S32ALNI(ctx); + break; + case OPC_MXU_S32LUI: + /* TODO: Implement emulation of S32LUI instruction. */ + MIPS_INVAL("OPC_MXU_S32LUI"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32NOR: + gen_mxu_S32NOR(ctx); + break; + case OPC_MXU_S32AND: + gen_mxu_S32AND(ctx); + break; + case OPC_MXU_S32OR: + gen_mxu_S32OR(ctx); + break; + case OPC_MXU_S32XOR: + gen_mxu_S32XOR(ctx); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool17 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---+---------+-----+-----------+ + * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15| + * +-----------+---------+---------+---+---------+-----+-----------+ + * + */ +static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 6, 2); + + switch (opcode) { + case OPC_MXU_LXW: + /* TODO: Implement emulation of LXW instruction. */ + MIPS_INVAL("OPC_MXU_LXW"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_LXH: + /* TODO: Implement emulation of LXH instruction. */ + MIPS_INVAL("OPC_MXU_LXH"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_LXHU: + /* TODO: Implement emulation of LXHU instruction. */ + MIPS_INVAL("OPC_MXU_LXHU"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_LXB: + /* TODO: Implement emulation of LXB instruction. */ + MIPS_INVAL("OPC_MXU_LXB"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_LXBU: + /* TODO: Implement emulation of LXBU instruction. */ + MIPS_INVAL("OPC_MXU_LXBU"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} +/* + * + * Decode MXU pool18 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18| + * +-----------+---------+-----+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 18, 3); + + switch (opcode) { + case OPC_MXU_D32SLLV: + /* TODO: Implement emulation of D32SLLV instruction. */ + MIPS_INVAL("OPC_MXU_D32SLLV"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D32SLRV: + /* TODO: Implement emulation of D32SLRV instruction. */ + MIPS_INVAL("OPC_MXU_D32SLRV"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D32SARV: + /* TODO: Implement emulation of D32SARV instruction. */ + MIPS_INVAL("OPC_MXU_D32SARV"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q16SLLV: + /* TODO: Implement emulation of Q16SLLV instruction. */ + MIPS_INVAL("OPC_MXU_Q16SLLV"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q16SLRV: + /* TODO: Implement emulation of Q16SLRV instruction. */ + MIPS_INVAL("OPC_MXU_Q16SLRV"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q16SARV: + /* TODO: Implement emulation of Q16SARV instruction. */ + MIPS_INVAL("OPC_MXU_Q16SARV"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool19 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19| + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 22, 2); + + switch (opcode) { + case OPC_MXU_Q8MUL: + case OPC_MXU_Q8MULSU: + gen_mxu_q8mul_q8mulsu(ctx); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool20 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+-----+-------+-------+-------+-----------+ + * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20| + * +-----------+---------+-----+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 18, 3); + + switch (opcode) { + case OPC_MXU_Q8MOVZ: + /* TODO: Implement emulation of Q8MOVZ instruction. */ + MIPS_INVAL("OPC_MXU_Q8MOVZ"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q8MOVN: + /* TODO: Implement emulation of Q8MOVN instruction. */ + MIPS_INVAL("OPC_MXU_Q8MOVN"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D16MOVZ: + /* TODO: Implement emulation of D16MOVZ instruction. */ + MIPS_INVAL("OPC_MXU_D16MOVZ"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D16MOVN: + /* TODO: Implement emulation of D16MOVN instruction. */ + MIPS_INVAL("OPC_MXU_D16MOVN"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32MOVZ: + /* TODO: Implement emulation of S32MOVZ instruction. */ + MIPS_INVAL("OPC_MXU_S32MOVZ"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32MOVN: + /* TODO: Implement emulation of S32MOVN instruction. */ + MIPS_INVAL("OPC_MXU_S32MOVN"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +/* + * + * Decode MXU pool21 + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21| + * +-----------+---+---+-------+-------+-------+-------+-----------+ + * + */ +static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx) +{ + uint32_t opcode =3D extract32(ctx->opcode, 22, 2); + + switch (opcode) { + case OPC_MXU_Q8MAC: + /* TODO: Implement emulation of Q8MAC instruction. */ + MIPS_INVAL("OPC_MXU_Q8MAC"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q8MACSU: + /* TODO: Implement emulation of Q8MACSU instruction. */ + MIPS_INVAL("OPC_MXU_Q8MACSU"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + + +/* + * Main MXU decoding function + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------------------------------------+-----------+ + * | SPECIAL2 | |x x x x x x| + * +-----------+---------------------------------------+-----------+ + * + */ +static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) +{ + /* + * TODO: Investigate necessity of including handling of + * CLZ, CLO, SDBB in this function, as they belong to + * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs. + */ + uint32_t opcode =3D extract32(ctx->opcode, 0, 6); + + if (opcode =3D=3D OPC__MXU_MUL) { + uint32_t rs, rt, rd, op1; + + rs =3D extract32(ctx->opcode, 21, 5); + rt =3D extract32(ctx->opcode, 16, 5); + rd =3D extract32(ctx->opcode, 11, 5); + op1 =3D MASK_SPECIAL2(ctx->opcode); + + gen_arith(ctx, op1, rd, rs, rt); + + return; + } + + if (opcode =3D=3D OPC_MXU_S32M2I) { + gen_mxu_s32m2i(ctx); + return; + } + + if (opcode =3D=3D OPC_MXU_S32I2M) { + gen_mxu_s32i2m(ctx); + return; + } + + { + TCGv t_mxu_cr =3D tcg_temp_new(); + TCGLabel *l_exit =3D gen_new_label(); + + gen_load_mxu_cr(t_mxu_cr); + tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN); + tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit); + + switch (opcode) { + case OPC_MXU_S32MADD: + /* TODO: Implement emulation of S32MADD instruction. */ + MIPS_INVAL("OPC_MXU_S32MADD"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32MADDU: + /* TODO: Implement emulation of S32MADDU instruction. */ + MIPS_INVAL("OPC_MXU_S32MADDU"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU__POOL00: + decode_opc_mxu__pool00(env, ctx); + break; + case OPC_MXU_S32MSUB: + /* TODO: Implement emulation of S32MSUB instruction. */ + MIPS_INVAL("OPC_MXU_S32MSUB"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32MSUBU: + /* TODO: Implement emulation of S32MSUBU instruction. */ + MIPS_INVAL("OPC_MXU_S32MSUBU"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU__POOL01: + decode_opc_mxu__pool01(env, ctx); + break; + case OPC_MXU__POOL02: + decode_opc_mxu__pool02(env, ctx); + break; + case OPC_MXU_D16MUL: + gen_mxu_d16mul(ctx); + break; + case OPC_MXU__POOL03: + decode_opc_mxu__pool03(env, ctx); + break; + case OPC_MXU_D16MAC: + gen_mxu_d16mac(ctx); + break; + case OPC_MXU_D16MACF: + /* TODO: Implement emulation of D16MACF instruction. */ + MIPS_INVAL("OPC_MXU_D16MACF"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D16MADL: + /* TODO: Implement emulation of D16MADL instruction. */ + MIPS_INVAL("OPC_MXU_D16MADL"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S16MAD: + /* TODO: Implement emulation of S16MAD instruction. */ + MIPS_INVAL("OPC_MXU_S16MAD"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q16ADD: + /* TODO: Implement emulation of Q16ADD instruction. */ + MIPS_INVAL("OPC_MXU_Q16ADD"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D16MACE: + /* TODO: Implement emulation of D16MACE instruction. */ + MIPS_INVAL("OPC_MXU_D16MACE"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU__POOL04: + decode_opc_mxu__pool04(env, ctx); + break; + case OPC_MXU__POOL05: + decode_opc_mxu__pool05(env, ctx); + break; + case OPC_MXU__POOL06: + decode_opc_mxu__pool06(env, ctx); + break; + case OPC_MXU__POOL07: + decode_opc_mxu__pool07(env, ctx); + break; + case OPC_MXU__POOL08: + decode_opc_mxu__pool08(env, ctx); + break; + case OPC_MXU__POOL09: + decode_opc_mxu__pool09(env, ctx); + break; + case OPC_MXU__POOL10: + decode_opc_mxu__pool10(env, ctx); + break; + case OPC_MXU__POOL11: + decode_opc_mxu__pool11(env, ctx); + break; + case OPC_MXU_D32ADD: + /* TODO: Implement emulation of D32ADD instruction. */ + MIPS_INVAL("OPC_MXU_D32ADD"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU__POOL12: + decode_opc_mxu__pool12(env, ctx); + break; + case OPC_MXU__POOL13: + decode_opc_mxu__pool13(env, ctx); + break; + case OPC_MXU__POOL14: + decode_opc_mxu__pool14(env, ctx); + break; + case OPC_MXU_Q8ACCE: + /* TODO: Implement emulation of Q8ACCE instruction. */ + MIPS_INVAL("OPC_MXU_Q8ACCE"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S8LDD: + gen_mxu_s8ldd(ctx); + break; + case OPC_MXU_S8STD: + /* TODO: Implement emulation of S8STD instruction. */ + MIPS_INVAL("OPC_MXU_S8STD"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S8LDI: + /* TODO: Implement emulation of S8LDI instruction. */ + MIPS_INVAL("OPC_MXU_S8LDI"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S8SDI: + /* TODO: Implement emulation of S8SDI instruction. */ + MIPS_INVAL("OPC_MXU_S8SDI"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU__POOL15: + decode_opc_mxu__pool15(env, ctx); + break; + case OPC_MXU__POOL16: + decode_opc_mxu__pool16(env, ctx); + break; + case OPC_MXU__POOL17: + decode_opc_mxu__pool17(env, ctx); + break; + case OPC_MXU_S16LDD: + /* TODO: Implement emulation of S16LDD instruction. */ + MIPS_INVAL("OPC_MXU_S16LDD"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S16STD: + /* TODO: Implement emulation of S16STD instruction. */ + MIPS_INVAL("OPC_MXU_S16STD"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S16LDI: + /* TODO: Implement emulation of S16LDI instruction. */ + MIPS_INVAL("OPC_MXU_S16LDI"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S16SDI: + /* TODO: Implement emulation of S16SDI instruction. */ + MIPS_INVAL("OPC_MXU_S16SDI"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D32SLL: + /* TODO: Implement emulation of D32SLL instruction. */ + MIPS_INVAL("OPC_MXU_D32SLL"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D32SLR: + /* TODO: Implement emulation of D32SLR instruction. */ + MIPS_INVAL("OPC_MXU_D32SLR"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D32SARL: + /* TODO: Implement emulation of D32SARL instruction. */ + MIPS_INVAL("OPC_MXU_D32SARL"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_D32SAR: + /* TODO: Implement emulation of D32SAR instruction. */ + MIPS_INVAL("OPC_MXU_D32SAR"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q16SLL: + /* TODO: Implement emulation of Q16SLL instruction. */ + MIPS_INVAL("OPC_MXU_Q16SLL"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q16SLR: + /* TODO: Implement emulation of Q16SLR instruction. */ + MIPS_INVAL("OPC_MXU_Q16SLR"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU__POOL18: + decode_opc_mxu__pool18(env, ctx); + break; + case OPC_MXU_Q16SAR: + /* TODO: Implement emulation of Q16SAR instruction. */ + MIPS_INVAL("OPC_MXU_Q16SAR"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU__POOL19: + decode_opc_mxu__pool19(env, ctx); + break; + case OPC_MXU__POOL20: + decode_opc_mxu__pool20(env, ctx); + break; + case OPC_MXU__POOL21: + decode_opc_mxu__pool21(env, ctx); + break; + case OPC_MXU_Q16SCOP: + /* TODO: Implement emulation of Q16SCOP instruction. */ + MIPS_INVAL("OPC_MXU_Q16SCOP"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q8MADL: + /* TODO: Implement emulation of Q8MADL instruction. */ + MIPS_INVAL("OPC_MXU_Q8MADL"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_S32SFL: + /* TODO: Implement emulation of S32SFL instruction. */ + MIPS_INVAL("OPC_MXU_S32SFL"); + generate_exception_end(ctx, EXCP_RI); + break; + case OPC_MXU_Q8SAD: + /* TODO: Implement emulation of Q8SAD instruction. */ + MIPS_INVAL("OPC_MXU_Q8SAD"); + generate_exception_end(ctx, EXCP_RI); + break; + default: + MIPS_INVAL("decode_opc_mxu"); + generate_exception_end(ctx, EXCP_RI); + } + + gen_set_label(l_exit); + tcg_temp_free(t_mxu_cr); + } +} + +#endif /* !defined(TARGET_MIPS64) */ + + --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.43 as permitted sender) client-ip=209.85.128.43; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f43.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.43 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906639; cv=none; d=zohomail.com; s=zohoarc; b=d1Qc1u4idIbkhY39osEjw7gChDeuYFN/eolMMOwMnQQ6qSzoi6hL4OvFXo5/rWCZMD5vaYy3dpzGfcHtnWVTBqgXdLfasH3qh50CmbBb41lbuNODP3k6i0H1nMbNFSN/lljfTjxC2oD8VpANWsxicYdboM7UK7E3jZOeOITSriM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906639; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Rm8hYLTL5cania5VITZzWfQieMs0D23dPfzaoPosV3I=; b=HMhzTKPWBkZVkTrczKZSTjhz18Vji0/PmWQVqeBPO/CPjmryyeLe+3JwebMsuPh5xBavbo/IFqrDkF7MAYDzCVGwWvGKD0Mujxg2eYxYFvzQ9VtN65QISFXORyEz0os8qiDfLEsB/x073ZKyOYHxg6YHH02Cow8bdpIXFTlQWdA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.43 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) by mx.zohomail.com with SMTPS id 1605906639455243.4594586529346; Fri, 20 Nov 2020 13:10:39 -0800 (PST) Received: by mail-wm1-f43.google.com with SMTP id h21so11254943wmb.2 for ; Fri, 20 Nov 2020 13:10:38 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id g131sm5857149wma.35.2020.11.20.13.10.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Rm8hYLTL5cania5VITZzWfQieMs0D23dPfzaoPosV3I=; b=aoIfLHmArPUFlfb8IQyDQfmyvkvM7vjFtHFV6CC3bDthy6ZCgN561wVaGoPsX27VTZ u6ySV/6fNwFgbDFl4El5WgDd80YxWwhdCiYc38gKdLBRnw/VlGnHpPLBMrw5XTNLQOZa hwyUV3OGAAm016e7l5T2lcuLM6f7eQrJPUpmYtghGZ8XwwCSq+pebi12cy33Jd+q5zHr 0OBzkGmfySbrGzFfo4+NlOpUN3x62n6qHPQwI2hQmSZcVkHUdsDDiKE1fmKysa7m6P61 h2U8MorLmrN58f8ITmjO3+s8fzUla5PWVBpEjsCaD1P91zincUyNZAQFnpAvM59YmUBy +QmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=Rm8hYLTL5cania5VITZzWfQieMs0D23dPfzaoPosV3I=; b=WDbbwYmLAOgQhn6crk7rmfSAVbe06IfIxrIkdtvX0GB/G2NUZzteokp+P6VbyQ3dBY Z01QDAvp9nJrzIhpm3wSL/m35KGnyQyjh76vvRsRNeNT7idUIcBgMmcInettL0qd5u2C +DQiWEfZcxfafOuE6jJSSDoSQjF7v+dhSdWybN5Oh1nphI6wCxeAU06/VTmfXQdcKWd3 c8oukpQYkRJYsFL2avJMlmkkMROLGBpNlHWX+r9xr+epi9GAtUY3vx65gJ9Fy43PGvwm OmCN54bwAU1/Oyf5IcB+IxXfji9ADSTV3pDdx+ESl40Vz0NlHYC3PGc2Uu9vMxQ2sGG6 Nc4A== X-Gm-Message-State: AOAM533A964ewqiCqmxJ0sBCWHdwNHDbBVMjKrjDDJ/ny43dVekFPJpd clcQfc5aaWh9E2CAWA0UzAI= X-Google-Smtp-Source: ABdhPJxTKACMefaqiPzdHIy+zYI1qEKZk1BrAvic6PRNwPiMFWrFztjZSrix7u7NnFO0kqMIMmk2/w== X-Received: by 2002:a7b:ce0e:: with SMTP id m14mr11632954wmc.111.1605906637583; Fri, 20 Nov 2020 13:10:37 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 21/26] target/mips: Make pipeline 1 multiply opcodes generic Date: Fri, 20 Nov 2020 22:08:39 +0100 Message-Id: <20201120210844.2625602-22-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Special2 multiply opcodes are not specific to Toshiba TX79, and are not part of its multimedia extension. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/translate.c | 75 +++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 0914b89eae6..6b35498dd3d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -330,6 +330,19 @@ enum { OPC_MUL =3D 0x02 | OPC_SPECIAL2, OPC_MSUB =3D 0x04 | OPC_SPECIAL2, OPC_MSUBU =3D 0x05 | OPC_SPECIAL2, + + /* Multiply Instructions for Pipeline 1 */ + OPC_MFHI1 =3D 0x10 | OPC_SPECIAL2, + OPC_MTHI1 =3D 0x11 | OPC_SPECIAL2, + OPC_MFLO1 =3D 0x12 | OPC_SPECIAL2, + OPC_MTLO1 =3D 0x13 | OPC_SPECIAL2, + OPC_MULT1 =3D 0x18 | OPC_SPECIAL2, + OPC_MULTU1 =3D 0x19 | OPC_SPECIAL2, + OPC_DIV1 =3D 0x1A | OPC_SPECIAL2, + OPC_DIVU1 =3D 0x1B | OPC_SPECIAL2, + OPC_MADD1 =3D 0x20 | OPC_SPECIAL2, + OPC_MADDU1 =3D 0x21 | OPC_SPECIAL2, + /* Misc */ OPC_CLZ =3D 0x20 | OPC_SPECIAL2, OPC_CLO =3D 0x21 | OPC_SPECIAL2, @@ -933,21 +946,9 @@ enum { =20 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) enum { - MMI_OPC_MADD =3D 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ - MMI_OPC_MADDU =3D 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU = */ MMI_OPC_PLZCW =3D 0x04 | MMI_OPC_CLASS_MMI, MMI_OPC_CLASS_MMI0 =3D 0x08 | MMI_OPC_CLASS_MMI, MMI_OPC_CLASS_MMI2 =3D 0x09 | MMI_OPC_CLASS_MMI, - MMI_OPC_MFHI1 =3D 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_= MFHI */ - MMI_OPC_MTHI1 =3D 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_= MTHI */ - MMI_OPC_MFLO1 =3D 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_= MFLO */ - MMI_OPC_MTLO1 =3D 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_= MTLO */ - MMI_OPC_MULT1 =3D 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_= MULT */ - MMI_OPC_MULTU1 =3D 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_M= ULTU */ - MMI_OPC_DIV1 =3D 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_= DIV */ - MMI_OPC_DIVU1 =3D 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_= DIVU */ - MMI_OPC_MADD1 =3D 0x20 | MMI_OPC_CLASS_MMI, - MMI_OPC_MADDU1 =3D 0x21 | MMI_OPC_CLASS_MMI, MMI_OPC_CLASS_MMI1 =3D 0x28 | MMI_OPC_CLASS_MMI, MMI_OPC_CLASS_MMI3 =3D 0x29 | MMI_OPC_CLASS_MMI, MMI_OPC_PMFHL =3D 0x30 | MMI_OPC_CLASS_MMI, @@ -3049,26 +3050,26 @@ static void gen_shift(DisasContext *ctx, uint32_t o= pc, /* Copy GPR to and from TX79 HI1/LO1 register. */ static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg) { - if (reg =3D=3D 0 && (opc =3D=3D MMI_OPC_MFHI1 || opc =3D=3D MMI_OPC_MF= LO1)) { + if (reg =3D=3D 0 && (opc =3D=3D OPC_MFHI1 || opc =3D=3D OPC_MFLO1)) { /* Treat as NOP. */ return; } =20 switch (opc) { - case MMI_OPC_MFHI1: + case OPC_MFHI1: tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]); break; - case MMI_OPC_MFLO1: + case OPC_MFLO1: tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]); break; - case MMI_OPC_MTHI1: + case OPC_MTHI1: if (reg !=3D 0) { tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]); } else { tcg_gen_movi_tl(cpu_HI[1], 0); } break; - case MMI_OPC_MTLO1: + case OPC_MTLO1: if (reg !=3D 0) { tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]); } else { @@ -3443,7 +3444,7 @@ static void gen_div1_tx79(DisasContext *ctx, uint32_t= opc, int rs, int rt) gen_load_gpr(t1, rt); =20 switch (opc) { - case MMI_OPC_DIV1: + case OPC_DIV1: { TCGv t2 =3D tcg_temp_new(); TCGv t3 =3D tcg_temp_new(); @@ -3464,7 +3465,7 @@ static void gen_div1_tx79(DisasContext *ctx, uint32_t= opc, int rs, int rt) tcg_temp_free(t2); } break; - case MMI_OPC_DIVU1: + case OPC_DIVU1: { TCGv t2 =3D tcg_const_tl(0); TCGv t3 =3D tcg_const_tl(1); @@ -3719,7 +3720,7 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t = opc, gen_load_gpr(t1, rt); =20 switch (opc) { - case MMI_OPC_MULT1: + case OPC_MULT1: acc =3D 1; /* Fall through */ case OPC_MULT: @@ -3738,7 +3739,7 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t = opc, tcg_temp_free_i32(t3); } break; - case MMI_OPC_MULTU1: + case OPC_MULTU1: acc =3D 1; /* Fall through */ case OPC_MULTU: @@ -3757,10 +3758,10 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_= t opc, tcg_temp_free_i32(t3); } break; - case MMI_OPC_MADD1: + case OPC_MADD1: acc =3D 1; /* Fall through */ - case MMI_OPC_MADD: + case OPC_MADD: { TCGv_i64 t2 =3D tcg_temp_new_i64(); TCGv_i64 t3 =3D tcg_temp_new_i64(); @@ -3779,10 +3780,10 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_= t opc, tcg_temp_free_i64(t2); } break; - case MMI_OPC_MADDU1: + case OPC_MADDU1: acc =3D 1; /* Fall through */ - case MMI_OPC_MADDU: + case OPC_MADDU: { TCGv_i64 t2 =3D tcg_temp_new_i64(); TCGv_i64 t3 =3D tcg_temp_new_i64(); @@ -12741,24 +12742,24 @@ static void decode_mmi(CPUMIPSState *env, DisasCo= ntext *ctx) case MMI_OPC_CLASS_MMI3: decode_mmi3(env, ctx); break; - case MMI_OPC_MULT1: - case MMI_OPC_MULTU1: - case MMI_OPC_MADD: - case MMI_OPC_MADDU: - case MMI_OPC_MADD1: - case MMI_OPC_MADDU1: + case OPC_MULT1: + case OPC_MULTU1: + case OPC_MADD: + case OPC_MADDU: + case OPC_MADD1: + case OPC_MADDU1: gen_mul_txx9(ctx, opc, rd, rs, rt); break; - case MMI_OPC_DIV1: - case MMI_OPC_DIVU1: + case OPC_DIV1: + case OPC_DIVU1: gen_div1_tx79(ctx, opc, rs, rt); break; - case MMI_OPC_MTLO1: - case MMI_OPC_MTHI1: + case OPC_MTLO1: + case OPC_MTHI1: gen_HILO1_tx79(ctx, opc, rs); break; - case MMI_OPC_MFLO1: - case MMI_OPC_MFHI1: + case OPC_MFLO1: + case OPC_MFHI1: gen_HILO1_tx79(ctx, opc, rd); break; case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */ --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.48 as permitted sender) client-ip=209.85.128.48; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f48.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.48 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906645; cv=none; d=zohomail.com; s=zohoarc; b=S6nVOAvYYO3dvY+rFxOw4NSV4mB8dg3M9e1pdt6XLLNqslNA5x7FKMPnsGsLIaOAEVZ4QDqI3CX5KEIyW2IXHPY9r2JHo1LW3uRk3AcWtWbsZ/9NED5Di4htibRevnPN+WqFKXe4YwRCL9PATxGMK9vDuW/5ZUS9YYUDxRKfsog= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906645; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=WVddlHHp5p37eCkU7NTnbc/InwYZaLbhrydicBuAWhI=; b=faLIc3nAAR960mXTK6VgrAHvspCKJuZRYhKmPAjxaqqhbV2DQ2d7VLS+G64M/VJw7kCmA0m20H20pFWoYIrS/N8Jsr3U5jG0LMMyOAxFdlhu+NXl1BmtTzIvrJNBnxtPCmNdx4mpBY6f8so9wDbNgziAean5uGQvnyikACQ00mA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.48 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) by mx.zohomail.com with SMTPS id 1605906645459178.31249529433376; Fri, 20 Nov 2020 13:10:45 -0800 (PST) Received: by mail-wm1-f48.google.com with SMTP id s13so11250707wmh.4 for ; Fri, 20 Nov 2020 13:10:44 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id f16sm6339233wrp.66.2020.11.20.13.10.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WVddlHHp5p37eCkU7NTnbc/InwYZaLbhrydicBuAWhI=; b=c22SCDDvEouppyosM+ZG9RhfGpGLyxWi43vhxwkcj6+UmdVJjQKWXMfSfTPhcL+FgM uH9/5XdCXc/58UmmABhDVeh0ED6M0CKoDlkDGCt0dNktdK722+NKXlGXZk8efknKRB1z B0EB9t9jXwmiMpXfKu9CKZekjtQrlBhcmlua+lp+NCAPy4r9an5GqFGx+orP4LAujqPv lH6Ut6YTuiZe9h8hOvkpFUYm24vKixe4fpZQ5hvAHRHpH8B/KnDUWhlU8scF2H9SsqGW Gg3A8/3Pq/2q4S74PM44YXmeCB+9svdybfLWmACFl5crOskDEFzoN1dfrvC5CxpGlZuA reWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=WVddlHHp5p37eCkU7NTnbc/InwYZaLbhrydicBuAWhI=; b=DIqDtbAeZyN7ETy6oN8M7YAhQ4f3Lh4DHhTXA/AyaDIyAhBWxHhozFu53slndNIYw3 6JaEExISzCprkfMw7HgwXgC4V2bnHrgj0dYkkO/jqtqChv63WMMI3P8UwaLD1bUZ0z0V JEqTmoUK8ouPGYDiZYoFE7ImRqd7iEhahwW/0zUp7jDEPmjXlDHOSW8E8sOOjouXSsYi wW3+i3zB638d71ekQru+hofGtQwA16yffGvBTKS4ojANkLzcXGQQtZ4Ms+IP/SS6PJ4G ay0GtwuuVInRAw9iE8Hj+4EHo7ncwxjYQacAX53r9miUN1FFz4LS8SSOeKqRX7oCGU2Q 35VQ== X-Gm-Message-State: AOAM532zIpjj5HWAFpv1PUcK+J6i43RWRjnZ87WIvlOvAMvk1Qb1OE41 e8guVY1MXWTH3YSNkqKdGwI= X-Google-Smtp-Source: ABdhPJw2eJoC7eeYwrj4PuAisqceNTw/VRIok/z3kUn61Rtrom6lQhWmi9su7f+ouyJ4k0WYVOvYmQ== X-Received: by 2002:a1c:964d:: with SMTP id y74mr11476220wmd.129.1605906643249; Fri, 20 Nov 2020 13:10:43 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 22/26] target/mips: Extract Toshiba TXx9 translation routines Date: Fri, 20 Nov 2020 22:08:40 +0100 Message-Id: <20201120210844.2625602-23-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract 300 lines of the Toshiba TX19/TX39/TX49/TX79 translation routines to 'vendor-tx_translate.c.inc'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/translate.c | 302 +----------------------- target/mips/vendor-tx_translate.c.inc | 315 ++++++++++++++++++++++++++ 2 files changed, 316 insertions(+), 301 deletions(-) create mode 100644 target/mips/vendor-tx_translate.c.inc diff --git a/target/mips/translate.c b/target/mips/translate.c index 6b35498dd3d..a1cf1fe7f23 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -730,31 +730,6 @@ enum { * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit * or sixteen 8-bit paths. * - * Reference: - * - * The Toshiba TX System RISC TX79 Core Architecture manual, - * https://wiki.qemu.org/File:C790.pdf - * - * Three-Operand Multiply and Multiply-Add (4 instructions) - * -------------------------------------------------------- - * MADD [rd,] rs, rt Multiply/Add - * MADDU [rd,] rs, rt Multiply/Add Unsigned - * MULT [rd,] rs, rt Multiply (3-operand) - * MULTU [rd,] rs, rt Multiply Unsigned (3-operand) - * - * Multiply Instructions for Pipeline 1 (10 instructions) - * ------------------------------------------------------ - * MULT1 [rd,] rs, rt Multiply Pipeline 1 - * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1 - * DIV1 rs, rt Divide Pipeline 1 - * DIVU1 rs, rt Divide Unsigned Pipeline 1 - * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1 - * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1 - * MFHI1 rd Move From HI1 Register - * MFLO1 rd Move From LO1 Register - * MTHI1 rs Move To HI1 Register - * MTLO1 rs Move To LO1 Register - * * Arithmetic (19 instructions) * ---------------------------- * PADDB rd, rs, rt Parallel Add Byte @@ -3046,44 +3021,6 @@ static void gen_shift(DisasContext *ctx, uint32_t op= c, tcg_temp_free(t1); } =20 -#if defined(TARGET_MIPS64) -/* Copy GPR to and from TX79 HI1/LO1 register. */ -static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg) -{ - if (reg =3D=3D 0 && (opc =3D=3D OPC_MFHI1 || opc =3D=3D OPC_MFLO1)) { - /* Treat as NOP. */ - return; - } - - switch (opc) { - case OPC_MFHI1: - tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]); - break; - case OPC_MFLO1: - tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]); - break; - case OPC_MTHI1: - if (reg !=3D 0) { - tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]); - } else { - tcg_gen_movi_tl(cpu_HI[1], 0); - } - break; - case OPC_MTLO1: - if (reg !=3D 0) { - tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]); - } else { - tcg_gen_movi_tl(cpu_LO[1], 0); - } - break; - default: - MIPS_INVAL("mfthilo1 TX79"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} -#endif - /* Arithmetic on HI/LO registers */ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) { @@ -3432,65 +3369,6 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc= , int rd, int rs, int rt) tcg_temp_free(t1); } =20 -#if defined(TARGET_MIPS64) -static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) -{ - TCGv t0, t1; - - t0 =3D tcg_temp_new(); - t1 =3D tcg_temp_new(); - - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - - switch (opc) { - case OPC_DIV1: - { - TCGv t2 =3D tcg_temp_new(); - TCGv t3 =3D tcg_temp_new(); - tcg_gen_ext32s_tl(t0, t0); - tcg_gen_ext32s_tl(t1, t1); - tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); - tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); - tcg_gen_and_tl(t2, t2, t3); - tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); - tcg_gen_or_tl(t2, t2, t3); - tcg_gen_movi_tl(t3, 0); - tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); - tcg_gen_div_tl(cpu_LO[1], t0, t1); - tcg_gen_rem_tl(cpu_HI[1], t0, t1); - tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); - tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); - tcg_temp_free(t3); - tcg_temp_free(t2); - } - break; - case OPC_DIVU1: - { - TCGv t2 =3D tcg_const_tl(0); - TCGv t3 =3D tcg_const_tl(1); - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_ext32u_tl(t1, t1); - tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); - tcg_gen_divu_tl(cpu_LO[1], t0, t1); - tcg_gen_remu_tl(cpu_HI[1], t0, t1); - tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); - tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); - tcg_temp_free(t3); - tcg_temp_free(t2); - } - break; - default: - MIPS_INVAL("div1 TX79"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - out: - tcg_temp_free(t0); - tcg_temp_free(t1); -} -#endif - static void gen_muldiv(DisasContext *ctx, uint32_t opc, int acc, int rs, int rt) { @@ -3683,138 +3561,6 @@ static void gen_muldiv(DisasContext *ctx, uint32_t = opc, tcg_temp_free(t1); } =20 -/* - * These MULT[U] and MADD[U] instructions implemented in for example - * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core - * architectures are special three-operand variants with the syntax - * - * MULT[U][1] rd, rs, rt - * - * such that - * - * (rd, LO, HI) <- rs * rt - * - * and - * - * MADD[U][1] rd, rs, rt - * - * such that - * - * (rd, LO, HI) <- (LO, HI) + rs * rt - * - * where the low-order 32-bits of the result is placed into both the - * GPR rd and the special register LO. The high-order 32-bits of the - * result is placed into the special register HI. - * - * If the GPR rd is omitted in assembly language, it is taken to be 0, - * which is the zero register that always reads as 0. - */ -static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, - int rd, int rs, int rt) -{ - TCGv t0 =3D tcg_temp_new(); - TCGv t1 =3D tcg_temp_new(); - int acc =3D 0; - - gen_load_gpr(t0, rs); - gen_load_gpr(t1, rt); - - switch (opc) { - case OPC_MULT1: - acc =3D 1; - /* Fall through */ - case OPC_MULT: - { - TCGv_i32 t2 =3D tcg_temp_new_i32(); - TCGv_i32 t3 =3D tcg_temp_new_i32(); - tcg_gen_trunc_tl_i32(t2, t0); - tcg_gen_trunc_tl_i32(t3, t1); - tcg_gen_muls2_i32(t2, t3, t2, t3); - if (rd) { - tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); - } - tcg_gen_ext_i32_tl(cpu_LO[acc], t2); - tcg_gen_ext_i32_tl(cpu_HI[acc], t3); - tcg_temp_free_i32(t2); - tcg_temp_free_i32(t3); - } - break; - case OPC_MULTU1: - acc =3D 1; - /* Fall through */ - case OPC_MULTU: - { - TCGv_i32 t2 =3D tcg_temp_new_i32(); - TCGv_i32 t3 =3D tcg_temp_new_i32(); - tcg_gen_trunc_tl_i32(t2, t0); - tcg_gen_trunc_tl_i32(t3, t1); - tcg_gen_mulu2_i32(t2, t3, t2, t3); - if (rd) { - tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); - } - tcg_gen_ext_i32_tl(cpu_LO[acc], t2); - tcg_gen_ext_i32_tl(cpu_HI[acc], t3); - tcg_temp_free_i32(t2); - tcg_temp_free_i32(t3); - } - break; - case OPC_MADD1: - acc =3D 1; - /* Fall through */ - case OPC_MADD: - { - TCGv_i64 t2 =3D tcg_temp_new_i64(); - TCGv_i64 t3 =3D tcg_temp_new_i64(); - - tcg_gen_ext_tl_i64(t2, t0); - tcg_gen_ext_tl_i64(t3, t1); - tcg_gen_mul_i64(t2, t2, t3); - tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); - tcg_gen_add_i64(t2, t2, t3); - tcg_temp_free_i64(t3); - gen_move_low32(cpu_LO[acc], t2); - gen_move_high32(cpu_HI[acc], t2); - if (rd) { - gen_move_low32(cpu_gpr[rd], t2); - } - tcg_temp_free_i64(t2); - } - break; - case OPC_MADDU1: - acc =3D 1; - /* Fall through */ - case OPC_MADDU: - { - TCGv_i64 t2 =3D tcg_temp_new_i64(); - TCGv_i64 t3 =3D tcg_temp_new_i64(); - - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_ext32u_tl(t1, t1); - tcg_gen_extu_tl_i64(t2, t0); - tcg_gen_extu_tl_i64(t3, t1); - tcg_gen_mul_i64(t2, t2, t3); - tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); - tcg_gen_add_i64(t2, t2, t3); - tcg_temp_free_i64(t3); - gen_move_low32(cpu_LO[acc], t2); - gen_move_high32(cpu_HI[acc], t2); - if (rd) { - gen_move_low32(cpu_gpr[rd], t2); - } - tcg_temp_free_i64(t2); - } - break; - default: - MIPS_INVAL("mul/madd TXx9"); - generate_exception_end(ctx, EXCP_RI); - goto out; - } - - out: - tcg_temp_free(t0); - tcg_temp_free(t1); -} - static void gen_cl(DisasContext *ctx, uint32_t opc, int rd, int rs) { @@ -11247,6 +10993,7 @@ out: #include "mod-mips-dsp_translate.c.inc" =20 #include "vendor-vr54xx_translate.c.inc" +#include "vendor-tx_translate.c.inc" #include "vendor-loong-simd_translate.c.inc" #include "vendor-loong-lext_translate.c.inc" #include "vendor-xburst_translate.c.inc" @@ -11365,53 +11112,6 @@ static void decode_opc_special_r6(CPUMIPSState *en= v, DisasContext *ctx) } } =20 -static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) -{ - int rs =3D extract32(ctx->opcode, 21, 5); - int rt =3D extract32(ctx->opcode, 16, 5); - int rd =3D extract32(ctx->opcode, 11, 5); - uint32_t op1 =3D MASK_SPECIAL(ctx->opcode); - - switch (op1) { - case OPC_MOVN: /* Conditional move */ - case OPC_MOVZ: - gen_cond_move(ctx, op1, rd, rs, rt); - break; - case OPC_MFHI: /* Move from HI/LO */ - case OPC_MFLO: - gen_HILO(ctx, op1, 0, rd); - break; - case OPC_MTHI: - case OPC_MTLO: /* Move to HI/LO */ - gen_HILO(ctx, op1, 0, rs); - break; - case OPC_MULT: - case OPC_MULTU: - gen_mul_txx9(ctx, op1, rd, rs, rt); - break; - case OPC_DIV: - case OPC_DIVU: - gen_muldiv(ctx, op1, 0, rs, rt); - break; -#if defined(TARGET_MIPS64) - case OPC_DMULT: - case OPC_DMULTU: - case OPC_DDIV: - case OPC_DDIVU: - check_insn_opc_user_only(ctx, INSN_R5900); - gen_muldiv(ctx, op1, 0, rs, rt); - break; -#endif - case OPC_JR: - gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); - break; - default: /* Invalid */ - MIPS_INVAL("special_tx79"); - generate_exception_end(ctx, EXCP_RI); - break; - } -} - static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) { int rs, rt, rd, sa; diff --git a/target/mips/vendor-tx_translate.c.inc b/target/mips/vendor-tx_= translate.c.inc new file mode 100644 index 00000000000..1d157743bd4 --- /dev/null +++ b/target/mips/vendor-tx_translate.c.inc @@ -0,0 +1,315 @@ +/* + * Toshiba TX instruction translation routines. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * Overview of the TX79-specific instruction set + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + * + * Reference: + * + * The Toshiba TX System RISC TX79 Core Architecture manual, + * https://wiki.qemu.org/File:C790.pdf + * + * Three-Operand Multiply and Multiply-Add (4 instructions) + * -------------------------------------------------------- + * MADD [rd,] rs, rt Multiply/Add + * MADDU [rd,] rs, rt Multiply/Add Unsigned + * MULT [rd,] rs, rt Multiply (3-operand) + * MULTU [rd,] rs, rt Multiply Unsigned (3-operand) + * + * Multiply Instructions for Pipeline 1 (10 instructions) + * ------------------------------------------------------ + * MULT1 [rd,] rs, rt Multiply Pipeline 1 + * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1 + * DIV1 rs, rt Divide Pipeline 1 + * DIVU1 rs, rt Divide Unsigned Pipeline 1 + * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1 + * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1 + * MFHI1 rd Move From HI1 Register + * MFLO1 rd Move From LO1 Register + * MTHI1 rs Move To HI1 Register + * MTLO1 rs Move To LO1 Register + * + */ + +#if defined(TARGET_MIPS64) + +/* Copy GPR to and from TX79 HI1/LO1 register. */ +static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg) +{ + if (reg =3D=3D 0 && (opc =3D=3D OPC_MFHI1 || opc =3D=3D OPC_MFLO1)) { + /* Treat as NOP. */ + return; + } + + switch (opc) { + case OPC_MFHI1: + tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]); + break; + case OPC_MFLO1: + tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]); + break; + case OPC_MTHI1: + if (reg !=3D 0) { + tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]); + } else { + tcg_gen_movi_tl(cpu_HI[1], 0); + } + break; + case OPC_MTLO1: + if (reg !=3D 0) { + tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]); + } else { + tcg_gen_movi_tl(cpu_LO[1], 0); + } + break; + default: + MIPS_INVAL("mfthilo1 TX79"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} + +static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) +{ + TCGv t0, t1; + + t0 =3D tcg_temp_new(); + t1 =3D tcg_temp_new(); + + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + + switch (opc) { + case OPC_DIV1: + { + TCGv t2 =3D tcg_temp_new(); + TCGv t3 =3D tcg_temp_new(); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); + tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); + tcg_gen_and_tl(t2, t2, t3); + tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); + tcg_gen_or_tl(t2, t2, t3); + tcg_gen_movi_tl(t3, 0); + tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); + tcg_gen_div_tl(cpu_LO[1], t0, t1); + tcg_gen_rem_tl(cpu_HI[1], t0, t1); + tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); + tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); + tcg_temp_free(t3); + tcg_temp_free(t2); + } + break; + case OPC_DIVU1: + { + TCGv t2 =3D tcg_const_tl(0); + TCGv t3 =3D tcg_const_tl(1); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); + tcg_gen_divu_tl(cpu_LO[1], t0, t1); + tcg_gen_remu_tl(cpu_HI[1], t0, t1); + tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); + tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); + tcg_temp_free(t3); + tcg_temp_free(t2); + } + break; + default: + MIPS_INVAL("div1 TX79"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + out: + tcg_temp_free(t0); + tcg_temp_free(t1); +} +#endif + +/* + * These MULT[U] and MADD[U] instructions implemented in for example + * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core + * architectures are special three-operand variants with the syntax + * + * MULT[U][1] rd, rs, rt + * + * such that + * + * (rd, LO, HI) <- rs * rt + * + * and + * + * MADD[U][1] rd, rs, rt + * + * such that + * + * (rd, LO, HI) <- (LO, HI) + rs * rt + * + * where the low-order 32-bits of the result is placed into both the + * GPR rd and the special register LO. The high-order 32-bits of the + * result is placed into the special register HI. + * + * If the GPR rd is omitted in assembly language, it is taken to be 0, + * which is the zero register that always reads as 0. + */ +static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, + int rd, int rs, int rt) +{ + TCGv t0 =3D tcg_temp_new(); + TCGv t1 =3D tcg_temp_new(); + int acc =3D 0; + + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); + + switch (opc) { + case OPC_MULT1: + acc =3D 1; + /* Fall through */ + case OPC_MULT: + { + TCGv_i32 t2 =3D tcg_temp_new_i32(); + TCGv_i32 t3 =3D tcg_temp_new_i32(); + tcg_gen_trunc_tl_i32(t2, t0); + tcg_gen_trunc_tl_i32(t3, t1); + tcg_gen_muls2_i32(t2, t3, t2, t3); + if (rd) { + tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); + } + tcg_gen_ext_i32_tl(cpu_LO[acc], t2); + tcg_gen_ext_i32_tl(cpu_HI[acc], t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t3); + } + break; + case OPC_MULTU1: + acc =3D 1; + /* Fall through */ + case OPC_MULTU: + { + TCGv_i32 t2 =3D tcg_temp_new_i32(); + TCGv_i32 t3 =3D tcg_temp_new_i32(); + tcg_gen_trunc_tl_i32(t2, t0); + tcg_gen_trunc_tl_i32(t3, t1); + tcg_gen_mulu2_i32(t2, t3, t2, t3); + if (rd) { + tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); + } + tcg_gen_ext_i32_tl(cpu_LO[acc], t2); + tcg_gen_ext_i32_tl(cpu_HI[acc], t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t3); + } + break; + case OPC_MADD1: + acc =3D 1; + /* Fall through */ + case OPC_MADD: + { + TCGv_i64 t2 =3D tcg_temp_new_i64(); + TCGv_i64 t3 =3D tcg_temp_new_i64(); + + tcg_gen_ext_tl_i64(t2, t0); + tcg_gen_ext_tl_i64(t3, t1); + tcg_gen_mul_i64(t2, t2, t3); + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); + tcg_gen_add_i64(t2, t2, t3); + tcg_temp_free_i64(t3); + gen_move_low32(cpu_LO[acc], t2); + gen_move_high32(cpu_HI[acc], t2); + if (rd) { + gen_move_low32(cpu_gpr[rd], t2); + } + tcg_temp_free_i64(t2); + } + break; + case OPC_MADDU1: + acc =3D 1; + /* Fall through */ + case OPC_MADDU: + { + TCGv_i64 t2 =3D tcg_temp_new_i64(); + TCGv_i64 t3 =3D tcg_temp_new_i64(); + + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_extu_tl_i64(t2, t0); + tcg_gen_extu_tl_i64(t3, t1); + tcg_gen_mul_i64(t2, t2, t3); + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); + tcg_gen_add_i64(t2, t2, t3); + tcg_temp_free_i64(t3); + gen_move_low32(cpu_LO[acc], t2); + gen_move_high32(cpu_HI[acc], t2); + if (rd) { + gen_move_low32(cpu_gpr[rd], t2); + } + tcg_temp_free_i64(t2); + } + break; + default: + MIPS_INVAL("mul/madd TXx9"); + generate_exception_end(ctx, EXCP_RI); + goto out; + } + + out: + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) +{ + int rs =3D extract32(ctx->opcode, 21, 5); + int rt =3D extract32(ctx->opcode, 16, 5); + int rd =3D extract32(ctx->opcode, 11, 5); + uint32_t op1 =3D MASK_SPECIAL(ctx->opcode); + + switch (op1) { + case OPC_MOVN: /* Conditional move */ + case OPC_MOVZ: + gen_cond_move(ctx, op1, rd, rs, rt); + break; + case OPC_MFHI: /* Move from HI/LO */ + case OPC_MFLO: + gen_HILO(ctx, op1, 0, rd); + break; + case OPC_MTHI: + case OPC_MTLO: /* Move to HI/LO */ + gen_HILO(ctx, op1, 0, rs); + break; + case OPC_MULT: + case OPC_MULTU: + gen_mul_txx9(ctx, op1, rd, rs, rt); + break; + case OPC_DIV: + case OPC_DIVU: + gen_muldiv(ctx, op1, 0, rs, rt); + break; +#if defined(TARGET_MIPS64) + case OPC_DMULT: + case OPC_DMULTU: + case OPC_DDIV: + case OPC_DDIVU: + check_insn_opc_user_only(ctx, INSN_R5900); + gen_muldiv(ctx, op1, 0, rs, rt); + break; +#endif + case OPC_JR: + gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); + break; + default: /* Invalid */ + MIPS_INVAL("special_tx79"); + generate_exception_end(ctx, EXCP_RI); + break; + } +} --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.51 as permitted sender) client-ip=209.85.221.51; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f51.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.51 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail(p=none dis=none) header.from=amsat.org ARC-Seal: i=1; a=rsa-sha256; t=1605906651; cv=none; d=zohomail.com; s=zohoarc; b=D7QXAMqzrzee+FB7ChvtygDBKvT9z4OKFpdpCrSWqJ+r79LECQ2z2vFYjwag1Lnv+sPuZX0+/z1w7wkjJKjrLwV133kYtPrn/QV1wqQGt/DBGidZAfwkpkB0S29u30fkyTdjLYxnKHsdReQ40BMeCZZMhSyG73wty7q5IhHr8Ck= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906651; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=SJ5WrYDZYS+2JUUdA5Q+wdGcJ86nhJimA4y57aYU1AM=; b=l0xZnKL/bCjIV/sNKXqjEvC9h2D0APF1dA/R1hiePaqwJDK1+gTwdwUEHv8UhOk/1i3/Y8N0UBGh/UPNWNwPSWO8yyvVbpu/U87LOUr27I+nae+UKUTL7fSa49tqSdAlzHBtUNwqLfeT+J4sKlGFmKfLVByOM051MGfZRuYx5cc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.51 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) by mx.zohomail.com with SMTPS id 1605906651169904.6703087962122; Fri, 20 Nov 2020 13:10:51 -0800 (PST) Received: by mail-wr1-f51.google.com with SMTP id s8so11671592wrw.10 for ; Fri, 20 Nov 2020 13:10:50 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id b124sm5405140wmh.13.2020.11.20.13.10.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SJ5WrYDZYS+2JUUdA5Q+wdGcJ86nhJimA4y57aYU1AM=; b=O1VZU1FhDEGiy1WM5k4vI8nW1BUxVVfHMkWiMmjM2n1s+jERUhYeo078nRA32Yaja8 u1YlN0CK58mJ8Ug44diLZ1Qh4rMmf915fhkztgzmBp4KmQALsW/2KMjNH8w/lIhGIY0X ghTJ+WWXu/qAghumEioSJYwrKwYRCjW/TGn1c9OpH5OwEbRITp4s2DHfybZPWg6dSjhA 7W5/d86NReQ0yFEnODjBGBs+J7SFMgyGDY97290eIUpNs+4YtIxpdim3y0tZRE/M8Kbn VdBtSYHq53dj15GM0VsX9ARzHKL+ikQL4oEX9sLvmjKReGicuPUP//HDULMZuElg1cv8 kbgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=SJ5WrYDZYS+2JUUdA5Q+wdGcJ86nhJimA4y57aYU1AM=; b=rGSrYFRmaAcF4EkCiDLbC8ApTndLFNqQfg0xRP/zKyUBxbNnJggm5VVDrA6bo+UTCm ShEl8TggLpLgwJuKn8v6XYDRyqxZf2vFjB301rqj0O29y9wch4cjHa9ggr4V1RHQDSLT a5Zml4XwSIE81Cm+YkAxdbK+dWGVjLakAdhzrWXMnBNHLrE6j5mR/oJ8udB64cuHAsUl HebNJ0Nu76/tq+38jkAGhqRdp06ksqgllhkPq5QyTgMxrEm7Jhv5UseeSSoJJnCCSZLB m+DohmNmg3QYBA+4/3RCvn76BZ+dCrZGap6utqube2J83FKL5c03gzzJ+46dNZa4Cc3I ZXeA== X-Gm-Message-State: AOAM5307r5jfwJa6p15IRfXeEcRAcZJkGAAlzateT+JM/MykWNCLsl9G KOphSpGy9GhimTueGKo2t2E= X-Google-Smtp-Source: ABdhPJwQO9Q7UYFaKc8x5VmaRum5+EfGPVTSoMi3f/tbnaDL2rtvmcrzqhZ9BxzzP1QFxhshIeDYsA== X-Received: by 2002:a5d:4d86:: with SMTP id b6mr17803677wru.369.1605906648792; Fri, 20 Nov 2020 13:10:48 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 23/26] target/mips: Extract Toshiba TX79 multimedia translation routines Date: Fri, 20 Nov 2020 22:08:41 +0100 Message-Id: <20201120210844.2625602-24-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Extract 600 lines of the the Toshiba TX79 multimedia translation routines to 'vendor-tx-mmi_translate.c.inc'. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/mips/translate.c | 567 --------------------- target/mips/vendor-tx-mmi_translate.c.inc | 573 ++++++++++++++++++++++ target/mips/vendor-tx_translate.c.inc | 2 + 3 files changed, 575 insertions(+), 567 deletions(-) create mode 100644 target/mips/vendor-tx-mmi_translate.c.inc diff --git a/target/mips/translate.c b/target/mips/translate.c index a1cf1fe7f23..57e82079c50 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -719,405 +719,6 @@ enum { OPC_NMSUB_PS =3D 0x3E | OPC_CP3, }; =20 - -/* - * Overview of the TX79-specific instruction set - * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - * - * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits - * are only used by the specific quadword (128-bit) LQ/SQ load/store - * instructions and certain multimedia instructions (MMIs). These MMIs - * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit - * or sixteen 8-bit paths. - * - * Arithmetic (19 instructions) - * ---------------------------- - * PADDB rd, rs, rt Parallel Add Byte - * PSUBB rd, rs, rt Parallel Subtract Byte - * PADDH rd, rs, rt Parallel Add Halfword - * PSUBH rd, rs, rt Parallel Subtract Halfword - * PADDW rd, rs, rt Parallel Add Word - * PSUBW rd, rs, rt Parallel Subtract Word - * PADSBH rd, rs, rt Parallel Add/Subtract Halfword - * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte - * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte - * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword - * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Half= word - * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word - * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word - * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte - * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation By= te - * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword - * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Ha= lfword - * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word - * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Wo= rd - * - * Min/Max (4 instructions) - * ------------------------ - * PMAXH rd, rs, rt Parallel Maximum Halfword - * PMINH rd, rs, rt Parallel Minimum Halfword - * PMAXW rd, rs, rt Parallel Maximum Word - * PMINW rd, rs, rt Parallel Minimum Word - * - * Absolute (2 instructions) - * ------------------------- - * PABSH rd, rt Parallel Absolute Halfword - * PABSW rd, rt Parallel Absolute Word - * - * Logical (4 instructions) - * ------------------------ - * PAND rd, rs, rt Parallel AND - * POR rd, rs, rt Parallel OR - * PXOR rd, rs, rt Parallel XOR - * PNOR rd, rs, rt Parallel NOR - * - * Shift (9 instructions) - * ---------------------- - * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword - * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword - * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword - * PSLLW rd, rt, sa Parallel Shift Left Logical Word - * PSRLW rd, rt, sa Parallel Shift Right Logical Word - * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word - * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word - * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word - * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word - * - * Compare (6 instructions) - * ------------------------ - * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte - * PCEQB rd, rs, rt Parallel Compare for Equal Byte - * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword - * PCEQH rd, rs, rt Parallel Compare for Equal Halfword - * PCGTW rd, rs, rt Parallel Compare for Greater Than Word - * PCEQW rd, rs, rt Parallel Compare for Equal Word - * - * LZC (1 instruction) - * ------------------- - * PLZCW rd, rs Parallel Leading Zero or One Count Word - * - * Quadword Load and Store (2 instructions) - * ---------------------------------------- - * LQ rt, offset(base) Load Quadword - * SQ rt, offset(base) Store Quadword - * - * Multiply and Divide (19 instructions) - * ------------------------------------- - * PMULTW rd, rs, rt Parallel Multiply Word - * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word - * PDIVW rs, rt Parallel Divide Word - * PDIVUW rs, rt Parallel Divide Unsigned Word - * PMADDW rd, rs, rt Parallel Multiply-Add Word - * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word - * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word - * PMULTH rd, rs, rt Parallel Multiply Halfword - * PMADDH rd, rs, rt Parallel Multiply-Add Halfword - * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword - * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword - * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword - * PDIVBW rs, rt Parallel Divide Broadcast Word - * PMFHI rd Parallel Move From HI Register - * PMFLO rd Parallel Move From LO Register - * PMTHI rs Parallel Move To HI Register - * PMTLO rs Parallel Move To LO Register - * PMFHL rd Parallel Move From HI/LO Register - * PMTHL rs Parallel Move To HI/LO Register - * - * Pack/Extend (11 instructions) - * ----------------------------- - * PPAC5 rd, rt Parallel Pack to 5 bits - * PPACB rd, rs, rt Parallel Pack to Byte - * PPACH rd, rs, rt Parallel Pack to Halfword - * PPACW rd, rs, rt Parallel Pack to Word - * PEXT5 rd, rt Parallel Extend Upper from 5 bits - * PEXTUB rd, rs, rt Parallel Extend Upper from Byte - * PEXTLB rd, rs, rt Parallel Extend Lower from Byte - * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword - * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword - * PEXTUW rd, rs, rt Parallel Extend Upper from Word - * PEXTLW rd, rs, rt Parallel Extend Lower from Word - * - * Others (16 instructions) - * ------------------------ - * PCPYH rd, rt Parallel Copy Halfword - * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword - * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword - * PREVH rd, rt Parallel Reverse Halfword - * PINTH rd, rs, rt Parallel Interleave Halfword - * PINTEH rd, rs, rt Parallel Interleave Even Halfword - * PEXEH rd, rt Parallel Exchange Even Halfword - * PEXCH rd, rt Parallel Exchange Center Halfword - * PEXEW rd, rt Parallel Exchange Even Word - * PEXCW rd, rt Parallel Exchange Center Word - * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable - * MFSA rd Move from Shift Amount Register - * MTSA rs Move to Shift Amount Register - * MTSAB rs, immediate Move Byte Count to Shift Amount Register - * MTSAH rs, immediate Move Halfword Count to Shift Amount Register - * PROT3W rd, rt Parallel Rotate 3 Words - * - * MMI (MultiMedia Instruction) encodings - * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - * - * MMI instructions encoding table keys: - * - * * This code is reserved for future use. An attempt to execute it - * causes a Reserved Instruction exception. - * % This code indicates an instruction class. The instruction word - * must be further decoded by examining additional tables that show - * the values for other instruction fields. - * # This code is reserved for the unsupported instructions DMULT, - * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt - * to execute it causes a Reserved Instruction exception. - * - * MMI instructions encoded by opcode field (MMI, LQ, SQ): - * - * 31 26 0 - * +--------+----------------------------------------+ - * | opcode | | - * +--------+----------------------------------------+ - * - * opcode bits 28..26 - * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 - * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 - * -------+-------+-------+-------+-------+-------+-------+-------+-----= -- - * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ - * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI - * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL - * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ - * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU - * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE - * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD - * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD - */ - -enum { - MMI_OPC_CLASS_MMI =3D 0x1C << 26, /* Same as OPC_SPECIAL2 */ - MMI_OPC_LQ =3D 0x1E << 26, /* Same as OPC_MSA */ - MMI_OPC_SQ =3D 0x1F << 26, /* Same as OPC_SPECIAL3 */ -}; - -/* - * MMI instructions with opcode field =3D MMI: - * - * 31 26 5 0 - * +--------+-------------------------------+--------+ - * | MMI | |function| - * +--------+-------------------------------+--------+ - * - * function bits 2..0 - * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 - * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 - * -------+-------+-------+-------+-------+-------+-------+-------+-----= -- - * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * - * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * - * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * - * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * - * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * - * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * - * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH - * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW - */ - -#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) -enum { - MMI_OPC_PLZCW =3D 0x04 | MMI_OPC_CLASS_MMI, - MMI_OPC_CLASS_MMI0 =3D 0x08 | MMI_OPC_CLASS_MMI, - MMI_OPC_CLASS_MMI2 =3D 0x09 | MMI_OPC_CLASS_MMI, - MMI_OPC_CLASS_MMI1 =3D 0x28 | MMI_OPC_CLASS_MMI, - MMI_OPC_CLASS_MMI3 =3D 0x29 | MMI_OPC_CLASS_MMI, - MMI_OPC_PMFHL =3D 0x30 | MMI_OPC_CLASS_MMI, - MMI_OPC_PMTHL =3D 0x31 | MMI_OPC_CLASS_MMI, - MMI_OPC_PSLLH =3D 0x34 | MMI_OPC_CLASS_MMI, - MMI_OPC_PSRLH =3D 0x36 | MMI_OPC_CLASS_MMI, - MMI_OPC_PSRAH =3D 0x37 | MMI_OPC_CLASS_MMI, - MMI_OPC_PSLLW =3D 0x3C | MMI_OPC_CLASS_MMI, - MMI_OPC_PSRLW =3D 0x3E | MMI_OPC_CLASS_MMI, - MMI_OPC_PSRAW =3D 0x3F | MMI_OPC_CLASS_MMI, -}; - -/* - * MMI instructions with opcode field =3D MMI and bits 5..0 =3D MMI0: - * - * 31 26 10 6 5 0 - * +--------+----------------------+--------+--------+ - * | MMI | |function| MMI0 | - * +--------+----------------------+--------+--------+ - * - * function bits 7..6 - * bits | 0 | 1 | 2 | 3 - * 10..8 | 00 | 01 | 10 | 11 - * -------+-------+-------+-------+------- - * 0 000 | PADDW | PSUBW | PCGTW | PMAXW - * 1 001 | PADDH | PSUBH | PCGTH | PMAXH - * 2 010 | PADDB | PSUBB | PCGTB | * - * 3 011 | * | * | * | * - * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW - * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH - * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB - * 7 111 | * | * | PEXT5 | PPAC5 - */ - -#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF)) -enum { - MMI_OPC_0_PADDW =3D (0x00 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PSUBW =3D (0x01 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PCGTW =3D (0x02 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PMAXW =3D (0x03 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PADDH =3D (0x04 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PSUBH =3D (0x05 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PCGTH =3D (0x06 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PMAXH =3D (0x07 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PADDB =3D (0x08 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PSUBB =3D (0x09 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PCGTB =3D (0x0A << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PADDSW =3D (0x10 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PSUBSW =3D (0x11 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PEXTLW =3D (0x12 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PPACW =3D (0x13 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PADDSH =3D (0x14 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PSUBSH =3D (0x15 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PEXTLH =3D (0x16 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PPACH =3D (0x17 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PADDSB =3D (0x18 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PSUBSB =3D (0x19 << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PEXTLB =3D (0x1A << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PPACB =3D (0x1B << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PEXT5 =3D (0x1E << 6) | MMI_OPC_CLASS_MMI0, - MMI_OPC_0_PPAC5 =3D (0x1F << 6) | MMI_OPC_CLASS_MMI0, -}; - -/* - * MMI instructions with opcode field =3D MMI and bits 5..0 =3D MMI1: - * - * 31 26 10 6 5 0 - * +--------+----------------------+--------+--------+ - * | MMI | |function| MMI1 | - * +--------+----------------------+--------+--------+ - * - * function bits 7..6 - * bits | 0 | 1 | 2 | 3 - * 10..8 | 00 | 01 | 10 | 11 - * -------+-------+-------+-------+------- - * 0 000 | * | PABSW | PCEQW | PMINW - * 1 001 | PADSBH| PABSH | PCEQH | PMINH - * 2 010 | * | * | PCEQB | * - * 3 011 | * | * | * | * - * 4 100 | PADDUW| PSUBUW| PEXTUW| * - * 5 101 | PADDUH| PSUBUH| PEXTUH| * - * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV - * 7 111 | * | * | * | * - */ - -#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF)) -enum { - MMI_OPC_1_PABSW =3D (0x01 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PCEQW =3D (0x02 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PMINW =3D (0x03 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PADSBH =3D (0x04 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PABSH =3D (0x05 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PCEQH =3D (0x06 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PMINH =3D (0x07 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PCEQB =3D (0x0A << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PADDUW =3D (0x10 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PSUBUW =3D (0x11 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PEXTUW =3D (0x12 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PADDUH =3D (0x14 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PSUBUH =3D (0x15 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PEXTUH =3D (0x16 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PADDUB =3D (0x18 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PSUBUB =3D (0x19 << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_PEXTUB =3D (0x1A << 6) | MMI_OPC_CLASS_MMI1, - MMI_OPC_1_QFSRV =3D (0x1B << 6) | MMI_OPC_CLASS_MMI1, -}; - -/* - * MMI instructions with opcode field =3D MMI and bits 5..0 =3D MMI2: - * - * 31 26 10 6 5 0 - * +--------+----------------------+--------+--------+ - * | MMI | |function| MMI2 | - * +--------+----------------------+--------+--------+ - * - * function bits 7..6 - * bits | 0 | 1 | 2 | 3 - * 10..8 | 00 | 01 | 10 | 11 - * -------+-------+-------+-------+------- - * 0 000 | PMADDW| * | PSLLVW| PSRLVW - * 1 001 | PMSUBW| * | * | * - * 2 010 | PMFHI | PMFLO | PINTH | * - * 3 011 | PMULTW| PDIVW | PCPYLD| * - * 4 100 | PMADDH| PHMADH| PAND | PXOR - * 5 101 | PMSUBH| PHMSBH| * | * - * 6 110 | * | * | PEXEH | PREVH - * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W - */ - -#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF)) -enum { - MMI_OPC_2_PMADDW =3D (0x00 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PSLLVW =3D (0x02 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PSRLVW =3D (0x03 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PMSUBW =3D (0x04 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PMFHI =3D (0x08 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PMFLO =3D (0x09 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PINTH =3D (0x0A << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PMULTW =3D (0x0C << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PDIVW =3D (0x0D << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PCPYLD =3D (0x0E << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PMADDH =3D (0x10 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PHMADH =3D (0x11 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PAND =3D (0x12 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PXOR =3D (0x13 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PMSUBH =3D (0x14 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PHMSBH =3D (0x15 << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PEXEH =3D (0x1A << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PREVH =3D (0x1B << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PMULTH =3D (0x1C << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PDIVBW =3D (0x1D << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PEXEW =3D (0x1E << 6) | MMI_OPC_CLASS_MMI2, - MMI_OPC_2_PROT3W =3D (0x1F << 6) | MMI_OPC_CLASS_MMI2, -}; - -/* - * MMI instructions with opcode field =3D MMI and bits 5..0 =3D MMI3: - * - * 31 26 10 6 5 0 - * +--------+----------------------+--------+--------+ - * | MMI | |function| MMI3 | - * +--------+----------------------+--------+--------+ - * - * function bits 7..6 - * bits | 0 | 1 | 2 | 3 - * 10..8 | 00 | 01 | 10 | 11 - * -------+-------+-------+-------+------- - * 0 000 |PMADDUW| * | * | PSRAVW - * 1 001 | * | * | * | * - * 2 010 | PMTHI | PMTLO | PINTEH| * - * 3 011 |PMULTUW| PDIVUW| PCPYUD| * - * 4 100 | * | * | POR | PNOR - * 5 101 | * | * | * | * - * 6 110 | * | * | PEXCH | PCPYH - * 7 111 | * | * | PEXCW | * - */ - -#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF)) -enum { - MMI_OPC_3_PMADDUW =3D (0x00 << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PSRAVW =3D (0x03 << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PMTHI =3D (0x08 << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PMTLO =3D (0x09 << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PINTEH =3D (0x0A << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PMULTUW =3D (0x0C << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PDIVUW =3D (0x0D << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PCPYUD =3D (0x0E << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_POR =3D (0x12 << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PNOR =3D (0x13 << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PEXCH =3D (0x1A << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PCPYH =3D (0x1B << 6) | MMI_OPC_CLASS_MMI3, - MMI_OPC_3_PEXCW =3D (0x1E << 6) | MMI_OPC_CLASS_MMI3, -}; - /* global register indices */ static TCGv cpu_gpr[32], cpu_PC; static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; @@ -1127,11 +728,6 @@ static TCGv_i32 hflags; static TCGv_i32 fpu_fcr0, fpu_fcr31; static TCGv_i64 fpu_f64[32]; =20 -#if defined(TARGET_MIPS64) -/* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) = */ -static TCGv_i64 cpu_mmr[32]; -#endif - #include "exec/gen-icount.h" =20 #define gen_helper_0e0i(name, arg) do { \ @@ -11402,169 +10998,6 @@ static void decode_opc_special(CPUMIPSState *env,= DisasContext *ctx) } } =20 - -#if defined(TARGET_MIPS64) - -/* - * - * MMI (MultiMedia Interface) ASE instructions - * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - */ - -/* - * MMI instructions category: data communication - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH - * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W - * PCPYUD PEXEH PEXTLW PPACW - * PEXEW PEXTUB - * PEXTUH - * PEXTUW - */ - -/* - * PCPYH rd, rt - * - * Parallel Copy Halfword - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+---------+---------+---------+-----------+ - * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 | - * +-----------+---------+---------+---------+---------+-----------+ - */ -static void gen_mmi_pcpyh(DisasContext *ctx) -{ - uint32_t pd, rt, rd; - uint32_t opcode; - - opcode =3D ctx->opcode; - - pd =3D extract32(opcode, 21, 5); - rt =3D extract32(opcode, 16, 5); - rd =3D extract32(opcode, 11, 5); - - if (unlikely(pd !=3D 0)) { - generate_exception_end(ctx, EXCP_RI); - } else if (rd =3D=3D 0) { - /* nop */ - } else if (rt =3D=3D 0) { - tcg_gen_movi_i64(cpu_gpr[rd], 0); - tcg_gen_movi_i64(cpu_mmr[rd], 0); - } else { - TCGv_i64 t0 =3D tcg_temp_new(); - TCGv_i64 t1 =3D tcg_temp_new(); - uint64_t mask =3D (1ULL << 16) - 1; - - tcg_gen_andi_i64(t0, cpu_gpr[rt], mask); - tcg_gen_movi_i64(t1, 0); - tcg_gen_or_i64(t1, t0, t1); - tcg_gen_shli_i64(t0, t0, 16); - tcg_gen_or_i64(t1, t0, t1); - tcg_gen_shli_i64(t0, t0, 16); - tcg_gen_or_i64(t1, t0, t1); - tcg_gen_shli_i64(t0, t0, 16); - tcg_gen_or_i64(t1, t0, t1); - - tcg_gen_mov_i64(cpu_gpr[rd], t1); - - tcg_gen_andi_i64(t0, cpu_mmr[rt], mask); - tcg_gen_movi_i64(t1, 0); - tcg_gen_or_i64(t1, t0, t1); - tcg_gen_shli_i64(t0, t0, 16); - tcg_gen_or_i64(t1, t0, t1); - tcg_gen_shli_i64(t0, t0, 16); - tcg_gen_or_i64(t1, t0, t1); - tcg_gen_shli_i64(t0, t0, 16); - tcg_gen_or_i64(t1, t0, t1); - - tcg_gen_mov_i64(cpu_mmr[rd], t1); - - tcg_temp_free(t0); - tcg_temp_free(t1); - } -} - -/* - * PCPYLD rd, rs, rt - * - * Parallel Copy Lower Doubleword - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+---------+---------+---------+-----------+ - * | MMI | rs | rt | rd | PCPYLD | MMI2 | - * +-----------+---------+---------+---------+---------+-----------+ - */ -static void gen_mmi_pcpyld(DisasContext *ctx) -{ - uint32_t rs, rt, rd; - uint32_t opcode; - - opcode =3D ctx->opcode; - - rs =3D extract32(opcode, 21, 5); - rt =3D extract32(opcode, 16, 5); - rd =3D extract32(opcode, 11, 5); - - if (rd =3D=3D 0) { - /* nop */ - } else { - if (rs =3D=3D 0) { - tcg_gen_movi_i64(cpu_mmr[rd], 0); - } else { - tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]); - } - if (rt =3D=3D 0) { - tcg_gen_movi_i64(cpu_gpr[rd], 0); - } else { - if (rd !=3D rt) { - tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]); - } - } - } -} - -/* - * PCPYUD rd, rs, rt - * - * Parallel Copy Upper Doubleword - * - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - * +-----------+---------+---------+---------+---------+-----------+ - * | MMI | rs | rt | rd | PCPYUD | MMI3 | - * +-----------+---------+---------+---------+---------+-----------+ - */ -static void gen_mmi_pcpyud(DisasContext *ctx) -{ - uint32_t rs, rt, rd; - uint32_t opcode; - - opcode =3D ctx->opcode; - - rs =3D extract32(opcode, 21, 5); - rt =3D extract32(opcode, 16, 5); - rd =3D extract32(opcode, 11, 5); - - if (rd =3D=3D 0) { - /* nop */ - } else { - if (rs =3D=3D 0) { - tcg_gen_movi_i64(cpu_gpr[rd], 0); - } else { - tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]); - } - if (rt =3D=3D 0) { - tcg_gen_movi_i64(cpu_mmr[rd], 0); - } else { - if (rd !=3D rt) { - tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]); - } - } - } -} - -#endif - static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ct= x) { int rs, rt, rd; diff --git a/target/mips/vendor-tx-mmi_translate.c.inc b/target/mips/vendor= -tx-mmi_translate.c.inc new file mode 100644 index 00000000000..fcc05a96e15 --- /dev/null +++ b/target/mips/vendor-tx-mmi_translate.c.inc @@ -0,0 +1,573 @@ +/* + * Toshiba TX MultiMedia Instruction translation routines. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits + * are only used by the specific quadword (128-bit) LQ/SQ load/store + * instructions and certain multimedia instructions (MMIs). These MMIs + * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit + * or sixteen 8-bit paths. + * + * Reference: + * + * The Toshiba TX System RISC TX79 Core Architecture manual, + * https://wiki.qemu.org/File:C790.pdf + * + * Arithmetic (19 instructions) + * ---------------------------- + * PADDB rd, rs, rt Parallel Add Byte + * PSUBB rd, rs, rt Parallel Subtract Byte + * PADDH rd, rs, rt Parallel Add Halfword + * PSUBH rd, rs, rt Parallel Subtract Halfword + * PADDW rd, rs, rt Parallel Add Word + * PSUBW rd, rs, rt Parallel Subtract Word + * PADSBH rd, rs, rt Parallel Add/Subtract Halfword + * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte + * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte + * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword + * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Half= word + * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word + * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word + * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte + * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation By= te + * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword + * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Ha= lfword + * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word + * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Wo= rd + * + * Min/Max (4 instructions) + * ------------------------ + * PMAXH rd, rs, rt Parallel Maximum Halfword + * PMINH rd, rs, rt Parallel Minimum Halfword + * PMAXW rd, rs, rt Parallel Maximum Word + * PMINW rd, rs, rt Parallel Minimum Word + * + * Absolute (2 instructions) + * ------------------------- + * PABSH rd, rt Parallel Absolute Halfword + * PABSW rd, rt Parallel Absolute Word + * + * Logical (4 instructions) + * ------------------------ + * PAND rd, rs, rt Parallel AND + * POR rd, rs, rt Parallel OR + * PXOR rd, rs, rt Parallel XOR + * PNOR rd, rs, rt Parallel NOR + * + * Shift (9 instructions) + * ---------------------- + * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword + * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword + * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword + * PSLLW rd, rt, sa Parallel Shift Left Logical Word + * PSRLW rd, rt, sa Parallel Shift Right Logical Word + * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word + * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word + * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word + * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word + * + * Compare (6 instructions) + * ------------------------ + * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte + * PCEQB rd, rs, rt Parallel Compare for Equal Byte + * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword + * PCEQH rd, rs, rt Parallel Compare for Equal Halfword + * PCGTW rd, rs, rt Parallel Compare for Greater Than Word + * PCEQW rd, rs, rt Parallel Compare for Equal Word + * + * LZC (1 instruction) + * ------------------- + * PLZCW rd, rs Parallel Leading Zero or One Count Word + * + * Quadword Load and Store (2 instructions) + * ---------------------------------------- + * LQ rt, offset(base) Load Quadword + * SQ rt, offset(base) Store Quadword + * + * Multiply and Divide (19 instructions) + * ------------------------------------- + * PMULTW rd, rs, rt Parallel Multiply Word + * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word + * PDIVW rs, rt Parallel Divide Word + * PDIVUW rs, rt Parallel Divide Unsigned Word + * PMADDW rd, rs, rt Parallel Multiply-Add Word + * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word + * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word + * PMULTH rd, rs, rt Parallel Multiply Halfword + * PMADDH rd, rs, rt Parallel Multiply-Add Halfword + * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword + * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword + * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword + * PDIVBW rs, rt Parallel Divide Broadcast Word + * PMFHI rd Parallel Move From HI Register + * PMFLO rd Parallel Move From LO Register + * PMTHI rs Parallel Move To HI Register + * PMTLO rs Parallel Move To LO Register + * PMFHL rd Parallel Move From HI/LO Register + * PMTHL rs Parallel Move To HI/LO Register + * + * Pack/Extend (11 instructions) + * ----------------------------- + * PPAC5 rd, rt Parallel Pack to 5 bits + * PPACB rd, rs, rt Parallel Pack to Byte + * PPACH rd, rs, rt Parallel Pack to Halfword + * PPACW rd, rs, rt Parallel Pack to Word + * PEXT5 rd, rt Parallel Extend Upper from 5 bits + * PEXTUB rd, rs, rt Parallel Extend Upper from Byte + * PEXTLB rd, rs, rt Parallel Extend Lower from Byte + * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword + * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword + * PEXTUW rd, rs, rt Parallel Extend Upper from Word + * PEXTLW rd, rs, rt Parallel Extend Lower from Word + * + * Others (16 instructions) + * ------------------------ + * PCPYH rd, rt Parallel Copy Halfword + * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword + * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword + * PREVH rd, rt Parallel Reverse Halfword + * PINTH rd, rs, rt Parallel Interleave Halfword + * PINTEH rd, rs, rt Parallel Interleave Even Halfword + * PEXEH rd, rt Parallel Exchange Even Halfword + * PEXCH rd, rt Parallel Exchange Center Halfword + * PEXEW rd, rt Parallel Exchange Even Word + * PEXCW rd, rt Parallel Exchange Center Word + * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable + * MFSA rd Move from Shift Amount Register + * MTSA rs Move to Shift Amount Register + * MTSAB rs, immediate Move Byte Count to Shift Amount Register + * MTSAH rs, immediate Move Halfword Count to Shift Amount Register + * PROT3W rd, rt Parallel Rotate 3 Words + * + * MMI (MultiMedia Instruction) encodings + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + * + * MMI instructions encoding table keys: + * + * * This code is reserved for future use. An attempt to execute it + * causes a Reserved Instruction exception. + * % This code indicates an instruction class. The instruction word + * must be further decoded by examining additional tables that show + * the values for other instruction fields. + * # This code is reserved for the unsupported instructions DMULT, + * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt + * to execute it causes a Reserved Instruction exception. + * + * MMI instructions encoded by opcode field (MMI, LQ, SQ): + * + * 31 26 0 + * +--------+----------------------------------------+ + * | opcode | | + * +--------+----------------------------------------+ + * + * opcode bits 28..26 + * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 + * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 + * -------+-------+-------+-------+-------+-------+-------+-------+-----= -- + * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ + * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI + * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL + * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ + * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU + * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE + * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD + * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD + */ + +enum { + MMI_OPC_CLASS_MMI =3D 0x1C << 26, /* Same as OPC_SPECIAL2 */ + MMI_OPC_LQ =3D 0x1E << 26, /* Same as OPC_MSA */ + MMI_OPC_SQ =3D 0x1F << 26, /* Same as OPC_SPECIAL3 */ +}; + +/* + * MMI instructions with opcode field =3D MMI: + * + * 31 26 5 0 + * +--------+-------------------------------+--------+ + * | MMI | |function| + * +--------+-------------------------------+--------+ + * + * function bits 2..0 + * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 + * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 + * -------+-------+-------+-------+-------+-------+-------+-------+-----= -- + * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * + * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * + * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * + * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * + * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * + * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * + * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH + * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW + */ + +#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) +enum { + MMI_OPC_PLZCW =3D 0x04 | MMI_OPC_CLASS_MMI, + MMI_OPC_CLASS_MMI0 =3D 0x08 | MMI_OPC_CLASS_MMI, + MMI_OPC_CLASS_MMI2 =3D 0x09 | MMI_OPC_CLASS_MMI, + MMI_OPC_CLASS_MMI1 =3D 0x28 | MMI_OPC_CLASS_MMI, + MMI_OPC_CLASS_MMI3 =3D 0x29 | MMI_OPC_CLASS_MMI, + MMI_OPC_PMFHL =3D 0x30 | MMI_OPC_CLASS_MMI, + MMI_OPC_PMTHL =3D 0x31 | MMI_OPC_CLASS_MMI, + MMI_OPC_PSLLH =3D 0x34 | MMI_OPC_CLASS_MMI, + MMI_OPC_PSRLH =3D 0x36 | MMI_OPC_CLASS_MMI, + MMI_OPC_PSRAH =3D 0x37 | MMI_OPC_CLASS_MMI, + MMI_OPC_PSLLW =3D 0x3C | MMI_OPC_CLASS_MMI, + MMI_OPC_PSRLW =3D 0x3E | MMI_OPC_CLASS_MMI, + MMI_OPC_PSRAW =3D 0x3F | MMI_OPC_CLASS_MMI, +}; + +/* + * MMI instructions with opcode field =3D MMI and bits 5..0 =3D MMI0: + * + * 31 26 10 6 5 0 + * +--------+----------------------+--------+--------+ + * | MMI | |function| MMI0 | + * +--------+----------------------+--------+--------+ + * + * function bits 7..6 + * bits | 0 | 1 | 2 | 3 + * 10..8 | 00 | 01 | 10 | 11 + * -------+-------+-------+-------+------- + * 0 000 | PADDW | PSUBW | PCGTW | PMAXW + * 1 001 | PADDH | PSUBH | PCGTH | PMAXH + * 2 010 | PADDB | PSUBB | PCGTB | * + * 3 011 | * | * | * | * + * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW + * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH + * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB + * 7 111 | * | * | PEXT5 | PPAC5 + */ + +#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF)) +enum { + MMI_OPC_0_PADDW =3D (0x00 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PSUBW =3D (0x01 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PCGTW =3D (0x02 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PMAXW =3D (0x03 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PADDH =3D (0x04 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PSUBH =3D (0x05 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PCGTH =3D (0x06 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PMAXH =3D (0x07 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PADDB =3D (0x08 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PSUBB =3D (0x09 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PCGTB =3D (0x0A << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PADDSW =3D (0x10 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PSUBSW =3D (0x11 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PEXTLW =3D (0x12 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PPACW =3D (0x13 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PADDSH =3D (0x14 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PSUBSH =3D (0x15 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PEXTLH =3D (0x16 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PPACH =3D (0x17 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PADDSB =3D (0x18 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PSUBSB =3D (0x19 << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PEXTLB =3D (0x1A << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PPACB =3D (0x1B << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PEXT5 =3D (0x1E << 6) | MMI_OPC_CLASS_MMI0, + MMI_OPC_0_PPAC5 =3D (0x1F << 6) | MMI_OPC_CLASS_MMI0, +}; + +/* + * MMI instructions with opcode field =3D MMI and bits 5..0 =3D MMI1: + * + * 31 26 10 6 5 0 + * +--------+----------------------+--------+--------+ + * | MMI | |function| MMI1 | + * +--------+----------------------+--------+--------+ + * + * function bits 7..6 + * bits | 0 | 1 | 2 | 3 + * 10..8 | 00 | 01 | 10 | 11 + * -------+-------+-------+-------+------- + * 0 000 | * | PABSW | PCEQW | PMINW + * 1 001 | PADSBH| PABSH | PCEQH | PMINH + * 2 010 | * | * | PCEQB | * + * 3 011 | * | * | * | * + * 4 100 | PADDUW| PSUBUW| PEXTUW| * + * 5 101 | PADDUH| PSUBUH| PEXTUH| * + * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV + * 7 111 | * | * | * | * + */ + +#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF)) +enum { + MMI_OPC_1_PABSW =3D (0x01 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PCEQW =3D (0x02 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PMINW =3D (0x03 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PADSBH =3D (0x04 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PABSH =3D (0x05 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PCEQH =3D (0x06 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PMINH =3D (0x07 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PCEQB =3D (0x0A << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PADDUW =3D (0x10 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PSUBUW =3D (0x11 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PEXTUW =3D (0x12 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PADDUH =3D (0x14 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PSUBUH =3D (0x15 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PEXTUH =3D (0x16 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PADDUB =3D (0x18 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PSUBUB =3D (0x19 << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_PEXTUB =3D (0x1A << 6) | MMI_OPC_CLASS_MMI1, + MMI_OPC_1_QFSRV =3D (0x1B << 6) | MMI_OPC_CLASS_MMI1, +}; + +/* + * MMI instructions with opcode field =3D MMI and bits 5..0 =3D MMI2: + * + * 31 26 10 6 5 0 + * +--------+----------------------+--------+--------+ + * | MMI | |function| MMI2 | + * +--------+----------------------+--------+--------+ + * + * function bits 7..6 + * bits | 0 | 1 | 2 | 3 + * 10..8 | 00 | 01 | 10 | 11 + * -------+-------+-------+-------+------- + * 0 000 | PMADDW| * | PSLLVW| PSRLVW + * 1 001 | PMSUBW| * | * | * + * 2 010 | PMFHI | PMFLO | PINTH | * + * 3 011 | PMULTW| PDIVW | PCPYLD| * + * 4 100 | PMADDH| PHMADH| PAND | PXOR + * 5 101 | PMSUBH| PHMSBH| * | * + * 6 110 | * | * | PEXEH | PREVH + * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W + */ + +#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF)) +enum { + MMI_OPC_2_PMADDW =3D (0x00 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PSLLVW =3D (0x02 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PSRLVW =3D (0x03 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PMSUBW =3D (0x04 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PMFHI =3D (0x08 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PMFLO =3D (0x09 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PINTH =3D (0x0A << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PMULTW =3D (0x0C << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PDIVW =3D (0x0D << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PCPYLD =3D (0x0E << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PMADDH =3D (0x10 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PHMADH =3D (0x11 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PAND =3D (0x12 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PXOR =3D (0x13 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PMSUBH =3D (0x14 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PHMSBH =3D (0x15 << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PEXEH =3D (0x1A << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PREVH =3D (0x1B << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PMULTH =3D (0x1C << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PDIVBW =3D (0x1D << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PEXEW =3D (0x1E << 6) | MMI_OPC_CLASS_MMI2, + MMI_OPC_2_PROT3W =3D (0x1F << 6) | MMI_OPC_CLASS_MMI2, +}; + +/* + * MMI instructions with opcode field =3D MMI and bits 5..0 =3D MMI3: + * + * 31 26 10 6 5 0 + * +--------+----------------------+--------+--------+ + * | MMI | |function| MMI3 | + * +--------+----------------------+--------+--------+ + * + * function bits 7..6 + * bits | 0 | 1 | 2 | 3 + * 10..8 | 00 | 01 | 10 | 11 + * -------+-------+-------+-------+------- + * 0 000 |PMADDUW| * | * | PSRAVW + * 1 001 | * | * | * | * + * 2 010 | PMTHI | PMTLO | PINTEH| * + * 3 011 |PMULTUW| PDIVUW| PCPYUD| * + * 4 100 | * | * | POR | PNOR + * 5 101 | * | * | * | * + * 6 110 | * | * | PEXCH | PCPYH + * 7 111 | * | * | PEXCW | * + */ + +#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF)) +enum { + MMI_OPC_3_PMADDUW =3D (0x00 << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PSRAVW =3D (0x03 << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PMTHI =3D (0x08 << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PMTLO =3D (0x09 << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PINTEH =3D (0x0A << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PMULTUW =3D (0x0C << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PDIVUW =3D (0x0D << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PCPYUD =3D (0x0E << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_POR =3D (0x12 << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PNOR =3D (0x13 << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PEXCH =3D (0x1A << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PCPYH =3D (0x1B << 6) | MMI_OPC_CLASS_MMI3, + MMI_OPC_3_PEXCW =3D (0x1E << 6) | MMI_OPC_CLASS_MMI3, +}; + +#if defined(TARGET_MIPS64) +/* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) = */ +static TCGv_i64 cpu_mmr[32]; + +/* + * + * MMI (MultiMedia Interface) ASE instructions + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + */ + +/* + * MMI instructions category: data communication + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH + * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W + * PCPYUD PEXEH PEXTLW PPACW + * PEXEW PEXTUB + * PEXTUH + * PEXTUW + */ + +/* + * PCPYH rd, rt + * + * Parallel Copy Halfword + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---------+---------+-----------+ + * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 | + * +-----------+---------+---------+---------+---------+-----------+ + */ +static void gen_mmi_pcpyh(DisasContext *ctx) +{ + uint32_t pd, rt, rd; + uint32_t opcode; + + opcode =3D ctx->opcode; + + pd =3D extract32(opcode, 21, 5); + rt =3D extract32(opcode, 16, 5); + rd =3D extract32(opcode, 11, 5); + + if (unlikely(pd !=3D 0)) { + generate_exception_end(ctx, EXCP_RI); + } else if (rd =3D=3D 0) { + /* nop */ + } else if (rt =3D=3D 0) { + tcg_gen_movi_i64(cpu_gpr[rd], 0); + tcg_gen_movi_i64(cpu_mmr[rd], 0); + } else { + TCGv_i64 t0 =3D tcg_temp_new(); + TCGv_i64 t1 =3D tcg_temp_new(); + uint64_t mask =3D (1ULL << 16) - 1; + + tcg_gen_andi_i64(t0, cpu_gpr[rt], mask); + tcg_gen_movi_i64(t1, 0); + tcg_gen_or_i64(t1, t0, t1); + tcg_gen_shli_i64(t0, t0, 16); + tcg_gen_or_i64(t1, t0, t1); + tcg_gen_shli_i64(t0, t0, 16); + tcg_gen_or_i64(t1, t0, t1); + tcg_gen_shli_i64(t0, t0, 16); + tcg_gen_or_i64(t1, t0, t1); + + tcg_gen_mov_i64(cpu_gpr[rd], t1); + + tcg_gen_andi_i64(t0, cpu_mmr[rt], mask); + tcg_gen_movi_i64(t1, 0); + tcg_gen_or_i64(t1, t0, t1); + tcg_gen_shli_i64(t0, t0, 16); + tcg_gen_or_i64(t1, t0, t1); + tcg_gen_shli_i64(t0, t0, 16); + tcg_gen_or_i64(t1, t0, t1); + tcg_gen_shli_i64(t0, t0, 16); + tcg_gen_or_i64(t1, t0, t1); + + tcg_gen_mov_i64(cpu_mmr[rd], t1); + + tcg_temp_free(t0); + tcg_temp_free(t1); + } +} + +/* + * PCPYLD rd, rs, rt + * + * Parallel Copy Lower Doubleword + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---------+---------+-----------+ + * | MMI | rs | rt | rd | PCPYLD | MMI2 | + * +-----------+---------+---------+---------+---------+-----------+ + */ +static void gen_mmi_pcpyld(DisasContext *ctx) +{ + uint32_t rs, rt, rd; + uint32_t opcode; + + opcode =3D ctx->opcode; + + rs =3D extract32(opcode, 21, 5); + rt =3D extract32(opcode, 16, 5); + rd =3D extract32(opcode, 11, 5); + + if (rd =3D=3D 0) { + /* nop */ + } else { + if (rs =3D=3D 0) { + tcg_gen_movi_i64(cpu_mmr[rd], 0); + } else { + tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]); + } + if (rt =3D=3D 0) { + tcg_gen_movi_i64(cpu_gpr[rd], 0); + } else { + if (rd !=3D rt) { + tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]); + } + } + } +} + +/* + * PCPYUD rd, rs, rt + * + * Parallel Copy Upper Doubleword + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---------+---------+-----------+ + * | MMI | rs | rt | rd | PCPYUD | MMI3 | + * +-----------+---------+---------+---------+---------+-----------+ + */ +static void gen_mmi_pcpyud(DisasContext *ctx) +{ + uint32_t rs, rt, rd; + uint32_t opcode; + + opcode =3D ctx->opcode; + + rs =3D extract32(opcode, 21, 5); + rt =3D extract32(opcode, 16, 5); + rd =3D extract32(opcode, 11, 5); + + if (rd =3D=3D 0) { + /* nop */ + } else { + if (rs =3D=3D 0) { + tcg_gen_movi_i64(cpu_gpr[rd], 0); + } else { + tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]); + } + if (rt =3D=3D 0) { + tcg_gen_movi_i64(cpu_mmr[rd], 0); + } else { + if (rd !=3D rt) { + tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]); + } + } + } +} + +#endif diff --git a/target/mips/vendor-tx_translate.c.inc b/target/mips/vendor-tx_= translate.c.inc index 1d157743bd4..2a3e7b12d77 100644 --- a/target/mips/vendor-tx_translate.c.inc +++ b/target/mips/vendor-tx_translate.c.inc @@ -41,6 +41,8 @@ =20 #if defined(TARGET_MIPS64) =20 +#include "vendor-tx-mmi_translate.c.inc" + /* Copy GPR to and from TX79 HI1/LO1 register. */ static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg) { --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.66 as permitted sender) client-ip=209.85.128.66; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f66.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.66 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail(p=none dis=none) header.from=amsat.org ARC-Seal: i=1; a=rsa-sha256; t=1605906655; cv=none; d=zohomail.com; s=zohoarc; b=QTtST9OAr0x6uwAePkvE3ERs5pdbMhAkX78vcTMT10NHhm4MctNOS6MGw9YZMYwZ75DDuY/Q3elPK0wY5bu6v0QkPY88BZQPPqIMiPP67TGn3w7iVcXeBSl0VUTRtufzMi00YiHZy4llAowW1MqGMxAc8MK/K5o8HZDexKh/CLo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906655; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=dewrVsFDGuxgSIArHJaBqqAmHYhFd/iS0jR527zZNV8=; b=TgFQITPqFAbTbLrKrdxpNYSgXw6QFr5IsLqH45UU4thH8hAWPOtXXF5BCCdKn1mf5UMo4BViWLkrEEWdBx2ANF4XIC/VO3q9ElnK62LvmtYWH69s35eV5jzw1x4ffSLzRFVrsPSFE5Qhde1M50OArcOE5+4N9W5MS8gXaSm8glo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.66 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by mx.zohomail.com with SMTPS id 1605906655607553.4918843245016; Fri, 20 Nov 2020 13:10:55 -0800 (PST) Received: by mail-wm1-f66.google.com with SMTP id c9so11866449wml.5 for ; Fri, 20 Nov 2020 13:10:55 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id h17sm8131107wrp.54.2020.11.20.13.10.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=dewrVsFDGuxgSIArHJaBqqAmHYhFd/iS0jR527zZNV8=; b=lL3s8QmCDWH+51LD3yVYqrVNz/Z2bC+9qpnyu2bzjcwrEIta37AATKUE1RPGm+c5RS VFU2Chmwx8wP9RBghgDVyxic3m1oeA/cKUaxEnALsm0M9zE2IrjlYXw7KXZq1x5XjpGl OZe+vT1lmxCQS/2FUwvIkkmMTcuz/1MJFtZHOngoL6j+9A2Hams2H5AGofzu3TRV+Rlz 5rWZN5Z824MlFrKNq7FEtdOERwnTVXDyxVGJ9DWDEE7hDNtazG839uwJQmpPAhNFbdFA /FmXeMMV8KRhQoprSt6EjHd82JL8NbwMSOdbyoLXP0yNHOTxwnDiFamWg/7FqNTtnLW6 8dmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=dewrVsFDGuxgSIArHJaBqqAmHYhFd/iS0jR527zZNV8=; b=tHBlaQCZh4PmoW9V4s23y4wb3FUttzON6nitaK6twsbWfyOqNe9onl4BKR6Ck6tZ9S 514mdIMfO0/ipw+WgARfJKtk6IPMOByAAd9XzrM0txUpno6aWLxz+Sh5d6D+hTxqPBVM 7CAzyvLMBUg1ZxUrgxKPUynEe+F75qm8idDfZXPfgZxcAlCs7RxLve3l0yJqeeJtXtCK 4VF9Mlj1Vm6oA8VhvnXPhADbIx4Dv/X3WkMxlSuXcymjESUnz5AZLwLCncuywNvGhdrK qx8qAfi1OaFc9f2/F84gZche8FpRlCg1r2ZoYWwudFFejo4HaiHAC0MeWdlr1XXyws3X Bxtw== X-Gm-Message-State: AOAM531a6za6+lMVFkYImuSM3Vt6Y/c3mZPdtNoTcyEVio8WD5Zu40k5 XpyDpmLy2krsRoRq9unUdvs= X-Google-Smtp-Source: ABdhPJzJNEzyT5EbNuw19Z2K17DuU0XlGOH8ll/gMv0RBi/zeTMUF1Ta3BMNRe5LntsQ/iky7huCwA== X-Received: by 2002:a7b:c05a:: with SMTP id u26mr12502592wmc.159.1605906653845; Fri, 20 Nov 2020 13:10:53 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 24/26] MAINTAINERS: Add entry for MIPS Loongson TCG Date: Fri, 20 Nov 2020 22:08:42 +0100 Message-Id: <20201120210844.2625602-25-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Add an entry for the TCG core related to Loongson. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- Adding Huacai and Jiaxun in case they want to be notified of changes, patch conditional to their individual approval. --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ce7fe949036..be42b56300f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -240,6 +240,13 @@ F: include/hw/timer/mips_gictimer.h F: tests/tcg/mips/ K: ^Subject:.*(?i)mips =20 +MIPS TCG CPUs (Loongson) +M: Philippe Mathieu-Daud=C3=A9 +R: Huacai Chen +R: Jiaxun Yang +S: Odd Fixes +F: target/mips/vendor-loong* + MIPS TCG CPUs (nanoMIPS ISA) S: Orphan F: disas/nanomips.* --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.128.50 as permitted sender) client-ip=209.85.128.50; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-f50.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.50 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1605906660; cv=none; d=zohomail.com; s=zohoarc; b=KgsTIY6mC7VQjnXMNPp2yB4oomr3jE6NRma8TywPRHi4x7XG4116ehCSL53e9nkz0QHItxebvua2NSFjO6sNOTRYuutk/MwUtNxZuo46ZcmIyISAT2mM5cor2qlCModA+q/31wF0EchQRQRr19tshJWrXz1ffNiP024G1zQVLto= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906660; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=7PprWlplgZYOuiiRh5VgMSfZy377w8BTxZUiTVT7Smk=; b=YsK8HlXA3RsKUB/0GD0w/+/SrJm9xegEBwUYSpU8kitQUWoVT9B3lYYeUiAgarXQuaNJRAiOihjzvk+u6nkTd/oQWah654NP9Y077E1Rx3HArptQkZp8Wcgbu11JI0wnhPWhUb8jLR4ZxOwoE31MDxD3cr8eSY4CDKuryY8XC3E= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.128.50 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) by mx.zohomail.com with SMTPS id 1605906660737475.58554971126944; Fri, 20 Nov 2020 13:11:00 -0800 (PST) Received: by mail-wm1-f50.google.com with SMTP id p22so11862730wmg.3 for ; Fri, 20 Nov 2020 13:11:00 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id p3sm6270483wrs.50.2020.11.20.13.10.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:10:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7PprWlplgZYOuiiRh5VgMSfZy377w8BTxZUiTVT7Smk=; b=LVu0Vm/K2vvoEBLiQtlg4V4b8l4yNikQd9R2Y0bW+hBS0HTsUQ210ZzUiyWKvh7lGq tCS5ICFeFvKVAOqgDXp6uM/z2IGZJLPaaVWcR6VU+YFo4NdQe2ZTgBMHaxfZpBk3/cl3 k+Q9VktMJdKrw7uuqL/U43Wbzml0yreiuqDq/0e8K5s37ASVqa4j5RHZk1PGVat2Mw8K oBau/6smcTtEgOjuLu9b9oIPnQSm1mWxHUOSX6PA/4qplMr7peiAZfPKiVhPbFTGaXuF Q1hHtwBO9e4wbzEfuzAX+XrgZOGpkqiQyAXxdkSulKkF8Rw8YctU1u4pAjSZ+7BDS9KM ofXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=7PprWlplgZYOuiiRh5VgMSfZy377w8BTxZUiTVT7Smk=; b=hvw11tnqo/T6EPXNiNTrZGEjluO6qT8LQXHPNhLq/L2GNdTOj4mOTNS3/x6Gbsclbn nLsNNYnIcZD1s//e0HsaHGtrO/hZbBg79sSDNF5I0/bJs5ySr2nb52xNDRBtceh2BmQV y7DZH2n7PCLv4/3AzTREmHe3+6VTTPZIhnHJCmuGURUOyGelvOS19YaiSsMpYDL9znsK d6G72LG43W2qLzJk4KqMUo4Gf75OECVEbtS287opEOMeJhk1F4vven9j8uGKApaXgmuG jvf5cvUvhhXz21tlvKAB0khVvGpYrxBQ4lCRVgRmt1V0EDukJNWO91tI1eHvxr9GcG1W Uk2A== X-Gm-Message-State: AOAM532KDx3A1trEKC3zqCDdK3+ap1Egfmltc1OmJFBBIpWPRm8cojfq x6YsE+fFnTXQqDaENb50v/o= X-Google-Smtp-Source: ABdhPJwPI/tOfENRXAENKeqrhxDcFjjPqz1B/h8IzBpm9yO9zAUQApImySp+byfrDEE/5NW0R228FA== X-Received: by 2002:a1c:e455:: with SMTP id b82mr11979232wmh.117.1605906658886; Fri, 20 Nov 2020 13:10:58 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 25/26] MAINTAINERS: Add entry for MIPS Ingenic Xburst TCG Date: Fri, 20 Nov 2020 22:08:43 +0100 Message-Id: <20201120210844.2625602-26-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Add an entry for the TCG core related to Ingenic Xburst. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- Adding Craig Janeczek in case he wants to be notified of changes, patch conditional to his approval. --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index be42b56300f..b6d98b95c47 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -247,6 +247,12 @@ R: Jiaxun Yang S: Odd Fixes F: target/mips/vendor-loong* =20 +MIPS TCG CPUs (Ingenic Xburst) +M: Philippe Mathieu-Daud=C3=A9 +R: Craig Janeczek +S: Odd Fixes +F: target/mips/vendor-xburst* + MIPS TCG CPUs (nanoMIPS ISA) S: Orphan F: disas/nanomips.* --=20 2.26.2 From nobody Fri Apr 26 17:53:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.66 as permitted sender) client-ip=209.85.221.66; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f66.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.66 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail(p=none dis=none) header.from=amsat.org ARC-Seal: i=1; a=rsa-sha256; t=1605906666; cv=none; d=zohomail.com; s=zohoarc; b=caKiUQSxXn8BhypiiA7rbn018ggqybY/BTYBp4TTQcEzZk4O64k06HZ9+/rSSYdjIayYAAm3Z0KBK+wuuDbw165CET9UgZvmbslv6vQcmsfHur1BkyJUZt2Z5BrqL37BYVJ5lYznDAlIZXk6+gusH5OSTT++if016YIZTDo2wU0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605906666; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=s44mYLGUlM6uamsgG+YNsLF+fke2Wh0JOve4ukdROjw=; b=cZ9ppZb/qb2H7esqQe582pOx/SOZ0pJF/pshZz2SYxoAzOSXjeErW1AYaj1LJLGo9LqxFpZLxJ/RyPUVIEqINvmBrjasVHMmDm3g9Bp9d6WtUsPyYwKmLEVCzqiIq4S+0uqA5GB8Mgc9Q6JsmN6iU6LjjYOGp5moHevmYxWP8Os= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.66 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by mx.zohomail.com with SMTPS id 160590666599932.8633089376674; Fri, 20 Nov 2020 13:11:05 -0800 (PST) Received: by mail-wr1-f66.google.com with SMTP id o15so11717711wru.6 for ; Fri, 20 Nov 2020 13:11:05 -0800 (PST) Return-Path: Return-Path: Received: from x1w.redhat.com (234.red-83-42-66.dynamicip.rima-tde.net. [83.42.66.234]) by smtp.gmail.com with ESMTPSA id z6sm5685798wmi.1.2020.11.20.13.11.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Nov 2020 13:11:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=s44mYLGUlM6uamsgG+YNsLF+fke2Wh0JOve4ukdROjw=; b=iBAr2j7iKQa3f6wJ3DCzZ6LE921omTEaT4kDQarshFqOLk+CC5Rt+MwYNIbrbKwR+h BZSJSLcEL+XXKEygJcLjwCkdvuUDoIVWWCuiZn1m9qO6lLqUOtG4SHDYO7AB6iPnEVIb Ukx0neEPt4pX2jwSxlmZi+rA8i69UVTJxxdn1TjaW3GLbth6rql8sh0JplE65dWN3jvg zlJEMy3ljPEtAhiVqQD1PrP5XKMV7C7ae9lFQcfQQz9YUiq3jw/86S9Q+Zpv3a1Pgxck FxwRgyt2+RyiQzAtLiFrMzkNeuQKPQHX+rCemOUCvYRvtRb/PBOLiFg7hSuWZSgZkngA lNSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=s44mYLGUlM6uamsgG+YNsLF+fke2Wh0JOve4ukdROjw=; b=nGrEXlZ7inAJ+ZYg5yBUWHtho6wLeU4K13CyhR+Y5Omkc10LYDeCF/+7w7iEvippLH 4UyaOROKsMcNIhsDriaQswXkYvKkTbaZTykjUshguTl6HubCvoUq3TPpF0X8k8vZxmVG uEw6Y//tE7AZc2FBWmMlVcRIIS4bFm34sXbjrQJ3eK7SXGbSdnTWTqtLFTwISOvlXFkC KvD7trXh29kj884Dhvh8IAngdKExXkY6L61YIAlYFjkZRm4oLOW2hKf3kdytga39qJSh EIRzFzVUP1Xk6sO8H+407eAmb+ovb9FAe0ZnH8bnSlIkxgIcGa6WLVN99+liZSxfzh4t q+aA== X-Gm-Message-State: AOAM532H09iwedDLOE1hmJVEhUnJAsHkpfKIxGcWV7+nIZ0SRcQHNgPP NjPhcIUwEf40+dLeez0/l88= X-Google-Smtp-Source: ABdhPJwv4YH7zOvp8RgF3T1iCe8hPLAZvyHbr7F5HKcBWYE1AeZQjIlKhLv46bNM+fPq1csO0nxMwg== X-Received: by 2002:adf:e5d0:: with SMTP id a16mr19599175wrn.340.1605906664235; Fri, 20 Nov 2020 13:11:04 -0800 (PST) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Craig Janeczek , Jiaxun Yang , Aurelien Jarno , Laurent Vivier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fredrik Noring , Aleksandar Rikalo , Richard Henderson , Huacai Chen , Paolo Bonzini Subject: [PATCH 26/26] MAINTAINERS: Add entry for MIPS Toshiba TCG Date: Fri, 20 Nov 2020 22:08:44 +0100 Message-Id: <20201120210844.2625602-27-f4bug@amsat.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201120210844.2625602-1-f4bug@amsat.org> References: <20201120210844.2625602-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Add an entry for the TCG core related to Toshiba TXx9. Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- Adding Fredrik Noring in case he wants to be notified of changes, patch conditional to his approval. --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b6d98b95c47..d97f0f1d66e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -253,6 +253,12 @@ R: Craig Janeczek S: Odd Fixes F: target/mips/vendor-xburst* =20 +MIPS TCG CPUs (Toshiba TX) +M: Philippe Mathieu-Daud=C3=A9 +R: Fredrik Noring +S: Odd Fixes +F: target/mips/vendor-tx* + MIPS TCG CPUs (nanoMIPS ISA) S: Orphan F: disas/nanomips.* --=20 2.26.2