From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70094.outbound.protection.outlook.com [40.107.7.94]) by sourceware.org (Postfix) with ESMTPS id F1188385734E for ; Fri, 29 Apr 2022 15:58:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F1188385734E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=syrmia.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=syrmia.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=QJNZ5eEEn/VAN7yuR6C5eRMMlB5/g2WQDnB/D17/hNFyEC6mZjIPGB/RRKV0OONSdaRzmQGEp26m1RJ05+/EOKMubpwk1KxPzmn3It8DuVbiVEuvr3Un2T90ZHMCQ+rjn58oLcZK6U7rVe5JhvmKn+Lpgvvi5VotjHQUpoB3g1I5OA2WlUFt5lJvSzI8ymKNQ41Bl8s1QKUNcFr/qczQtxWpIckCLRk1DH40ppASwq7Ht+pt+AsBfHJgGwbjvc9Kcn4NnCjMZRToE8cB17tbVhZ/DUnGVT8ILTuHkAjVNA2WbBMR9FtKxMnd1yKbroJrh7cP4I/qyGH8oiOqwZbFGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ZdXXAKPR6ANL1okrcT8eOzoA4n33n2r/qfWPdWFVfdc=; b=me5it1ZcntEuN1lu61COfoBuFuAv8fusT2tZF9IqWmp5owN4uS6yANCO4ekP5w2a1SmcnbA0kIRaVg/YcU2hPg4bJEXDOGUuSo4t3FtGzwhLYylQHNn84asJqpZ6BRn3SLSUTaFYKYJLjSjYCuanmHkr9/WxmWJVq9CfCdqGB0u3cQK7rSfqHavmz7BeWFF329ESoZeKK++4e3MQDER4BJzW2M584XrRWWhxLCPbZ9VQSFPHNR4nmb2kbRi7FnaPO9Ph2cSmCOio3injfpJTkrG+K53E10WiNkFpr8bj5+6HFojozyhDRcNsPAzL7+MRrfz6ZchBaKIxI1q3Ry3N4A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=syrmia.com; dmarc=pass action=none header.from=syrmia.com; dkim=pass header.d=syrmia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=syrmia.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ZdXXAKPR6ANL1okrcT8eOzoA4n33n2r/qfWPdWFVfdc=; b=SbqPvuUY8R3pwzrF4DAhDLerjsUEpu4MY5a1sg90cMKkNBgfQv84rx+zaUEX06FJwUmn2pL1p/FRu1XCnbiB0yTXFEDFvTFOKWQi4IOkTMpZK1RoSHyA+vasX0njLBzQjHjIpzdMG9sBewIXQB3zQiQud5bFKjVIDcA+zRvDYrc= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=syrmia.com; Received: from VI1PR0302MB3486.eurprd03.prod.outlook.com (2603:10a6:803:1e::32) by AM6PR03MB4069.eurprd03.prod.outlook.com (2603:10a6:20b:22::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5206.14; Fri, 29 Apr 2022 15:58:21 +0000 Received: from VI1PR0302MB3486.eurprd03.prod.outlook.com ([fe80::2d29:6a60:28e3:6e4f]) by VI1PR0302MB3486.eurprd03.prod.outlook.com ([fe80::2d29:6a60:28e3:6e4f%4]) with mapi id 15.20.5206.014; Fri, 29 Apr 2022 15:58:21 +0000 From: Aleksandar Rikalo To: gdb-patches@sourceware.org Subject: [PATCH 2/3] sim: Add nanoMIPS port Date: Fri, 29 Apr 2022 17:58:12 +0200 Message-Id: <20220429155813.388328-3-aleksandar.rikalo@syrmia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220429155813.388328-1-aleksandar.rikalo@syrmia.com> References: <20220429155813.388328-1-aleksandar.rikalo@syrmia.com> Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: VI1PR09CA0141.eurprd09.prod.outlook.com (2603:10a6:803:12c::25) To VI1PR0302MB3486.eurprd03.prod.outlook.com (2603:10a6:803:1e::32) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: bec52c82-8553-4c7b-a154-08da29f91592 X-MS-TrafficTypeDiagnostic: AM6PR03MB4069:EE_ X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Bhgv71VJePzUyU1zoNqpBiG/HDxHjsVyVI3qYN3JQytc0PSe+jwCFmW2uKzQ3z0D9lMwhSRUOek7YSDk0op6iDT6R9U6zSx1CfYOIBIOeQuDe9MtFfyLb0D2njzt2eoi0lh3F39QlFkB5wD0nK6UDzrcaPtbxCKOpTx/RfHNojzrvpVzwzr+ndf93oWknGdjXgmPflFcoqYrjzZT/EFJNEpAWuVynPXyPLo8klCsD9yJyX7Bl4p9RHmTIUOM+dlHpAWo/IG2/wC/QYvpyRG6efXzdT7iuILEoAXAV/4pQNB88yeMfDbu4U8ht4lnoBjZ8WwAtMSrrp+5AigMrsME5foKs6IjqJ5+h1oC5kr0LBh5ozQXy2WLIVTKLHMb7jpeMw8Ed1wxgxHDCEvMKnUrMp3oxlK9Rk2b6RpvsSjadbSUb6xMpx0cyr6DQiiQllzwMphvTBXfv8CBXcwU2Uh8wYA0Xy/u4MtxHU2YwFLtXiOYGbhbayQQl8UD4ftUvyo0JunlLZ1Kuw/UWhTfSe4ehjUPf7WdXtGFxANb6LsLCmpoqFaQ8LVbk36RWxoN6WW4nreCkSpbKpp3ikaNa3YXE7Mbvnva9wi/z1IU0wjCzFO8dMpxARTSUaYgqrGwy+eNFgkfBGJ8t01lMB1/0XcU0DvjhcLNSCfjFBQie7VcN2PU0KuLZU30DDNtvRBXfz2e9flfIwP2rNx8xmlBC1Xl9BiRapmm0XaVN0tXQXImthx1frUYJnbOcdUv43K9742GtaAuuR4pRdLFdlGxwLGoOOv+YYg0RAf7OkmBw4PO9CVkipkPFPDliIZzYY+/7ntvIneU6mrLyKVjczoo46yftoOwldK6T8XBDEtMMsBA9wgkZ+FC3pBD4ngd8yTvf+TF X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR0302MB3486.eurprd03.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230001)(396003)(376002)(136003)(346002)(366004)(39830400003)(52116002)(6506007)(36756003)(6666004)(66476007)(8676002)(83380400001)(66946007)(66556008)(2906002)(186003)(30864003)(1076003)(19627235002)(86362001)(6512007)(44832011)(26005)(2616005)(316002)(8936002)(38350700002)(38100700002)(6486002)(6916009)(5660300002)(508600001)(2004002)(21314003)(579004)(559001)(473944003)(357404004); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?emzhJo9QmuDQ8H+kRIM92P10no6LWQPRnVIMrGFMggQqzXjCJVc9sAB5ej5T?= =?us-ascii?Q?BQAntNsbhdEidWj/EKAfzFmgbQERSLcmkC8gVvC4qW8u3i8EMyB8EZJxnlut?= =?us-ascii?Q?jZBAEzG+3uSrwUUJdg5wj++uWT5QvNBX/aG4zIVRb+h5QNFA5d6Od1gzWXcP?= =?us-ascii?Q?pcfzUtl6JC+/YM+e7S3QQ2ZB+QrWRHqaalsvx2KFQvCtqkF77ObgpK21o01y?= =?us-ascii?Q?CFFZ9hyRpeReK3iLAdBqe0bIflvQz9OIYaDWYJAx5eviYfuPiToleeWis1/I?= =?us-ascii?Q?m46LvFy3n4haazNrXxnTImOpn6djEjr8gQtQU8zBKRbi1V6NbnmmacYGiMwj?= =?us-ascii?Q?6t0DgVqqfKt/V6mhaxgMVH7uY6rWtWYAApHmRQmw3Yd+nOGb6/Vqh1OZQTpN?= =?us-ascii?Q?qRg6heiy2VjTU3RRCmkl4KXOSz+akYgaoegNZaYtZnoeN1nFNJm8y5cR9Vzr?= =?us-ascii?Q?WWzz62GLNzql3FU5xFwefdutf4DCM7XOgN5PN+JpA/Ug9XygyGI/B1++39cY?= =?us-ascii?Q?8iyK8C0ZwXh4pyyYUvfPH4m7fOMneHAPL6EOi+0M6OILy/TvA28mw1YDF9aV?= =?us-ascii?Q?aP/Me/cFkzQLUjcxu4v3W2OnMnVOx7xA5x2/ytWDBjLSgUfsTB6bBPAKLtKF?= =?us-ascii?Q?Cex/0LPvY1uMPTmxiM66lELy4lFKCl8eRj/NaQDEm9byUVdVIwPah1a7cpP4?= =?us-ascii?Q?/Pons35k/MqvhQgcjMY8U0FDGy+cb8kjFHr5HDr/Qt4koqt4HMJkk7g9uenc?= =?us-ascii?Q?jWS/UmLyooxxoAmmmsAPlCeZ/4RR2VPQEOGO92Lr1DxG9FCp8GUmoWO5GY3l?= =?us-ascii?Q?9sF6CJirWRZFp0CZz+IfMhTvD7rNa43hk2UoQC/UXa3DVIcnvFjAGiztm9B0?= =?us-ascii?Q?lISSDYUIt+r7sF05crytO7f2g6KdTSfKayKSX3PPDQCg0YgyQQLSx8WVL2H8?= =?us-ascii?Q?TBIzSvIUqTVox11RRlcWB1m8wgTXs4fjInPC8VA5gTLwTdGfI6BpHq4Bw9gq?= =?us-ascii?Q?DvQSqC5GEvQI+cIiUD9XIFSEAK6uzEVbRXsfvK3uIf46uhAlYZxyo7SCbHYE?= =?us-ascii?Q?PBFl7dgUdOK3yysmxvFVlCPoyp26wUgvxvdn4Gba1HuX4kVlwAM972lXfI9o?= =?us-ascii?Q?3XKlFZbKJLg9vE64zpJ4JPJekxOLvN3OwxuW09KD1omvX1bKm9hxRy3dtIdI?= =?us-ascii?Q?VnsKRk3KacEuk40IcQpEyfMgf8GjobK18aK22OoI613MB6OXbctY5h9WUksc?= =?us-ascii?Q?C2uPa/1oWp4ypB2RWlzbGkBDhg5D7dCMiikwpu28BwazZcIG/ahDrDH1DCdQ?= =?us-ascii?Q?qU5ZsQTf/65221GToBF5WnNMs+m8OqYBpV1m2NM9E+FiZ9By1XCJnpuQbRY5?= =?us-ascii?Q?pxqbHjx5ufBZckke/fCP2159uFd4UfW5vX+6vt78tPVhomZhb8jX8zXVEayx?= =?us-ascii?Q?iup6kixzt6TiRG2oBJfsedejgcjgEQdAdN3YiwQ4dq3rmHxHCdU/jjyvJpSZ?= =?us-ascii?Q?YtA1s8jnu70Fpm/NDeTf4eywz6PrGYRIZNAXm38NMKAm/h2Mvm9FG+HWjn/g?= =?us-ascii?Q?GMJBJBpuAQJ+59gp8jCpKhCzO3cLwUjVoytIt51Y5V9KX8OWp7Th05XgHsWW?= =?us-ascii?Q?gOlWmYZvKYP03gjpjnVd7bb+NMqKtO9wai8vIZctus1mHHZ8Y6iWCYFhRN/n?= =?us-ascii?Q?GvMadEbXGjBnBRdPTJevi3T0GDkrTpHac8BZMb8hTHhBCMJ6RSM/C86X4Caq?= =?us-ascii?Q?0CI3Z8xSE7ONmnIUwgekCWtRkuwzJJU=3D?= X-OriginatorOrg: syrmia.com X-MS-Exchange-CrossTenant-Network-Message-Id: bec52c82-8553-4c7b-a154-08da29f91592 X-MS-Exchange-CrossTenant-AuthSource: VI1PR0302MB3486.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Apr 2022 15:58:21.5466 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 19214a73-c1ab-4e19-8f59-14bdcb09a66e X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: bxhKt02d8jOhDKBs8YEpHNUURyOUVXf39OtVYfrKdK1kBavGATTFdWE5W2ByOM3oHkRXqBPtFxid4VVjsN8yPu8TknDTKgR/cWruEYYRFDk= X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR03MB4069 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Apr 2022 15:58:39 -0000 Co-Authored-By: Jaydeep Patil Co-Authored-By: Matthew Fortune Co-Authored-By: Maciej W. Rozycki Co-Authored-By: Stefan Markovic Co-Authored-By: Sara Graovac Co-Authored-By: Dragan Mladjenovic --- sim/common/sim-bits.h | 4 + sim/configure | 8 + sim/mips/Makefile.in | 42 + sim/mips/configure | 71 + sim/mips/configure.ac | 28 + sim/mips/interp.c | 75 +- sim/mips/micromips.igen | 22 +- sim/mips/micromips16.dc | 3 + sim/mips/mips.igen | 441 +++-- sim/mips/nanomipsdsp.igen | 1116 +++++++++++++ sim/mips/nanomipsr6.igen | 3283 +++++++++++++++++++++++++++++++++++++ sim/mips/nanomipsrun.c | 109 ++ sim/mips/nms.c | 44 + sim/mips/sim-main.c | 87 +- sim/mips/sim-main.h | 154 +- 15 files changed, 5321 insertions(+), 166 deletions(-) create mode 100644 sim/mips/nanomipsdsp.igen create mode 100644 sim/mips/nanomipsr6.igen create mode 100644 sim/mips/nanomipsrun.c create mode 100644 sim/mips/nms.c diff --git a/sim/common/sim-bits.h b/sim/common/sim-bits.h index fab1dab478c..8799916de26 100644 --- a/sim/common/sim-bits.h +++ b/sim/common/sim-bits.h @@ -499,15 +499,19 @@ INLINE_SIM_BITS(unsigned_word) MSINSERTED (unsigned_word val, int start, int sto #define EXTEND4(X) (LSSEXT ((X), 3)) #define EXTEND5(X) (LSSEXT ((X), 4)) #define EXTEND6(X) (LSSEXT ((X), 5)) +#define EXTEND7(X) (LSSEXT ((X), 6)) #define EXTEND8(X) ((signed_word)(int8_t)(X)) #define EXTEND9(X) (LSSEXT ((X), 8)) +#define EXTEND10(X) (LSSEXT ((X), 9)) #define EXTEND11(X) (LSSEXT ((X), 10)) #define EXTEND12(X) (LSSEXT ((X), 11)) +#define EXTEND14(X) (LSSEXT ((X), 13)) #define EXTEND15(X) (LSSEXT ((X), 14)) #define EXTEND16(X) ((signed_word)(int16_t)(X)) #define EXTEND18(X) (LSSEXT ((X), 17)) #define EXTEND19(X) (LSSEXT ((X), 18)) #define EXTEND21(X) (LSSEXT ((X), 20)) +#define EXTEND22(X) (LSSEXT ((X), 21)) #define EXTEND24(X) (LSSEXT ((X), 23)) #define EXTEND25(X) (LSSEXT ((X), 24)) #define EXTEND26(X) (LSSEXT ((X), 25)) diff --git a/sim/configure b/sim/configure index b31c2f5d8f3..cc2d957192f 100755 --- a/sim/configure +++ b/sim/configure @@ -15298,6 +15298,14 @@ fi sim_enable_arch_mips=true sim_igen=yes ;; + nanomips*-*-*) + + sim_arch=mips + subdirs="$subdirs mips" + + sim_igen=yes + ;; + esac diff --git a/sim/mips/Makefile.in b/sim/mips/Makefile.in index 75438be5a18..6bf2d14bdef 100644 --- a/sim/mips/Makefile.in +++ b/sim/mips/Makefile.in @@ -61,6 +61,7 @@ SIM_OBJS = \ cp1.o \ mdmx.o \ dsp.o \ + nms.o \ sim-main.o \ sim-resume.o \ @@ -79,6 +80,20 @@ SIM_EXTRA_DEPS = itable.h ## COMMON_POST_CONFIG_FRAG +interp.o: $(srcdir)/interp.c sim-main.h itable.h + +m16run.o: sim-main.h m16_idecode.h m32_idecode.h m16run.c $(SIM_EXTRA_DEPS) + +micromipsrun.o: sim-main.h micromips16_idecode.h micromips32_idecode.h \ + micromips_m32_idecode.h micromipsrun.c $(SIM_EXTRA_DEPS) + +nms.o: $(srcdir)/nms.c $(srcdir)/sim-main.h + +multi-run.o: multi-include.h tmp-mach-multi + +../igen/igen: + cd ../igen && $(MAKE) + IGEN_TRACE= # -G omit-line-numbers # -G trace-rule-selection -G trace-rule-rejection -G trace-entries # -G trace-all IGEN_INSN=$(srcdir)/mips.igen IGEN_DC=$(srcdir)/mips.dc @@ -99,6 +114,8 @@ IGEN_INCLUDE=\ $(srcdir)/dsp2.igen \ $(srcdir)/mips3264r2.igen \ $(srcdir)/mips3264r6.igen \ + $(srcdir)/nanomipsdsp.igen \ + $(srcdir)/nanomipsr6.igen # NB: Since these can be built by a number of generators, care # must be taken to ensure that they are only dependant on @@ -463,8 +480,11 @@ tmp-mach-multi: $(IGEN_INSN) $(IGEN_DC) $(IGEN) $(IGEN_INCLUDE) f=`echo $${t} | sed -e 's/.*://'` ; \ case $${p} in \ micromips16*) e="-B 16 -H 15 -o $(MICROMIPS16_DC) -F 16" ;; \ + nanomips16*) e="-B 16 -H 15 -o $(MICROMIPS16_DC) -F 16" ;; \ micromips32* | micromips64*) \ e="-B 32 -H 31 -o $(MICROMIPS32_DC) -F $${f}" ;; \ + nanomips32* | nanomips64*) \ + e="-B 32 -H 31 -o $(MICROMIPS32_DC) -F $${f}" ;; \ micromips_m32*) \ e="-B 32 -H 31 -o $(IGEN_DC) -F $${f}"; \ m="mips32r2,mips3d,mdmx,dsp,dsp2,smartmips" ;; \ @@ -579,6 +599,28 @@ tmp-run-multi: $(srcdir)/m16run.c $(srcdir)/micromipsrun.c $(SHELL) $(srcdir)/../../move-if-change tmp-run \ micromips$${m}_run.c ; \ ;;\ + nanomips32*) \ + m=`echo $${t} | sed -e 's/^nanomips32//' -e 's/:.*//'`; \ + sed < $(srcdir)/nanomipsrun.c > tmp-run \ + -e "s/^sim_/nanomips32$${m}_/" \ + -e "s/nanomips_instruction_decode/nanomips32$${m}_instruction_decode/g" \ + -e "s/nanomips16_/nanomips16$${m}_/" \ + -e "s/nanomips32_/nanomips32$${m}_/" \ + -e "s/m32_/m32$${m}_/" ; \ + $(SHELL) $(srcdir)/../../move-if-change tmp-run \ + nanomips$${m}_run.c ; \ + ;;\ + nanomips64*) \ + m=`echo $${t} | sed -e 's/^nanomips64//' -e 's/:.*//'`; \ + sed < $(srcdir)/nanomipsrun.c > tmp-run \ + -e "s/^sim_/nanomips64$${m}_/" \ + -e "s/nanomips_instruction_decode/nanomips64$${m}_instruction_decode/g" \ + -e "s/nanomips16_/nanomips16$${m}_/" \ + -e "s/nanomips32_/nanomips64$${m}_/" \ + -e "s/m32_/m64$${m}_/" ; \ + $(SHELL) $(srcdir)/../../move-if-change tmp-run \ + nanomips$${m}_run.c ; \ + ;;\ esac \ done $(SILENCE) touch $@ diff --git a/sim/mips/configure b/sim/mips/configure index 2f635a50e10..1438951b5d1 100755 --- a/sim/mips/configure +++ b/sim/mips/configure @@ -1874,6 +1874,12 @@ case "${target}" in mipsisa64r6:mips64r6:32,64,f:mipsisa32r6,mipsisa64r6" sim_multi_default=mipsisa64r2 ;; + nanomips*-elf*) + sim_gen=MULTI + sim_multi_configs="\ + nanor6sim:nanomips64r6,nanomipsdsp:32,64,f:nanomipsisa64r6,nanomipsisa32r6" + sim_multi_default=nanomipsisa32r6 + ;; mips64*-*-*) sim_igen_filter="32,64,f" sim_gen=IGEN ;; @@ -2072,6 +2078,17 @@ __EOF__ sim_multi_obj="${sim_multi_obj} micromips${name}_run.o" sim_multi_flags="${sim_multi_flags} -F 16,32" ;; + *:*nanomips32*) + # Run igen twice, once for nanomips32 and once for nanomips16. + ws="nanomips16 nanomips32" + + # The top-level function for the micromips simulator is + # in a file micromips${name}_run.c, generated by the + # tmp-run-multi Makefile rule. + sim_multi_src="${sim_multi_src} nanomips${name}_run.c" + sim_multi_obj="${sim_multi_obj} nanomips${name}_run.o" + sim_multi_flags="${sim_multi_flags} -F 16,32" + ;; *:*micromips64*:*) # Run igen thrice, once for micromips64, once for micromips16, # and once for m64. @@ -2084,6 +2101,17 @@ __EOF__ sim_multi_obj="${sim_multi_obj} micromips${name}_run.o" sim_multi_flags="${sim_multi_flags} -F 16,32,64" ;; + *:*nanomips64*) + # Run igen twice, once for nanomips64 and once for nanomips16. + ws="nanomips16 nanomips64" + + # The top-level function for the micromips simulator is + # in a file micromips${name}_run.c, generated by the + # tmp-run-multi Makefile rule. + sim_multi_src="${sim_multi_src} nanomips${name}_run.c" + sim_multi_obj="${sim_multi_obj} nanomips${name}_run.o" + sim_multi_flags="${sim_multi_flags} -F 16,32,64" + ;; *) ws=m32 ;; @@ -2126,6 +2154,8 @@ __EOF__ } } +int +mips_mach_multi (SIM_DESC sd); int mips_mach_multi (SIM_DESC sd) { @@ -2155,6 +2185,47 @@ __EOF__ return bfd_mach_${sim_multi_default}; } } + +address_word +micromips_instruction_decode_multi (SIM_DESC sd, + sim_cpu* cpu, + address_word cia, + int instruction_size) +{ + unsigned long bfdmach; + if (STATE_ARCHITECTURE(SD) == NULL) + bfdmach = bfd_mach_${sim_multi_default}; + else + bfdmach = STATE_ARCHITECTURE(SD)->mach; + + switch (bfdmach) + { +__EOF__ + + # Add a case statement for each micromips-enabled engine + for fc in ${micromips_configs}; do + machine=`echo ${fc} | sed 's/.*:\(.*\):.*:.*:.*:.*/\1/'` + name=`echo ${fc} | sed 's/:.*//'` + bfdmachs=`echo ${fc} | sed 's/.*:.*:.*:.*:\(.*\):.*/\1/'` + case ${machine} in + micromips*) + for bfdmach in `echo ${bfdmachs} | sed 's/,/ /g'`; do + echo " case bfd_mach_${bfdmach}:" >> multi-run.c + done + echo " return ${name}_instruction_decode (sd, cpu, cia, instruction_size);" >> multi-run.c + ;; + *) + ;; + esac + done + + cat << __EOF__ >> multi-run.c + default: + fprintf(stderr, "no valid micromips instruction decoder for this micromips engine\n"); + abort(); + break; + } +} __EOF__ SIM_SUBTARGET="$SIM_SUBTARGET -DMIPS_MACH_MULTI" diff --git a/sim/mips/configure.ac b/sim/mips/configure.ac index 96806424958..0d48b9630d9 100644 --- a/sim/mips/configure.ac +++ b/sim/mips/configure.ac @@ -106,6 +106,12 @@ case "${target}" in mipsisa64r6:mips64r6:32,64,f:mipsisa32r6,mipsisa64r6" sim_multi_default=mipsisa64r2 ;; + nanomips*-*-elf*) + sim_gen=MULTI + sim_multi_configs="\ + nanor6sim:nanomips64r6,nanomipsdsp:32,64,f:nanomipsisa64r6,nanomipsisa32r6" + sim_multi_default=nanomipsisa64r6 + ;; mips64*-*-*) sim_igen_filter="32,64,f" sim_gen=IGEN ;; @@ -304,6 +310,17 @@ __EOF__ sim_multi_obj="${sim_multi_obj} micromips${name}_run.o" sim_multi_flags="${sim_multi_flags} -F 16,32" ;; + *:*nanomips32*) + # Run igen twice, once for nanomips32 and once for nanomips16. + ws="nanomips16 nanomips32" + + # The top-level function for the micromips simulator is + # in a file micromips${name}_run.c, generated by the + # tmp-run-multi Makefile rule. + sim_multi_src="${sim_multi_src} nanomips${name}_run.c" + sim_multi_obj="${sim_multi_obj} nanomips${name}_run.o" + sim_multi_flags="${sim_multi_flags} -F 16,32" + ;; *:*micromips64*:*) # Run igen thrice, once for micromips64, once for micromips16, # and once for m64. @@ -316,6 +333,17 @@ __EOF__ sim_multi_obj="${sim_multi_obj} micromips${name}_run.o" sim_multi_flags="${sim_multi_flags} -F 16,32,64" ;; + *:*nanomips64*) + # Run igen twice, once for nanomips64 and once for nanomips16. + ws="nanomips16 nanomips64" + + # The top-level function for the micromips simulator is + # in a file micromips${name}_run.c, generated by the + # tmp-run-multi Makefile rule. + sim_multi_src="${sim_multi_src} nanomips${name}_run.c" + sim_multi_obj="${sim_multi_obj} nanomips${name}_run.o" + sim_multi_flags="${sim_multi_flags} -F 16,32,64" + ;; *) ws=m32 ;; diff --git a/sim/mips/interp.c b/sim/mips/interp.c index c5d0901428b..eba56df0a3e 100644 --- a/sim/mips/interp.c +++ b/sim/mips/interp.c @@ -140,6 +140,7 @@ static SIM_ADDR lsipmon_monitor_base = 0xBFC00200; static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg); +int is_nanomips = 0; #define MEM_SIZE (8 << 20) /* 8 MBytes */ @@ -672,10 +673,13 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE; else if ((rn >= 33) && (rn <= 37)) cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE; + else if ((rn >= 70) && (rn <= 78)) + cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE; else if ((rn == SRIDX) || (rn == FCR0IDX) || (rn == FCR31IDX) - || ((rn >= 72) && (rn <= 89))) + || (rn == DSPCRIDX) + || ((rn >= 80) && (rn <= 89))) cpu->register_widths[rn] = 32; else cpu->register_widths[rn] = 0; @@ -1200,7 +1204,7 @@ sim_monitor (SIM_DESC sd, case 6: /* int open(char *path,int flags) */ { char *path = fetch_str (sd, A0); - V0 = sim_io_open (sd, path, (int)A1); + SET_RV0 (sim_io_open (sd, path, (int)A1)); free (path); break; } @@ -1210,7 +1214,7 @@ sim_monitor (SIM_DESC sd, int fd = A0; int nr = A2; char *buf = zalloc (nr); - V0 = sim_io_read (sd, fd, buf, nr); + SET_RV0 (sim_io_read (sd, fd, buf, nr)); sim_write (sd, A1, (unsigned char *)buf, nr); free (buf); } @@ -1222,7 +1226,7 @@ sim_monitor (SIM_DESC sd, int nr = A2; char *buf = zalloc (nr); sim_read (sd, A1, (unsigned char *)buf, nr); - V0 = sim_io_write (sd, fd, buf, nr); + SET_RV0 (sim_io_write (sd, fd, buf, nr)); if (fd == 1) sim_io_flush_stdout (sd); else if (fd == 2) @@ -1233,14 +1237,14 @@ sim_monitor (SIM_DESC sd, case 10: /* int close(int file) */ { - V0 = sim_io_close (sd, (int)A0); + SET_RV0 (sim_io_close (sd, (int)A0)); break; } case 2: /* Densan monitor: char inbyte(int waitflag) */ { if (A0 == 0) /* waitflag == NOWAIT */ - V0 = (unsigned_word)-1; + SET_RV0 ((unsigned_word)-1); } /* Drop through to case 11 */ @@ -1252,10 +1256,10 @@ sim_monitor (SIM_DESC sd, if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char)) { sim_io_error(sd,"Invalid return from character read"); - V0 = (unsigned_word)-1; + SET_RV0 ((unsigned_word)-1); } else - V0 = (unsigned_word)tmp; + SET_RV0 ((unsigned_word)tmp); break; } @@ -1531,21 +1535,26 @@ store_word (SIM_DESC sd, uword64 vaddr, signed_word val) { - address_word paddr = vaddr; + address_word paddr; + int uncached; if ((vaddr & 3) != 0) SignalExceptionAddressStore (); else { - const uword64 mask = 7; - uword64 memval; - unsigned int byte; - - paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)); - byte = (vaddr & mask) ^ (BigEndianCPU << 2); - memval = ((uword64) val) << (8 * byte); - StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr, - isREAL); + if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, + isTARGET, isREAL)) + { + const uword64 mask = 7; + uword64 memval; + unsigned int byte; + + paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)); + byte = (vaddr & mask) ^ (BigEndianCPU << 2); + memval = ((uword64) val) << (8 * byte); + StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr, + isREAL); + } } } @@ -1567,18 +1576,24 @@ load_word (SIM_DESC sd, } else { - address_word paddr = vaddr; - const uword64 mask = 0x7; - const unsigned int reverse = ReverseEndian ? 1 : 0; - const unsigned int bigend = BigEndianCPU ? 1 : 0; - uword64 memval; - unsigned int byte; - - paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2)); - LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA, - isREAL); - byte = (vaddr & mask) ^ (bigend << 2); - return EXTEND32 (memval >> (8 * byte)); + address_word paddr; + int uncached; + + if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, + isTARGET, isREAL)) + { + const uword64 mask = 0x7; + const unsigned int reverse = ReverseEndian ? 1 : 0; + const unsigned int bigend = BigEndianCPU ? 1 : 0; + uword64 memval; + unsigned int byte; + + paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2)); + LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr, + isDATA, isREAL); + byte = (vaddr & mask) ^ (bigend << 2); + return EXTEND32 (memval >> (8 * byte)); + } } return 0; diff --git a/sim/mips/micromips.igen b/sim/mips/micromips.igen index bb61b3f26e6..55545403a4b 100644 --- a/sim/mips/micromips.igen +++ b/sim/mips/micromips.igen @@ -42,6 +42,7 @@ *micromips32: *micromips64: *micromipsdsp: +*nanomipsdsp: { instruction_word delay_insn; sim_events_slip (SD, 1); @@ -49,7 +50,7 @@ CIA = nia; STATE |= simDELAYSLOT; ENGINE_ISSUE_PREFIX_HOOK(); - micromips_instruction_decode (SD, CPU, CIA, delayslot_instruction_size); + MICROMIPS_INSTRUCTION_DECODE (SD, CPU, CIA, delayslot_instruction_size); STATE &= ~simDELAYSLOT; return target; } @@ -128,6 +129,8 @@ :function:::FP_formats:convert_fmt_micromips:int fmt *micromips32: *micromips64: +*nanomips32r6: +*nanomips64r6: { switch (fmt) { @@ -141,6 +144,8 @@ :function:::FP_formats:convert_fmt_micromips_cvt_d:int fmt *micromips32: *micromips64: +*nanomips32r6: +*nanomips64r6: { switch (fmt) { @@ -155,6 +160,8 @@ :function:::FP_formats:convert_fmt_micromips_cvt_s:int fmt *micromips32: *micromips64: +*nanomips32r6: +*nanomips64r6: { switch (fmt) { @@ -865,8 +872,11 @@ address_word base = GPR[BASE]; address_word offset = EXTEND12 (IMMEDIATE); address_word vaddr = loadstore_ea (SD_, base, offset); - address_word paddr = vaddr; - CacheOp (OP, vaddr, paddr, instruction_0); + address_word paddr; + int uncached; + if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, + isTARGET, isREAL)) + CacheOp (OP, vaddr, paddr, instruction_0); } @@ -2275,6 +2285,8 @@ :%s::::FMT_MICROMIPS:int fmt *micromips32: *micromips64: +*nanomips32r6: +*nanomips64r6: { switch (fmt) { @@ -2289,6 +2301,8 @@ :%s::::FMT_MICROMIPS_CVT_D:int fmt *micromips32: *micromips64: +*nanomips32r6: +*nanomips64r6: { switch (fmt) { @@ -2303,6 +2317,8 @@ :%s::::FMT_MICROMIPS_CVT_S:int fmt *micromips32: *micromips64: +*nanomips32r6: +*nanomips64r6: { switch (fmt) { diff --git a/sim/mips/micromips16.dc b/sim/mips/micromips16.dc index a1cd9a0ea89..ace9bb94fad 100644 --- a/sim/mips/micromips16.dc +++ b/sim/mips/micromips16.dc @@ -8,4 +8,7 @@ switch,combine : 9 : 6 : : : : : : switch,combine : 9 : 5 : : : : : : + switch,combine : 3 : 0 : : : : : : + switch,combine : 2 : 0 : : : : : : + switch,combine : 5 : 3 : : : : : : switch,combine : 0 : 0 : : : : : : diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen index dfad4227615..8f427ce258b 100644 --- a/sim/mips/mips.igen +++ b/sim/mips/mips.igen @@ -79,6 +79,9 @@ :model:::micromips32:micromips64: // micromips.igen :model:::micromips64:micromips64: // micromips.igen :model:::micromipsdsp:micromipsdsp: // micromipsdsp.igen +:model:::nanomips32r6:nanomips32r6: // nanomipsr6.igen +:model:::nanomips64r6:nanomips64r6: // nanomipsr6.igen +:model:::nanomipsdsp:nanomipsdsp: // nanompsdsp.igen // Vendor Extensions // @@ -98,6 +101,31 @@ // For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK 000000,5.*,5.*,5.*,5.OP,111001:SPECIAL:32::RSVD "rsvd " +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*mips32: +*mips32r2: +*mips64: +*mips64r2: +*vr4100: +*vr4120: +*vr5000: +*vr5400: +*vr5500: +*r3900: +*mips16: +*mips16e: +*mips3d: +*mdmx: +*dsp: +*dsp2: +*smartmips: +*micromips32: +*micromips64: +*micromipsdsp: { SignalException (ReservedInstruction, instruction_0); } @@ -192,6 +220,7 @@ *vr5000: *r3900: *micromips32: +*nanomips32r6: { return base + offset; } @@ -201,6 +230,7 @@ *mips64r2: *micromips64: *mips64r6: +*nanomips64r6: { #if 0 /* XXX FIXME: enable this only after some additional testing. */ /* If in user mode and UX is not set, use 32-bit compatibility effective @@ -237,6 +267,8 @@ *micromips32: *micromips64: *mips64r6: +*nanomips32r6: +*nanomips64r6: { #if WITH_TARGET_WORD_BITSIZE == 64 return value != (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); @@ -274,6 +306,8 @@ *micromips32: *micromips64: *mips64r6: +*nanomips32r6: +*nanomips64r6: { unpredictable_action (CPU, CIA); } @@ -369,6 +403,7 @@ *r3900: *micromips32: *micromips64: +*nanomipsdsp: { int64_t time = sim_events_time (SD); history->mt.timestamp = time; @@ -399,6 +434,7 @@ *r3900: *micromips32: *micromips64: +*nanomipsdsp: { int64_t time = sim_events_time (SD); int ok = 1; @@ -473,6 +509,7 @@ *r3900: *micromips32: *micromips64: +*nanomipsdsp: { /* FIXME: could record the fact that a stall occured if we want */ int64_t time = sim_events_time (SD); @@ -570,6 +607,8 @@ *micromips64: *micromips32: *mips64r6: +*nanomips32r6: +*nanomips64r6: { #if 0 /* XXX FIXME: enable this only after some additional testing. */ if (UserMode && (SR & (status_UX|status_PX)) == 0) @@ -781,12 +820,44 @@ } :function:::void:do_lb:int rt, int offset, int base +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*mips32: +*mips32r2: +*mips32r6: +*mips64: +*mips64r2: +*mips64r6: +*vr4100: +*vr5000: +*r3900: +*micromips32: +*micromips64: { GPR[rt] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[base], EXTEND16 (offset))); } :function:::void:do_lh:int rt, int offset, int base +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*mips32: +*mips32r2: +*mips32r6: +*mips64: +*mips64r2: +*mips64r6: +*vr4100: +*vr5000: +*r3900: +*micromips32: +*micromips64: { GPR[rt] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base], EXTEND16 (offset))); @@ -811,6 +882,22 @@ } :function:::void:do_lw:int rt, int offset, int base +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*mips32: +*mips32r2: +*mips32r6: +*mips64: +*mips64r2: +*mips64r6: +*vr4100: +*vr5000: +*r3900: +*micromips32: +*micromips64: { GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset))); @@ -823,6 +910,22 @@ } :function:::void:do_lhu:int rt, int offset, int base +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*mips32: +*mips32r2: +*mips32r6: +*mips64: +*mips64r2: +*mips64r6: +*vr4100: +*vr5000: +*r3900: +*micromips32: +*micromips64: { GPR[rt] = do_load (SD_, AccessLength_HALFWORD, GPR[base], EXTEND16 (offset)); } @@ -844,7 +947,8 @@ address_word offset = EXTEND16 (insn_offset); { address_word vaddr = loadstore_ea (SD_, base, offset); - address_word paddr = vaddr; + address_word paddr; + int uncached; if ((vaddr & 3) != 0) { SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer, @@ -852,19 +956,23 @@ } else { - uint64_t memval = 0; - uint64_t memval1 = 0; - uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); - unsigned int shift = 2; - unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0); - unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0); - unsigned int byte; - paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); - LoadMemory (&memval, &memval1, AccessLength_WORD, paddr, vaddr, - isDATA, isREAL); - byte = ((vaddr & mask) ^ (bigend << shift)); - GPR[rt] = EXTEND32 (memval >> (8 * byte)); - LLBIT = 1; + if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, + isTARGET, isREAL)) + { + uint64_t memval = 0; + uint64_t memval1 = 0; + uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); + unsigned int shift = 2; + unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory (&memval, &memval1, uncached, AccessLength_WORD, paddr, + vaddr, isDATA, isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[rt] = EXTEND32 (memval >> (8 * byte)); + LLBIT = 1; + } } } } @@ -875,8 +983,8 @@ address_word offset = EXTEND16 (roffset); { address_word vaddr = loadstore_ea (SD_, base, offset); - address_word paddr = vaddr; - + address_word paddr; + int uncached; if ((vaddr & 7) != 0) { SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer, @@ -884,12 +992,16 @@ } else { - uint64_t memval = 0; - uint64_t memval1 = 0; - LoadMemory (&memval, &memval1, AccessLength_DOUBLEWORD, paddr, vaddr, - isDATA, isREAL); - GPR[rt] = memval; - LLBIT = 1; + if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, + isTARGET, isREAL)) + { + uint64_t memval = 0; + uint64_t memval1 = 0; + LoadMemory (&memval, &memval1, uncached, AccessLength_DOUBLEWORD, + paddr, vaddr, isDATA, isREAL); + GPR[rt] = memval; + LLBIT = 1; + } } } } @@ -1137,8 +1249,13 @@ address_word offset = EXTEND16 (insn_offset); { address_word vaddr = loadstore_ea (SD_, base, offset); - address_word paddr = vaddr; - /* Prefetch (paddr, vaddr, isDATA, hint); */ + address_word paddr; + int uncached; + { + if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, + isTARGET, isREAL)) + Prefetch (uncached, paddr, vaddr, isDATA, hint); + } } } @@ -1149,8 +1266,8 @@ address_word offset = EXTEND16 (offsetarg); { address_word vaddr = loadstore_ea (SD_, base, offset); - address_word paddr = vaddr; - + address_word paddr; + int uncached; if ((vaddr & 3) != 0) { SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, @@ -1158,23 +1275,27 @@ } else { - uint64_t memval = 0; - uint64_t memval1 = 0; - uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); - address_word reverseendian = - (ReverseEndian ? (mask ^ AccessLength_WORD) : 0); - address_word bigendiancpu = - (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0); - unsigned int byte; - paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); - byte = ((vaddr & mask) ^ bigendiancpu); - memval = ((uint64_t) GPR[rt] << (8 * byte)); - if (LLBIT) - StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr, - isREAL); - if (store_ll_bit) - GPR[rt] = LLBIT; - } + if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, + isTARGET, isREAL)) + { + uint64_t memval = 0; + uint64_t memval1 = 0; + uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); + address_word reverseendian = + (ReverseEndian ? (mask ^ AccessLength_WORD) : 0); + address_word bigendiancpu = + (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0); + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); + byte = ((vaddr & mask) ^ bigendiancpu); + memval = ((uint64_t) GPR[rt] << (8 * byte)); + if (LLBIT) + StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr, vaddr, + isREAL); + if (store_ll_bit) + GPR[rt] = LLBIT; + } + } } } @@ -1184,8 +1305,8 @@ address_word offset = EXTEND16 (roffset); { address_word vaddr = loadstore_ea (SD_, base, offset); - address_word paddr = vaddr; - + address_word paddr; + int uncached; if ((vaddr & 7) != 0) { SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer, @@ -1193,15 +1314,19 @@ } else { + if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, + isTARGET, isREAL)) + { uint64_t memval = 0; uint64_t memval1 = 0; memval = GPR[rt]; if (LLBIT) - StoreMemory (AccessLength_DOUBLEWORD, memval, memval1, paddr, vaddr, + StoreMemory (uncached, AccessLength_DOUBLEWORD, memval, memval1, paddr, vaddr, isREAL); if (store_ll_bit) GPR[rt] = LLBIT; } + } } } @@ -1688,8 +1813,11 @@ address_word index = GPR[rindex]; { address_word vaddr = loadstore_ea (SD_, base, index); - address_word paddr = vaddr; - /* Prefetch (paddr, vaddr, isDATA, hint); */ + address_word paddr; + int uncached; + if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, + isREAL)) + Prefetch (uncached, paddr, vaddr, isDATA, hint); } } @@ -1753,8 +1881,8 @@ check_fpu (SD_); { address_word vaddr = loadstore_ea (SD_, base, offset); - address_word paddr = vaddr; - + address_word paddr; + int uncached; if ((vaddr & 3) != 0) { SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr, @@ -1762,18 +1890,23 @@ } else { - uword64 memval = 0; - uword64 memval1 = 0; - uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); - address_word reverseendian = - (ReverseEndian ? (mask ^ AccessLength_WORD) : 0); - address_word bigendiancpu = - (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0); - unsigned int byte; - paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); - byte = ((vaddr & mask) ^ bigendiancpu); - memval = (((uword64)COP_SW(1, ft)) << (8 * byte)); - StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr, isREAL); + if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, + isTARGET, isREAL)) + { + uword64 memval = 0; + uword64 memval1 = 0; + uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); + address_word reverseendian = + (ReverseEndian ?(mask ^ AccessLength_WORD): 0); + address_word bigendiancpu = + (BigEndianCPU ?(mask ^ AccessLength_WORD): 0); + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); + byte = ((vaddr & mask) ^ bigendiancpu); + memval = (((uword64)COP_SW(1, ft)) << (8 * byte)); + StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr, + vaddr, isREAL); + } } } } @@ -1786,8 +1919,8 @@ check_u64 (SD_, instruction_0); { address_word vaddr = loadstore_ea (SD_, base, index); - address_word paddr = vaddr; - + address_word paddr; + int uncached; if ((vaddr & 3) != 0) { SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, @@ -1795,19 +1928,23 @@ } else { - uint64_t memval = 0; - uint64_t memval1 = 0; - uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); - address_word reverseendian = - (ReverseEndian ? (mask ^ AccessLength_WORD) : 0); - address_word bigendiancpu = - (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0); - unsigned int byte; - paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); - byte = ((vaddr & mask) ^ bigendiancpu); - memval = (((uint64_t)COP_SW(1,fs)) << (8 * byte)); - StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr, - isREAL); + if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, + isTARGET, isREAL)) + { + uint64_t memval = 0; + uint64_t memval1 = 0; + uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); + address_word reverseendian = + (ReverseEndian ? (mask ^ AccessLength_WORD) : 0); + address_word bigendiancpu = + (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0); + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); + byte = ((vaddr & mask) ^ bigendiancpu); + memval = (((uint64_t)COP_SW(1,fs)) << (8 * byte)); + StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr, + vaddr, isREAL); + } } } } @@ -1861,7 +1998,23 @@ -:function:::void:do_addiu:int rs, int rt, uint16_t immediate +:function:::void:do_addiu:int rs, int rt, int immediate +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*mips32: +*mips32r2: +*mips32r6: +*mips64: +*mips64r2: +*mips64r6: +*vr4100: +*vr5000: +*r3900: +*micromips32: +*micromips64: { if (NotWordValue (GPR[rs])) Unpredictable (); @@ -2595,6 +2748,14 @@ :function:::void:do_ddiv:int rs, int rt +*mipsIII: +*mipsIV: +*mipsV: +*mips64: +*mips64r2: +*micromips64: +*vr4100: +*vr5000: { check_div_hilo (SD_, HIHISTORY, LOHISTORY); TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); @@ -2641,6 +2802,14 @@ :function:::void:do_ddivu:int rs, int rt +*mipsIII: +*mipsIV: +*mipsV: +*mips64: +*mips64r2: +*micromips64: +*vr4100: +*vr5000: { check_div_hilo (SD_, HIHISTORY, LOHISTORY); TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); @@ -2680,6 +2849,20 @@ } :function:::void:do_div:int rs, int rt +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*mips32: +*mips32r2: +*micromips32: +*mips64: +*mips64r2: +*micromips64: +*vr4100: +*vr5000: +*r3900: { check_div_hilo (SD_, HIHISTORY, LOHISTORY); TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); @@ -2726,6 +2909,20 @@ :function:::void:do_divu:int rs, int rt +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*mips32: +*mips32r2: +*micromips32: +*mips64: +*mips64r2: +*micromips64: +*vr4100: +*vr5000: +*r3900: { check_div_hilo (SD_, HIHISTORY, LOHISTORY); TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); @@ -3277,16 +3474,18 @@ address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0); unsigned int byte; address_word paddr; + int uncached; uint64_t memval; address_word vaddr; - paddr = vaddr = loadstore_ea (SD_, base, offset); + vaddr = loadstore_ea (SD_, base, offset); if ((vaddr & access) != 0) { SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal); } + AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL); paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); - LoadMemory (&memval, NULL, access, paddr, vaddr, isDATA, isREAL); + LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isDATA, isREAL); byte = ((vaddr & mask) ^ bigendiancpu); return (memval >> (8 * byte)); } @@ -3299,6 +3498,7 @@ unsigned int byte; unsigned int word; address_word paddr; + int uncached; uint64_t memval; address_word vaddr; int nr_lhs_bits; @@ -3306,7 +3506,8 @@ unsigned_word lhs_mask; unsigned_word temp; - paddr = vaddr = loadstore_ea (SD_, base, offset); + vaddr = loadstore_ea (SD_, base, offset); + AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL); paddr = (paddr ^ (reverseendian & mask)); if (BigEndianMem == 0) paddr = paddr & ~access; @@ -3323,7 +3524,7 @@ (long) ((uint64_t) paddr >> 32), (long) paddr, word, byte, nr_lhs_bits, nr_rhs_bits); */ - LoadMemory (&memval, NULL, byte, paddr, vaddr, isDATA, isREAL); + LoadMemory (&memval, NULL, uncached, byte, paddr, vaddr, isDATA, isREAL); if (word == 0) { /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */ @@ -3352,17 +3553,19 @@ address_word bigendiancpu = (BigEndianCPU ? -1 : 0); unsigned int byte; address_word paddr; + int uncached; uint64_t memval; address_word vaddr; - paddr = vaddr = loadstore_ea (SD_, base, offset); + vaddr = loadstore_ea (SD_, base, offset); + AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL); /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */ paddr = (paddr ^ (reverseendian & mask)); if (BigEndianMem != 0) paddr = paddr & ~access; byte = ((vaddr & mask) ^ (bigendiancpu & mask)); /* NOTE: SPEC is wrong, had `byte' not `access - byte'. See SW. */ - LoadMemory (&memval, NULL, access - (access & byte), paddr, vaddr, isDATA, isREAL); + LoadMemory (&memval, NULL, uncached, access - (access & byte), paddr, vaddr, isDATA, isREAL); /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n", (long) paddr, byte, (long) paddr, (long) memval); */ { @@ -3714,6 +3917,23 @@ :function:::void:do_mfhi:int rd +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*vr4100: +*vr5000: +*r3900: +*mips32: +*mips64: +*mips32r2: +*mips64r2: +*dsp: +*micromips32: +*micromips64: +*micromipsdsp: +*nanomipsdsp: { check_mf_hilo (SD_, HIHISTORY, LOHISTORY); TRACE_ALU_INPUT1 (HI); @@ -4175,18 +4395,20 @@ address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0); unsigned int byte; address_word paddr; + int uncached; uint64_t memval; address_word vaddr; - paddr = vaddr = loadstore_ea (SD_, base, offset); + vaddr = loadstore_ea (SD_, base, offset); if ((vaddr & access) != 0) { SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal); } + AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL); paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); byte = ((vaddr & mask) ^ bigendiancpu); memval = (word << (8 * byte)); - StoreMemory (access, memval, 0, paddr, vaddr, isREAL); + StoreMemory (uncached, access, memval, 0, paddr, vaddr, isREAL); } :function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt @@ -4197,12 +4419,14 @@ unsigned int byte; unsigned int word; address_word paddr; + int uncached; uint64_t memval; address_word vaddr; int nr_lhs_bits; int nr_rhs_bits; - paddr = vaddr = loadstore_ea (SD_, base, offset); + vaddr = loadstore_ea (SD_, base, offset); + AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL); paddr = (paddr ^ (reverseendian & mask)); if (BigEndianMem == 0) paddr = paddr & ~access; @@ -4229,7 +4453,7 @@ /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n", (long) ((uint64_t) rt >> 32), (long) rt, (long) ((uint64_t) memval >> 32), (long) memval); */ - StoreMemory (byte, memval, 0, paddr, vaddr, isREAL); + StoreMemory (uncached, byte, memval, 0, paddr, vaddr, isREAL); } :function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt @@ -4239,16 +4463,18 @@ address_word bigendiancpu = (BigEndianCPU ? -1 : 0); unsigned int byte; address_word paddr; + int uncached; uint64_t memval; address_word vaddr; - paddr = vaddr = loadstore_ea (SD_, base, offset); + vaddr = loadstore_ea (SD_, base, offset); + AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL); paddr = (paddr ^ (reverseendian & mask)); if (BigEndianMem != 0) paddr &= ~access; byte = ((vaddr & mask) ^ (bigendiancpu & mask)); memval = (rt << (byte * 8)); - StoreMemory (access - (access & byte), memval, 0, paddr, vaddr, isREAL); + StoreMemory (uncached, access - (access & byte), memval, 0, paddr, vaddr, isREAL); } @@ -5225,6 +5451,8 @@ *vr4100: *vr5000: *r3900: +*nanomips32r6: +*nanomips64r6: { /* None of these ISAs support Paired Single, so just fall back to the single/double check. */ @@ -5273,6 +5501,8 @@ *r3900: *micromips32: *micromips64: +*nanomips32r6: +*nanomips64r6: { if (! COP_Usable (1)) SignalExceptionCoProcessorUnusable (1); @@ -5316,20 +5546,24 @@ int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian); address_word vaddr; address_word paddr; + int uncached; uint64_t memval; uint64_t v; - paddr = vaddr = loadstore_ea (SD_, base, offset); + vaddr = loadstore_ea (SD_, base, offset); if ((vaddr & AccessLength_DOUBLEWORD) != 0) { SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, AccessLength_DOUBLEWORD + 1, vaddr, read_transfer, sim_core_unaligned_signal); } - LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA, isREAL); + AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, + isREAL); + LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr, vaddr, + isDATA, isREAL); v = (uint64_t)memval; - LoadMemory (&memval, NULL, AccessLength_WORD, paddr + 4, vaddr + 4, isDATA, - isREAL); + LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr + 4, vaddr + 4, + isDATA, isREAL); return (bigendian ? ((v << 32) | memval) : (v | (memval << 32))); } @@ -5351,19 +5585,24 @@ int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian); address_word vaddr; address_word paddr; + int uncached; uint64_t memval; - paddr = vaddr = loadstore_ea (SD_, base, offset); + vaddr = loadstore_ea (SD_, base, offset); if ((vaddr & AccessLength_DOUBLEWORD) != 0) { SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, AccessLength_DOUBLEWORD + 1, vaddr, write_transfer, sim_core_unaligned_signal); } + AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, + isREAL); memval = (bigendian ? (v >> 32) : (v & 0xFFFFFFFF)); - StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr, isREAL); + StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr, + isREAL); memval = (bigendian ? (v & 0xFFFFFFFF) : (v >> 32)); - StoreMemory (AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4, isREAL); + StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4, + isREAL); } @@ -6628,7 +6867,10 @@ { address_word vaddr = loadstore_ea (SD_, base, offset); address_word paddr = vaddr; - CacheOp(op, vaddr, paddr, instruction_0); + + int uncached; + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + CacheOp(op, vaddr, paddr, instruction_0); } } @@ -6867,4 +7109,5 @@ :include:::smartmips.igen :include:::micromips.igen :include:::micromipsdsp.igen - +:include:::nanomipsr6.igen +:include:::nanomipsdsp.igen diff --git a/sim/mips/nanomipsdsp.igen b/sim/mips/nanomipsdsp.igen new file mode 100644 index 00000000000..65d0282f325 --- /dev/null +++ b/sim/mips/nanomipsdsp.igen @@ -0,0 +1,1116 @@ +// Simulator definition for the micromips ASE. +// Copyright (C) 2018-2022 Free Software Foundation, Inc. +// Contributed by Imagination Technologies, Ltd. +// Written by Ali Lown +// +// This file is part of GDB, the GNU debugger. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +001000,5.RT,5.RS,0001000100111111:POOL32A:32::ABSQ_S.PH +"absq_s.ph r, r" +*nanomipsdsp: +{ + do_ph_s_absq (SD_, RT, RS); +} + +001000,5.RT,5.RS,0000000100111111:POOL32A:32::ABSQ_S.QB +"absq_s.qb r, r" +*nanomipsdsp: +{ + do_qb_s_absq (SD_, RT, RS); +} + +001000,5.RT,5.RS,0010000100111111:POOL32A:32::ABSQ_S.W +"absq_s.w r, r" +*nanomipsdsp: +{ + do_w_s_absq (SD_, RT, RS); +} + +001000,5.RT,5.RS,5.RD,00000001101:POOL32A:32::ADDQ.PH +"addq.ph r, r, r" +*nanomipsdsp: +{ + do_ph_op (SD_, RD, RS, RT, 0, 0); +} + +001000,5.RT,5.RS,5.RD,10000001101:POOL32A:32::ADDQ_S.PH +"addq_s.ph r, r, r" +*nanomipsdsp: +{ + do_ph_op (SD_, RD, RS, RT, 0, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,1100000101:POOL32A:32::ADDQ_S.W +"addq_s.w r, r, r" +*nanomipsdsp: +{ + do_w_op (SD_, RD, RS, RT, 0); +} + +001000,5.RT,5.RS,5.RD,00001001101:POOL32A:32::ADDQH.PH +"addqh.ph r, r, r" +*nanomipsdsp: +{ + do_qh_ph_op (SD_, RD, RS, RT, 0, 0); +} + +001000,5.RT,5.RS,5.RD,10001001101:POOL32A:32::ADDQH_R.PH +"addqh_r.ph r, r, r" +*nanomipsdsp: +{ + do_qh_ph_op (SD_, RD, RS, RT, 0, 1); +} + +001000,5.RT,5.RS,5.RD,00010001101:POOL32A:32::ADDQH.W +"addqh.w r, r, r" +*nanomipsdsp: +{ + do_qh_w_op (SD_, RD, RS, RT, 0, 0); +} + +001000,5.RT,5.RS,5.RD,10010001101:POOL32A:32::ADDQH_R.W +"addqh_r.w r, r, r" +*nanomipsdsp: +{ + do_qh_w_op (SD_, RD, RS, RT, 0, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,1110000101:POOL32A:32::ADDSC +"addsc r, r, r" +*nanomipsdsp: +{ + do_addsc (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.RD,00100001101:POOL32A:32::ADDU.PH +"addu.ph r, r, r" +*nanomipsdsp: +{ + do_u_ph_op (SD_, RD, RS, RT, 0, 0); +} + +001000,5.RT,5.RS,5.RD,10100001101:POOL32A:32::ADDU_S.PH +"addu_s.ph r, r, r" +*nanomipsdsp: +{ + do_u_ph_op (SD_, RD, RS, RT, 0, 1); +} + +001000,5.RT,5.RS,5.RD,00011001101:POOL32A:32::ADDU.QB +"addu.qb r, r, r" +*nanomipsdsp: +{ + do_qb_op (SD_, RD, RS, RT, 0, 0); +} + +001000,5.RT,5.RS,5.RD,10011001101:POOL32A:32::ADDU_S.QB +"addu_s.qb r, r, r" +*nanomipsdsp: +{ + do_qb_op (SD_, RD, RS, RT, 0, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,1111000101:POOL32A:32::ADDWC +"addwc r, r, r" +*nanomipsdsp: +{ + do_addwc (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.RD,00101001101:POOL32A:32::ADDUH.QB +"adduh.qb r, r, r" +*nanomipsdsp: +{ + do_uh_qb_op (SD_, RD, RS, RT, 0, 0); +} + +001000,5.RT,5.RS,5.RD,10101001101:POOL32A:32::ADDUH_R.QB +"adduh_r.qb r, r, r" +*nanomipsdsp: +{ + do_uh_qb_op (SD_, RD, RS, RT, 0, 1); +} + +001000,5.RT,5.RS,5.SA,1.X,1000010101:POOL32A:32::APPEND +"append r, r, " +*nanomipsdsp: +{ + do_append (SD_, RT, RS, SA); +} + +001000,5.RT,5.RS,2.BP,00100010111111:POOL32A:32::BALIGN +"balign r, r, " +*nanomipsdsp: +{ + do_balign (SD_, RT, RS, BP); +} + +001000,5.RT,5.RS,0011000100111111:POOL32A:32::BITREV +"bitrev r, r" +*nanomipsdsp: +{ + do_bitrev (SD_, RT, RS); +} + +100010,5.X,0010001,14.IMMEDIATE:POOL32I:32::BPOSGE32C +"bposge32c " +*nanomipsdsp: +{ + uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; + if (pos >= 32) + NIA = delayslot_micromips (SD_, NIA + (EXTEND12 (IMMEDIATE) << 1), NIA, + MICROMIPS_DELAYSLOT_SIZE_ANY); +} + +001000,5.RT,5.RS,6.X,0000000101:POOL32A:32::CMP.EQ.PH +"cmp.eq.ph r, r" +*nanomipsdsp: +{ + do_ph_cmpu (SD_, RS, RT, 0); +} + +001000,5.RT,5.RS,0000000001,000101:POOL32A:32::CMP.LT.PH +"cmp.lt.ph r, r" +*nanomipsdsp: +{ + do_ph_cmpu (SD_, RS, RT, 1); +} + +001000,5.RT,5.RS,0000000010,000101:POOL32A:32::CMP.LE.PH +"cmp.le.ph r, r" +*nanomipsdsp: +{ + do_ph_cmpu (SD_, RS, RT, 2); +} + +001000,5.RT,5.RS,5.RD,1.X,0110000101:POOL32A:32::CMPGDU.EQ.QB +"cmpgdu.eq.qb r, r, r" +*nanomipsdsp: +{ + do_qb_cmpgdu (SD_, RD, RS, RT, 0); +} + +001000,5.RT,5.RS,5.RD,1.X,0111000101:POOL32A:32::CMPGDU.LT.QB +"cmpgdu.lt.qb r, r, r" +*nanomipsdsp: +{ + do_qb_cmpgdu (SD_, RD, RS, RT, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,1000000101:POOL32A:32::CMPGDU.LE.QB +"cmpgdu.le.qb r, r, r" +*nanomipsdsp: +{ + do_qb_cmpgdu (SD_, RD, RS, RT, 2); +} + +001000,5.RT,5.RS,5.RD,1.X,0011000101:POOL32A:32::CMPGU.EQ.QB +"cmpgu.eq.qb r, r, r" +*nanomipsdsp: +{ + do_qb_cmpgu (SD_, RD, RS, RT, 0); +} + +001000,5.RT,5.RS,5.RD,1.X,0100000101:POOL32A:32::CMPGU.LT.QB +"cmpgu.lt.qb r, r, r" +*nanomipsdsp: +{ + do_qb_cmpgu (SD_, RD, RS, RT, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,0101000101:POOL32A:32::CMPGU.LE.QB +"cmpgu.le.qb r, r, r" +*nanomipsdsp: +{ + do_qb_cmpgu (SD_, RD, RS, RT, 2); +} + +001000,5.RT,5.RS,5.X1,1.X2,1001000101:POOL32A:32::CMPU.EQ.QB +"cmpu.eq.qb r, r" +*nanomipsdsp: +{ + do_qb_cmpu (SD_, RS, RT, 0); +} + +001000,5.RT,5.RS,5.X1,1.X2,1010000101:POOL32A:32::CMPU.LT.QB +"cmpu.lt.qb r, r" +*nanomipsdsp: +{ + do_qb_cmpu (SD_, RS, RT, 1); +} + +001000,5.RT,5.RS,5.X1,1.X2,1011000101:POOL32A:32::CMPU.LE.QB +"cmpu.le.qb r, r" +*nanomipsdsp: +{ + do_qb_cmpu (SD_, RS, RT, 2); +} + +001000,5.RT,5.RS,2.AC,00000010111111:POOL32A:32::DPA.W.PH +"dpa.w.ph ac, r, r" +*nanomipsdsp: +{ + do_w_ph_dot_product (SD_, AC, RS, RT, 0); +} + +001000,5.RT,5.RS,2.AC,00001010111111:POOL32A:32::DPAQ_S.W.PH +"dpaq_s.w.ph ac, r, r" +*nanomipsdsp: +{ + do_ph_dot_product (SD_, AC, RS, RT, 0); +} + +001000,5.RT,5.RS,2.AC,01001010111111:POOL32A:32::DPAQ_SA.L.W +"dpaq_sa.l.w ac, r, r" +*nanomipsdsp: +{ + do_w_dot_product (SD_, AC, RS, RT, 0); +} + +001000,5.RT,5.RS,2.AC,10001010111111:POOL32A:32::DPAQX_S.W.PH +"dpaqx_s.w.ph ac, r, r" +*nanomipsdsp: +{ + do_qx_w_ph_dot_product (SD_, AC, RS, RT, 0, 0); +} + +001000,5.RT,5.RS,2.AC,11001010111111:POOL32A:32::DPAQX_SA.W.PH +"dpaqx_sa.w.ph ac, r, r" +*nanomipsdsp: +{ + do_qx_w_ph_dot_product (SD_, AC, RS, RT, 0, 1); +} + +001000,5.RT,5.RS,2.AC,10000010111111:POOL32A:32::DPAU.H.QBL +"dpau.h.qbl ac, r, r" +*nanomipsdsp: +{ + do_qb_dot_product (SD_, AC, RS, RT, 0, 0); +} + +001000,5.RT,5.RS,2.AC,11000010111111:POOL32A:32::DPAU.H.QBR +"dpau.h.qbr ac, r, r" +*nanomipsdsp: +{ + do_qb_dot_product (SD_, AC, RS, RT, 0, 1); +} + +001000,5.RT,5.RS,2.AC,01000010111111:POOL32A:32::DPAX.W.PH +"dpax.w.ph ac, r, r" +*nanomipsdsp: +{ + do_x_w_ph_dot_product (SD_, AC, RS, RT, 0); +} + +001000,5.RT,5.RS,2.AC,00010010111111:POOL32A:32::DPS.W.PH +"dps.w.ph ac, r, r" +*nanomipsdsp: +{ + do_w_ph_dot_product (SD_, AC, RS, RT, 1); +} + +001000,5.RT,5.RS,2.AC,00011010111111:POOL32A:32::DPSQ_S.W.PH +"dpsq_s.w.ph ac, r, r" +*nanomipsdsp: +{ + do_ph_dot_product (SD_, AC, RS, RT, 1); +} + +001000,5.RT,5.RS,2.AC,01011010111111:POOL32A:32::DPSQ_SA.L.W +"dpsq_sa.l.w ac, r, r" +*nanomipsdsp: +{ + do_w_dot_product (SD_, AC, RS, RT, 1); +} + +001000,5.RT,5.RS,2.AC,10011010111111:POOL32A:32::DPSQX_S.W.PH +"dpsqx_s.w.ph ac, r, r" +*nanomipsdsp: +{ + do_qx_w_ph_dot_product (SD_, AC, RS, RT, 1, 0); +} + +001000,5.RT,5.RS,2.AC,11011010111111:POOL32A:32::DPSQX_SA.W.PH +"dpsqx_sa.w.ph ac, r, r" +*nanomipsdsp: +{ + do_qx_w_ph_dot_product (SD_, AC, RS, RT, 1, 1); +} + +001000,5.RT,5.RS,2.AC,10010010111111:POOL32A:32::DPSU.H.QBL +"dpsu.h.qbl ac, r, r" +*nanomipsdsp: +{ + do_qb_dot_product (SD_, AC, RS, RT, 1, 0); +} + +001000,5.RT,5.RS,2.AC,11010010111111:POOL32A:32::DPSU.H.QBR +"dpsu.h.qbr ac, r, r" +*nanomipsdsp: +{ + do_qb_dot_product (SD_, AC, RS, RT, 1, 1); +} + +001000,5.RT,5.RS,2.AC,01010010111111:POOL32A:32::DPSX.W.PH +"dpsx.w.ph ac, r, r" +*nanomipsdsp: +{ + do_x_w_ph_dot_product (SD_, AC, RS, RT, 1); +} + +001000,5.RT,5.SIZE,2.AC,10011001111111:POOL32A:32::EXTP +"extp r, ac, " +*nanomipsdsp: +{ + do_extp (SD_, RT, AC, SIZE, 0); +} + +001000,5.RT,5.SIZE,2.AC,11011001111111:POOL32A:32::EXTPDP +"extpdp r, ac, " +*nanomipsdsp: +{ + do_extp (SD_, RT, AC, SIZE, 1); +} + +001000,5.RT,5.RS,2.AC,11100010111111:POOL32A:32::EXTPDPV +"extpdpv r, ac, r" +*nanomipsdsp: +{ + do_extpv (SD_, RT, AC, RS, 1); +} + +001000,5.RT,5.RS,2.AC,10100010111111:POOL32A:32::EXTPV +"extpv r, ac, r" +*nanomipsdsp: +{ + do_extpv (SD_, RT, AC, RS, 0); +} + +001000,5.RT,5.SHIFT,2.AC,00111001111111:POOL32A:32::EXTR.W +"extr.w r, ac, " +*nanomipsdsp: +{ + do_w_extr (SD_, RT, AC, SHIFT, 0); +} + +001000,5.RT,5.SHIFT,2.AC,01111001111111:POOL32A:32::EXTR_R.W +"extr_r.w r, ac, " +*nanomipsdsp: +{ + do_w_extr (SD_, RT, AC, SHIFT, 1); +} + +001000,5.RT,5.SHIFT,2.AC,10111001111111:POOL32A:32::EXTR_RS.W +"extr_rs.w r, ac, " +*nanomipsdsp: +{ + do_w_extr (SD_, RT, AC, SHIFT, 2); +} + +001000,5.RT,5.SHIFT,2.AC,11111001111111:POOL32A:32::EXTR_S.H +"extr_s.h r, ac, " +*nanomipsdsp: +{ + do_h_extr (SD_, RT, AC, SHIFT); +} + +001000,5.RT,5.RS,2.AC,00111010111111:POOL32A:32::EXTRV.W +"extrv.w r, ac, r" +*nanomipsdsp: +{ + do_extrv (SD_, RT, AC, RS, 0); +} + +001000,5.RT,5.RS,2.AC,01111010111111:POOL32A:32::EXTRV_R.W +"extrv_r.w r, ac, r" +*nanomipsdsp: +{ + do_extrv (SD_, RT, AC, RS, 1); +} + +001000,5.RT,5.RS,2.AC,10111010111111:POOL32A:32::EXTRV_RS.W +"extrv_rs.w r, ac, r" +*nanomipsdsp: +{ + do_extrv (SD_, RT, AC, RS, 2); +} + +001000,5.RT,5.RS,2.AC,11111010111111:POOL32A:32::EXTRV_S.H +"extrv_s.h r, ac, r" +*nanomipsdsp: +{ + do_extrv_s_h (SD_, RT, AC, RS); +} + +001000,5.RT,5.RS,0100000100111111:POOL32A:32::INSV +"insv r, r" +*nanomipsdsp: +{ + do_insv (SD_, RT, RS); +} + +001000,5.RT,5.RS,2.AC,00101010111111:POOL32A:32::MADD_DSP +"madd ac, r, r" +*nanomipsdsp: +{ + do_dsp_madd (SD_, AC, RS, RT); +} + +001000,5.RT,5.RS,2.AC,01101010111111:POOL32A:32::MADDU_DSP +"maddu ac, r, r" +*nanomipsdsp: +{ + do_dsp_maddu (SD_, AC, RS, RT); +} + +001000,5.RT,5.RS,2.AC,01101001111111:POOL32A:32::MAQ_S.W.PHL +"maq_s.w.phl ac, r, r" +*nanomipsdsp: +{ + do_ph_maq (SD_, AC, RS, RT, 0, 0); +} + +001000,5.RT,5.RS,2.AC,11101001111111:POOL32A:32::MAQ_SA.W.PHL +"maq_sa.w.phl ac, r, r" +*nanomipsdsp: +{ + do_ph_maq (SD_, AC, RS, RT, 1, 0); +} + +001000,5.RT,5.RS,2.AC,00101001111111:POOL32A:32::MAQ_S.W.PHR +"maq_s.w.phr ac, r, r" +*nanomipsdsp: +{ + do_ph_maq (SD_, AC, RS, RT, 0, 1); +} + +001000,5.RT,5.RS,2.AC,10101001111111:POOL32A:32::MAQ_SA.W.PHR +"maq_sa.w.phr ac, r, r" +*nanomipsdsp: +{ + do_ph_maq (SD_, AC, RS, RT, 1, 1); +} + +001000,5.RS,5.X,2.AC,00000001111111:POOL32A:32::MFHI_DSP +"mfhi r, ac" +*nanomipsdsp: +{ + do_dsp_mfhi (SD_, AC, RS); +} + +001000,5.RS,5.X,2.AC,01000001111111:POOL32A:32::MFLO_DSP +"mflo r, ac" +*nanomipsdsp: +{ + do_dsp_mflo (SD_, AC, RS); +} + +001000,5.RT,5.RS,5.RD,1.X,1010010101:POOL32A:32::MODSUB +"modsub r, r, r" +*nanomipsdsp: +{ + do_modsub (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,2.AC,10101010111111:POOL32A:32::MSUB_DSP +"msub ac, r, r" +*nanomipsdsp: +{ + do_dsp_msub (SD_, AC, RS, RT); +} + +001000,5.RT,5.RS,2.AC,11101010111111:POOL32A:32::MSUBU_DSP +"msubu ac, r, r" +*nanomipsdsp: +{ + do_dsp_msubu (SD_, AC, RS, RT); +} + +001000,00000,5.RS,2.AC,10000001111111:POOL32A:32::MTHI_DSP +"mthi r, ac" +*nanomipsdsp: +{ + do_dsp_mthi (SD_, AC, RS); +} + +001000,00000,5.RS,2.AC,00001001111111:POOL32A:32::MTHLIP +"mthlip r, ac" +*nanomipsdsp: +{ + do_mthlip (SD_, RS, AC); +} + +001000,00000,5.RS,2.AC,11000001111111:POOL32A:32::MTLO_DSP +"mtlo r, ac" +*nanomipsdsp: +{ + do_dsp_mtlo (SD_, AC, RS); +} + +001000,5.RT,5.RS,5.RD,00000101101:POOL32A:32::MUL.PH +"mul.ph r, r, r" +*nanomipsdsp: +{ + do_ph_op (SD_, RD, RS, RT, 2, 0); +} + +001000,5.RT,5.RS,5.RD,10000101101:POOL32A:32::MUL_S.PH +"mul_s.ph r, r, r" +*nanomipsdsp: +{ + do_ph_op (SD_, RD, RS, RT, 2, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,0000100101:POOL32A:32::MULEQ_S.W.PHL +"muleq_s.w.phl r, r, r" +*nanomipsdsp: +{ + do_ph_muleq (SD_, RD, RS, RT, 0); +} + +001000,5.RT,5.RS,5.RD,1.X,0001100101:POOL32A:32::MULEQ_S.W.PHR +"muleq_s.w.phr r, r, r" +*nanomipsdsp: +{ + do_ph_muleq (SD_, RD, RS, RT, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,0010010101:POOL32A:32::MULEU_S.PH.QBL +"muleu_s.ph.qbl r, r, r" +*nanomipsdsp: +{ + do_qb_muleu (SD_, RD, RS, RT, 0); +} + +001000,5.RT,5.RS,5.RD,1.X,0011010101:POOL32A:32::MULEU_S.PH.QBR +"muleu_s.ph.qbr r, r, r" +*nanomipsdsp: +{ + do_qb_muleu (SD_, RD, RS, RT, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,0100010101:POOL32A:32::MULQ_RS.PH +"mulq_rs.ph r, r, r" +*nanomipsdsp: +{ + do_ph_mulq (SD_, RD, RS, RT, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,0110010101:POOL32A:32::MULQ_RS.W +"mulq_rs.w r, r, r" +*nanomipsdsp: +{ + do_w_mulq (SD_, RD, RS, RT, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,0101010101:POOL32A:32::MULQ_S.PH +"mulq_s.ph r, r, r" +*nanomipsdsp: +{ + do_ph_mulq (SD_, RD, RS, RT, 0); +} + +001000,5.RT,5.RS,5.RD,1.X,0111010101:POOL32A:32::MULQ_S.W +"mulq_s.w r, r, r" +*nanomipsdsp: +{ + do_w_mulq (SD_, RD, RS, RT, 0); +} + +001000,5.RT,5.RS,2.AC,10110010111111:POOL32A:32::MULSA.W.PH +"mulsa.w.ph ac, r, r" +*nanomipsdsp: +{ + do_ph_w_mulsa (SD_, AC, RS, RT); +} + +001000,5.RT,5.RS,2.AC,11110010111111:POOL32A:32::MULSAQ_S.W.PH +"mulsaq_s.w.ph ac, r, r" +*nanomipsdsp: +{ + do_mulsaq_s_w_ph (SD_, AC, RS, RT); +} + +001000,5.RT,5.RS,2.AC,00110010111111:POOL32A:32::MULT_DSP +"mult ac, r, r" +*nanomipsdsp: +{ + do_dsp_mult (SD_, AC, RS, RT); +} + +001000,5.RT,5.RS,2.AC,01110010111111:POOL32A:32::MULTU_DSP +"multu ac, r, r" +*nanomipsdsp: +{ + do_dsp_multu (SD_, AC, RS, RT); +} + +001000,5.RT,5.RS,5.RD,1.X,0110101101:POOL32A:32::PACKRL.PH +"packrl.ph r, r, r" +*nanomipsdsp: +{ + do_ph_packrl (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.RD,1.X,1000101101:POOL32A:32::PICK.PH +"pick.ph r, r, r" +*nanomipsdsp: +{ + do_ph_pick (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.RD,1.X,0111101101:POOL32A:32::PICK.QB +"pick.qb r, r, r" +*nanomipsdsp: +{ + do_qb_pick (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,0101000100111111:POOL32A:32::PRECEQ.W.PHL +"preceq.w.phl r, r" +*nanomipsdsp: +{ + do_w_preceq (SD_, RT, RS, 0); +} + +001000,5.RT,5.RS,0110000100111111:POOL32A:32::PRECEQ.W.PHR +"preceq.w.phr r, r" +*nanomipsdsp: +{ + do_w_preceq (SD_, RT, RS, 1); +} + +001000,5.RT,5.RS,0111000100111111:POOL32A:32::PRECEQU.PH.QBL +"precequ.ph.qbl r, r" +*nanomipsdsp: +{ + do_qb_ph_precequ (SD_, RT, RS, 2); +} + +001000,5.RT,5.RS,0111001100111111:POOL32A:32::PRECEQU.PH.QBLA +"precequ.ph.qbla r, r" +*nanomipsdsp: +{ + do_qb_ph_precequ (SD_, RT, RS, 3); +} + +001000,5.RT,5.RS,1001000100111111:POOL32A:32::PRECEQU.PH.QBR +"precequ.ph.qbr r, r" +*nanomipsdsp: +{ + do_qb_ph_precequ (SD_, RT, RS, 0); +} + +001000,5.RT,5.RS,1001001100111111:POOL32A:32::PRECEQU.PH.QBRA +"precequ.ph.qbra r, r" +*nanomipsdsp: +{ + do_qb_ph_precequ (SD_, RT, RS, 1); +} + +001000,5.RT,5.RS,1011000100111111:POOL32A:32::PRECEU.PH.QBL +"preceu.ph.qbl r, r" +*nanomipsdsp: +{ + do_qb_ph_preceu (SD_, RT, RS, 2); +} + +001000,5.RT,5.RS,1011001100111111:POOL32A:32::PRECEU.PH.QBLA +"preceu.ph.qbla r, r" +*nanomipsdsp: +{ + do_qb_ph_preceu (SD_, RT, RS, 3); +} + +001000,5.RT,5.RS,1101000100111111:POOL32A:32::PRECEU.PH.QBR +"preceu.ph.qbr r, r" +*nanomipsdsp: +{ + do_qb_ph_preceu (SD_, RT, RS, 0); +} + +001000,5.RT,5.RS,1101001100111111:POOL32A:32::PRECEU.PH.QBRA +"preceu.ph.qbra r, r" +*nanomipsdsp: +{ + do_qb_ph_preceu (SD_, RT, RS, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,0001101101:POOL32A:32::PRECR.QB.PH +"precr.qb.ph r, r, r" +*nanomipsdsp: +{ + do_ph_qb_precr (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.SA,01111001101:POOL32A:32::PRECR_SRA.PH.W +"precr_sra.ph.w r, r, " +*nanomipsdsp: +{ + do_precr_sra (SD_, RT, RS, SA, 0); +} + +001000,5.RT,5.RS,5.SA,11111001101:POOL32A:32::PRECR_SRA_R.PH.W +"precr_sra_r.ph.w r, r, " +*nanomipsdsp: +{ + do_precr_sra (SD_, RT, RS, SA, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,0011101101:POOL32A:32::PRECRQ.PH.W +"precrq.ph.w r, r, r" +*nanomipsdsp: +{ + do_w_ph_precrq (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.RD,1.X,0010101101:POOL32A:32::PRECRQ.QB.PH +"precrq.qb.ph r, r, r" +*nanomipsdsp: +{ + do_ph_qb_precrq (SD_, RD, RS, RT, 0); +} + +001000,5.RT,5.RS,5.RD,1.X,0101101101:POOL32A:32::PRECRQU_S.QB.PH +"precrqu_s.qb.ph r, r, r" +*nanomipsdsp: +{ + do_ph_qb_precrq (SD_, RD, RS, RT, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,0100101101:POOL32A:32::PRECRQ_RS.PH.W +"precrq_rs.ph.w r, r, r" +*nanomipsdsp: +{ + do_w_ph_rs_precrq (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.SA,1.X,1001010101:POOL32A:32::PREPEND +"prepend r, r, " +*nanomipsdsp: +{ + do_prepend (SD_, RT, RS, SA); +} + +001000,5.RT,5.RS,1111000100111111:POOL32A:32::RADDU.W.QB +"raddu.w.qb r, r" +*nanomipsdsp: +{ + do_qb_w_raddu (SD_, RT, RS); +} + +001000,5.RT,7.CONTROL_MASK,00011001111111:POOL32A:32::RDDSP +"rddsp r":CONTROL_MASK == 1111111111 +"rddsp r, " +*nanomipsdsp: +{ + do_rddsp (SD_, RT, CONTROL_MASK); +} + +001000,5.RT,10.IMMEDIATE,1.X,0000111101:POOL32A:32::REPL.PH +"repl.ph r, " +*nanomipsdsp: +{ + do_repl (SD_, RT, IMMEDIATE, 2); +} + +001000,5.RT,8.IMMEDIATE,1.X,010111111111:POOL32A:32::REPL.QB +"repl.qb r, " +*nanomipsdsp: +{ + do_repl (SD_, RT, IMMEDIATE, 0); +} + +001000,5.RT,5.RS,0000001100111111:POOL32A:32::REPLV.PH +"replv.ph r, r" +*nanomipsdsp: +{ + do_repl (SD_, RT, RS, 3); +} + +001000,5.RT,5.RS,0001001100111111:POOL32A:32::REPLV.QB +"replv.qb r, r" +*nanomipsdsp: +{ + do_repl (SD_, RT, RS, 1); +} + +001000,0000,6.IMMEDIATE,2.AC,00000000011101:POOL32A:32::SHILO +"shilo ac, " +*nanomipsdsp: +{ + do_shilo (SD_, AC, IMMEDIATE); +} + +001000,00000,5.RS,2.AC,01001001111111:POOL32A:32::SHILOV +"shilov ac, r" +*nanomipsdsp: +{ + do_shilov (SD_, AC, RS); +} + +001000,5.RT,5.RS,4.SHIFT,001110110101:POOL32A:32::SHLL.PH +"shll.ph r, r, " +*nanomipsdsp: +{ + do_ph_shift (SD_, RT, RS, SHIFT, 0, 0); +} + +001000,5.RT,5.RS,4.SHIFT,101110110101:POOL32A:32::SHLL_S.PH +"shll_s.ph r, r, " +*nanomipsdsp: +{ + do_ph_shift (SD_, RT, RS, SHIFT, 0, 1); +} + +001000,5.RT,5.RS,3.SHIFT,0100001111111:POOL32A:32::SHLL.QB +"shll.qb r, r, " +*nanomipsdsp: +{ + do_qb_shift (SD_, RT, RS, SHIFT, 0); +} + +001000,5.RT,5.RS,5.RD,01110001101:POOL32A:32::SHLLV.PH +"shllv.ph r, r, r" +*nanomipsdsp: +{ + do_ph_shl (SD_, RD, RT, RS, 0, 0); +} + +001000,5.RT,5.RS,5.RD,11110001101:POOL32A:32::SHLLV_S.PH +"shllv_s.ph r, r, r" +*nanomipsdsp: +{ + do_ph_shl (SD_, RD, RT, RS, 0, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,1110010101:POOL32A:32::SHLLV.QB +"shllv.qb r, r, r" +*nanomipsdsp: +{ + do_qb_shl (SD_, RD, RT, RS, 0); +} + +001000,5.RT,5.RS,5.RD,1.X,1111010101:POOL32A:32::SHLLV_S.W +"shllv_s.w r, r, r" +*nanomipsdsp: +{ + do_w_s_shllv (SD_, RD, RT, RS); +} + +001000,5.RT,5.RS,5.SHIFT,1.X,1111110101:POOL32A:32::SHLL_S.W +"shll_s.w r, r, " +*nanomipsdsp: +{ + do_w_shll (SD_, RT, RS, SHIFT); +} + +001000,5.RT,5.RS,3.SHIFT,0000111111111:POOL32A:32::SHRA.QB +"shra.qb r, r, " +*nanomipsdsp: +{ + do_qb_shra (SD_, RT, RS, SHIFT, 0); +} + +001000,5.RT,5.RS,3.SHIFT,1000111111111:POOL32A:32::SHRA_R.QB +"shra_r.qb r, r, " +*nanomipsdsp: +{ + do_qb_shra (SD_, RT, RS, SHIFT, 1); +} + +001000,5.RT,5.RS,4.SHIFT,1.X,01100110101:POOL32A:32::SHRA.PH +"shra.ph r, r, " +*nanomipsdsp: +{ + do_ph_shift (SD_, RT, RS, SHIFT, 1, 0); +} + +001000,5.RT,5.RS,4.SHIFT,1.X,11100110101:POOL32A:32::SHRA_R.PH +"shra_r.ph r, r, " +*nanomipsdsp: +{ + do_ph_shift (SD_, RT, RS, SHIFT, 1, 1); +} + +001000,5.RT,5.RS,5.RD,00110001101:POOL32A:32::SHRAV.PH +"shrav.ph r, r, r" +*nanomipsdsp: +{ + do_ph_shl (SD_, RD, RT, RS, 1, 0); +} + +001000,5.RT,5.RS,5.RD,10110001101:POOL32A:32::SHRAV_R.PH +"shrav_r.ph r, r, r" +*nanomipsdsp: +{ + do_ph_shl (SD_, RD, RT, RS, 1, 1); +} + +001000,5.RT,5.RS,5.RD,00111001101:POOL32A:32::SHRAV.QB +"shrav.qb r, r, r" +*nanomipsdsp: +{ + do_qb_shrav (SD_, RD, RT, RS, 0); +} + +001000,5.RT,5.RS,5.RD,10111001101:POOL32A:32::SHRAV_R.QB +"shrav_r.qb r, r, r" +*nanomipsdsp: +{ + do_qb_shrav (SD_, RD, RT, RS, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,1011010101:POOL32A:32::SHRAV_R.W +"shrav_r.w r, r, r" +*nanomipsdsp: +{ + do_w_r_shrav (SD_, RD, RT, RS); +} + +001000,5.RT,5.RS,5.SHIFT,1.X,1011110101:POOL32A:32::SHRA_R.W +"shra_r.w r, r, " +*nanomipsdsp: +{ + do_w_shra (SD_, RT, RS, SHIFT); +} + +001000,5.RT,5.RS,4.SHIFT,001111111111:POOL32A:32::SHRL.PH +"shrl.ph r, r, " +*nanomipsdsp: +{ + do_ph_shrl (SD_, RT, RS, SHIFT); +} + +001000,5.RT,5.RS,3.SHIFT,1100001111111:POOL32A:32::SHRL.QB +"shrl.qb r, r, " +*nanomipsdsp: +{ + do_qb_shift (SD_, RT, RS, SHIFT, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,1100010101:POOL32A:32::SHRLV.PH +"shrlv.ph r, r, r" +*nanomipsdsp: +{ + do_ph_shrlv (SD_, RD, RT, RS); +} + +001000,5.RT,5.RS,5.RD,1.X,1101010101:POOL32A:32::SHRLV.QB +"shrlv.qb r, r, r" +*nanomipsdsp: +{ + do_qb_shl (SD_, RD, RT, RS, 1); +} + +001000,5.RT,5.RS,5.RD,01000001101:POOL32A:32::SUBQ.PH +"subq.ph r, r, r" +*nanomipsdsp: +{ + do_ph_op (SD_, RD, RS, RT, 1, 0); +} + +001000,5.RT,5.RS,5.RD,11000001101:POOL32A:32::SUBQ_S.PH +"subq_s.ph r, r, r" +*nanomipsdsp: +{ + do_ph_op (SD_, RD, RS, RT, 1, 1); +} + +001000,5.RT,5.RS,5.RD,1.X,1101000101:POOL32A:32::SUBQ_S.W +"subq_s.w r, r, r" +*nanomipsdsp: +{ + do_w_op (SD_, RD, RS, RT, 1); +} + +001000,5.RT,5.RS,5.RD,01001001101:POOL32A:32::SUBQH.PH +"subqh.ph r, r, r" +*nanomipsdsp: +{ + do_qh_ph_op (SD_, RD, RS, RT, 1, 0); +} + +001000,5.RT,5.RS,5.RD,11001001101:POOL32A:32::SUBQH_R.PH +"subqh_r.ph r, r, r" +*nanomipsdsp: +{ + do_qh_ph_op (SD_, RD, RS, RT, 1, 1); +} + +001000,5.RT,5.RS,5.RD,01010001101:POOL32A:32::SUBQH.W +"subqh.w r, r, r" +*nanomipsdsp: +{ + do_qh_w_op (SD_, RD, RS, RT, 1, 0); +} + +001000,5.RT,5.RS,5.RD,11010001101:POOL32A:32::SUBQH_R.W +"subqh_r.w r, r, r" +*nanomipsdsp: +{ + do_qh_w_op (SD_, RD, RS, RT, 1, 1); +} + +001000,5.RT,5.RS,5.RD,01100001101:POOL32A:32::SUBU.PH +"subu.ph r, r, r" +*nanomipsdsp: +{ + do_u_ph_op (SD_, RD, RS, RT, 1, 0); +} + +001000,5.RT,5.RS,5.RD,11100001101:POOL32A:32::SUBU_S.PH +"subu_s.ph r, r, r" +*nanomipsdsp: +{ + do_u_ph_op (SD_, RD, RS, RT, 1, 1); +} + +001000,5.RT,5.RS,5.RD,01011001101:POOL32A:32::SUBU.QB +"subu.qb r, r, r" +*nanomipsdsp: +{ + do_qb_op (SD_, RD, RS, RT, 1, 0); +} + +001000,5.RT,5.RS,5.RD,11011001101:POOL32A:32::SUBU_S.QB +"subu_s.qb r, r, r" +*nanomipsdsp: +{ + do_qb_op (SD_, RD, RS, RT, 1, 1); +} + +001000,5.RT,5.RS,5.RD,01101001101:POOL32A:32::SUBUH.QB +"subuh.qb r, r, r" +*nanomipsdsp: +{ + do_uh_qb_op (SD_, RD, RS, RT, 1, 0); +} + +001000,5.RT,5.RS,5.RD,11101001101:POOL32A:32::SUBUH_R.QB +"subuh_r.qb r, r, r" +*nanomipsdsp: +{ + do_uh_qb_op (SD_, RD, RS, RT, 1, 1); +} + +001000,5.RT,7.CONTROL_MASK,01011001111111:POOL32A:32::WRDSP +"wrdsp r":CONTROL_MASK == 1111111111 +"wrdsp r, " +*nanomipsdsp: +{ + do_wrdsp (SD_, RT, CONTROL_MASK); +} diff --git a/sim/mips/nanomipsr6.igen b/sim/mips/nanomipsr6.igen new file mode 100644 index 00000000000..109fa1510f9 --- /dev/null +++ b/sim/mips/nanomipsr6.igen @@ -0,0 +1,3283 @@ +// Simulator definition for the nanoMIPS. +// Copyright (C) 2018-2022 Free Software Foundation, Inc. +// Contributed by Imagination Technologies, Ltd. +// Written by Ali Lown +// +// This file is part of GDB, the GNU debugger. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +:compute:::int:U_SHIFT_1BIT:U:(U << 1) +:compute:::int:U_SHIFT_2BIT:U:(U << 2) +:compute:::int:U_SHIFT_3BIT:U:(U << 3) +:compute:::int:U_SHIFT_4BIT:U:(U << 4) +:compute:::int:EU_127:EU:((EU == 127) ? -1 \: EU) +:compute:::int:U_LW4X4:U2,U3:((U3 << 3) | (U2 << 2)) +:compute:::int:AXUIPC_S_LO:S1,S2,S3:((EXTEND32((S3 << 31) | (S2 << 21) | (S1 << 12))) & 0x0000ffff) +:compute:::int:AXUIPC_S_HI:S1,S2,S3:((EXTEND32((S3 << 31) | (S2 << 21) | (S1 << 12))) & 0xffff0000) +:compute:::int:AXUIPC_S:S1,S2,S3:(EXTEND32((S3 << 31) | (S2 << 21) | (S1 << 12))) +:compute:::int:TRD2:RD20,RD21:(compute_gpr2_dest1_reg (SD_, (RD21 << 1 | RD20))) +:compute:::int:TRE2:RD20,RD21:(compute_gpr2_dest2_reg (SD_, (RD21 << 1 | RD20))) +:compute:::int:TRS2:RS4,RS2_0:(compute_gpr4_zero (SD_, (RS4 << 3 | RS2_0))) +:compute:::int:TRT2:RT4,RT2_0:(compute_gpr4_zero (SD_, (RT4 << 3 | RT2_0))) +:compute:::int:TRD2_REV:RD4,RD2_0:(compute_gpr4 (SD_, (RD4 << 3) | RD2_0)) +:compute:::int:TRE2_REV:RE4,RE2_0:(compute_gpr4 (SD_, (RE4 << 3) | RE2_0)) +:compute:::int:TRS2_REV:RS20,RS21:(compute_gpr2_dest1_reg (SD_, (RS21 << 1 | RS20))) +:compute:::int:TRT2_REV:RS20,RS21:(compute_gpr2_dest2_reg (SD_, (RS21 << 1 | RS20))) +:compute:::address_word:ADDRESS8:S1,S2:(nia + EXTEND8((S2 << 7) | (S1 << 1))) +:compute:::address_word:ADDRESS11:S1,S2:(nia + EXTEND11((S2 << 10) | (S1 << 1))) +:compute:::address_word:ADDRESS15:S1,S2:(nia + EXTEND15((S2 << 14) | (S1 << 1))) +:compute:::address_word:ADDRESS21:S1,S2:(nia + EXTEND21((S2 << 20) | (S1 << 1))) +:compute:::address_word:ADDRESS22:S1,S2:(nia + EXTEND22((S2 << 21) | (S1 << 1))) +:compute:::address_word:ADDRESS26:S1,S2:(nia + EXTEND26((S2 << 25) | (S1 << 1))) +:compute:::int:INS_POS:LSB:(LSB) +:compute:::int:INS_SIZE:LSB,MSBD:(1 + MSBD - LSB) +:compute:::address_word:ADDRESS12:S1,S2:(nia + EXTEND12(S2 << 11 | S1 << 1)) +:compute:::int:S_14_BIT:S1,S2:(EXTEND14 ((S1 << 13) | S2)) +:compute:::int:S_4_BIT:S1,S2:(EXTEND4((S1 << 3) | S2)) +:compute:::int:S_9_BIT:S1,S2:(EXTEND9((S1 << 8) | S2)) +:compute:::int:S_9_BIT_LLSC:S1,S2:(EXTEND9((S1 << 8) | (S2 << 2))) +:compute:::int:RD1:RD:(compute_gpr1_dest_reg (SD_, RD)) +:compute:::int:RT_5_BIT_NM_Z:RT1,RT2:(compute_gpr4_zero (SD_, (RT1 << 3) | RT2)) +:compute:::int:RT_5_BIT_NM:RT1,RT2:(compute_gpr4 (SD_, (RT1 << 3) | RT2)) +:compute:::int:RS_5_BIT_NM:RS1,RS2:(compute_gpr4 (SD_, (RS1 << 3) | RS2)) +:compute:::int:TRTZ:RTZ:((RTZ >= 1 && RTZ <= 3) ? (16 + RTZ) \: RTZ) +:compute:::int:EU_12_13:EU:((EU == 12) ? 255 \: ((EU == 13) ? 65535 \: EU)) +:compute:::int:RS_MOVE:RS1,RS_CODE_1,RS_CODE_2:((RS1 << 3) | (RS_CODE_1 << 2) | RS_CODE_2) +:compute:::int:CODE_BREAK:RS_CODE_1,RS_CODE_2:((RS_CODE_1 << 2) | RS_CODE_2) +:compute:::int:TRD_NM:RD:((RD < 4) ? (16 + RD) \: RD) +:compute:::int:TRS_NM:RS:((RS < 4) ? (16 + RS) \: RS) +:compute:::int:TRT_NM:RT:((RT < 4) ? (16 + RT) \: RT) +:compute:::int:COUNT:COUNT3:(COUNT3 == 0 ? 8 \: COUNT3) +:compute:::int:SHIFTX_1BIT:SHIFTX:(SHIFTX << 1) + +:function:::void:do_msubf:int fd, int fs, int ft, int fmt, instruction_word instruction_0 +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + TRACE_ALU_INPUT3 (FGR[fd], FGR[fs], FGR[ft]); + StoreFPR (fd, fmt, FusedMultiplySub (ValueFPR (fs, fmt), + ValueFPR (ft, fmt), + ValueFPR (fd, fmt), fmt)); + TRACE_ALU_RESULT (FGR[fd]); +} + +:function:::void:do_maddf:int fd, int fs, int ft, int fmt, instruction_word instruction_0 +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + TRACE_ALU_INPUT3 (FGR[fd], FGR[fs], FGR[ft]); + StoreFPR (fd, fmt, FusedMultiplyAdd (ValueFPR (fs, fmt), + ValueFPR (ft, fmt), + ValueFPR (fd, fmt), fmt)); + TRACE_ALU_RESULT (FGR[fd]); +} + +:function:::void:do_rint:int fd, int fs, int fmt, instruction_word instruction_0 +{ + uint64_t result = 0; + check_fpu (SD_); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + TRACE_ALU_INPUT1 (FGR[fs]); + RoundToIntegralExact (ValueFPR (fs, fmt), &result, fmt); + StoreFPR (fd, fmt, result); + TRACE_ALU_RESULT (FGR[fd]); +} + +:function:::void:do_class:int fd, int fs, int fmt, instruction_word instruction_0 +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR (fd, fmt, Classify (ValueFPR (fs, fmt), fmt)); +} + +:function:::void:do_seleqzf:int fd, int fs, int ft, int fmt, instruction_word instruction_0 +{ + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + TRACE_ALU_INPUT2 (ValueFPR(fs, fmt), FGR[ft]); + if ((FGR[ft] & 0x01) == 0) + StoreFPR (fd, fmt, ValueFPR (fs, fmt)); + else + StoreFPR (fd, fmt, 0); + TRACE_ALU_RESULT (ValueFPR(fd, fmt)); +} + +:function:::void:do_selnezf:int fd, int fs, int ft, int fmt, instruction_word instruction_0 +{ + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + TRACE_ALU_INPUT2 (ValueFPR(fs, fmt), FGR[ft]); + if ((FGR[ft] & 0x01) == 0x1) + StoreFPR (fd, fmt, ValueFPR (fs, fmt)); + else + StoreFPR (fd, fmt, 0); + TRACE_ALU_RESULT (ValueFPR(fd, fmt)); +} + +:function:::void:do_self:int fd, int fs, int ft, int fmt, instruction_word instruction_0 +{ + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + TRACE_ALU_INPUT3 (FGR[fd], ValueFPR(fs, fmt), ValueFPR(ft, fmt)); + if ((FGR[fd] & 0x01) != 0) + StoreFPR (fd, fmt, ValueFPR (ft, fmt)); + else + StoreFPR (fd, fmt, ValueFPR (fs, fmt)); + TRACE_ALU_RESULT (ValueFPR(fd, fmt)); +} + +:function:::void:do_mina:int fd, int fs, int ft, int fmt, instruction_word instruction_0 +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + TRACE_ALU_INPUT2 (FGR[fs], FGR[ft]); + StoreFPR (fd, fmt, MinA (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt)); + TRACE_ALU_RESULT (FGR[fd]); +} + +:function:::void:do_maxa:int fd, int fs, int ft, int fmt, instruction_word instruction_0 +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + TRACE_ALU_INPUT2 (FGR[fs], FGR[ft]); + StoreFPR (fd, fmt, MaxA (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt)); + TRACE_ALU_RESULT (FGR[fd]); +} + +:function:::void:do_max:int fd, int fs, int ft, int fmt, instruction_word instruction_0 +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + TRACE_ALU_INPUT2 (FGR[fs], FGR[ft]); + StoreFPR (fd, fmt, Max (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt)); + TRACE_ALU_RESULT (FGR[fd]); +} + +:function:::void:do_min:int fd, int fs, int ft, int fmt, instruction_word instruction_0 +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + TRACE_ALU_INPUT2 (FGR[fs], FGR[ft]); + StoreFPR (fd, fmt, Min (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt)); + TRACE_ALU_RESULT (FGR[fd]); +} + +:function:::void:do_cmp:int fd, int fs, int ft, int fmt, int condition +{ + uint64_t result; + check_fpu (SD_); + TRACE_ALU_INPUT2 (ValueFPR (fs, fmt), ValueFPR (ft, fmt)); + result = R6Compare (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt, condition); + StoreFPR (fd, fmt, result); + TRACE_ALU_RESULT (result); +} + +:function:::void:do_modu:int rd, int rs, int rt +{ + uint32_t n = GPR[rs]; + uint32_t d = GPR[rt]; + TRACE_ALU_INPUT2 (n,d); + if (d == 0) + GPR[rd] = EXTEND32 (0); + else + GPR[rd] = EXTEND32 (n % d); + + TRACE_ALU_RESULT (GPR[rd]); +} + +:function:::void:do_mod:int rd, int rs, int rt +{ + int32_t n = GPR[rs]; + int32_t d = GPR[rt]; + TRACE_ALU_INPUT2 (n,d); + if (d == 0 || (n == SIGNED32 (0x80000000) && d == -1)) + GPR[rd] = EXTEND32 (0); + else + GPR[rd] = EXTEND32 (n % d); + + TRACE_ALU_RESULT (GPR[rd]); +} + +:function:::void:do_muhu:int rd, int rs, int rt +{ + uint64_t prod; + if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) + Unpredictable (); + TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); + prod = ((uint64_t)(uint32_t) GPR[rs]) + * ((uint64_t)(uint32_t) GPR[rt]); + GPR[rd] = EXTEND32 (VH4_8 (prod)); + TRACE_ALU_RESULT (GPR[rd]); +} + +:function:::void:do_mulu:int rd, int rs, int rt +{ + uint64_t prod; + if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) + Unpredictable (); + TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); + prod = ((uint64_t)(uint32_t) GPR[rs]) + * ((uint64_t)(uint32_t) GPR[rt]); + GPR[rd] = EXTEND32 (VL4_8 (prod)); + TRACE_ALU_RESULT (GPR[rd]); +} + +:function:::void:do_muh:int rd, int rs, int rt +{ + int64_t prod; + if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) + Unpredictable (); + TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); + prod = ((int64_t)(int32_t) GPR[rs]) + * ((int64_t)(int32_t) GPR[rt]); + GPR[rd] = EXTEND32 (VH4_8 (prod)); + TRACE_ALU_RESULT (GPR[rd]); +} + +:function:::void:do_lsa:int rd, int rs, int rt, unsigned immediate +{ + uint32_t t = GPR[rs] << immediate; + GPR[rd] = EXTEND32(GPR[rt] + t); + TRACE_ALU_RESULT (GPR[rd]); +} + +:function:::void:do_divu:int rd, int rs, int rt +*nanomips32r6: +*nanomips64r6: +{ + uint32_t n = GPR[rs]; + uint32_t d = GPR[rt]; + TRACE_ALU_INPUT2 (n,d); + if (d == 0) + GPR[rd] = EXTEND32 (0x80000000); + else + GPR[rd] = EXTEND32 (n / d); + + TRACE_ALU_RESULT (GPR[rd]); +} + +:function:::void:do_div:int rd, int rs, int rt +*nanomips32r6: +*nanomips64r6: +{ + int32_t n = GPR[rs]; + int32_t d = GPR[rt]; + TRACE_ALU_INPUT2 (n,d); + if (d == 0) + GPR[rd] = EXTEND32 (0x80000000); + else if (n == SIGNED32 (0x80000000) && d == -1) + GPR[rd] = EXTEND32 (0x80000000); + else + GPR[rd] = EXTEND32 (n / d); + + TRACE_ALU_RESULT (GPR[rd]); +} + +:function:::void:do_llwp:int rt, int ru, int roffset, int rbase +{ + address_word base = GPR[rbase]; + address_word offset = EXTEND16 (roffset); + { + address_word vaddr = loadstore_ea (SD_, base, offset); + address_word paddr; + int uncached; + if ((vaddr & 7) != 0) + { + SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer, + sim_core_unaligned_signal); + } + else + { + if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, + isTARGET, isREAL)) + { + uint64_t memval = 0; + uint64_t memval1 = 0; + uint64_t data = memval; + + LoadMemory (&memval, &memval1, uncached, AccessLength_DOUBLEWORD, + paddr, vaddr, isDATA, isREAL); + + GPR[rt] = EXTEND32 (data & 0xFFFFFFFF); + GPR[ru] = EXTEND32 (data >> 32); + + LLBIT = 1; + COP0_COUNT++; + } + } + } +} + +:function:::void:do_rotx:int rt, int rs, int shift, int shiftx, int stripe +{ + int i; + uint64_t tmp0 = ((uint64_t)GPR[rs] << 32) | (GPR[rs] & 0xFFFFFFFF); + uint64_t tmp1, tmp2, tmp3, tmp4, tmp5; + + tmp1 = tmp0; + for (i = 0; i <=46; i++) { + int s; + + if (i & 0x8) + s = shift; + else + s = shiftx; + + if (stripe != 0 && !(i & 0x4)) + s = ~s; + + if (s & 0x10) { + if (tmp0 & (1LL << (i + 16))) + tmp1 |= 1LL << i; + else + tmp1 &= ~(1LL << i); + } + } + + tmp2 = tmp1; + for (i = 0; i <=38; i++) { + int s; + + if (i & 0x4) + s = shift; + else + s = shiftx; + + if (s & 0x8) { + if (tmp1 & (1LL << (i + 8))) + tmp2 |= 1LL << i; + else + tmp2 &= ~(1LL << i); + } + } + + tmp3 = tmp2; + for (i = 0; i <=34; i++) { + int s; + + if (i & 0x2) + s = shift; + else + s = shiftx; + + if (s & 0x4) { + if (tmp2 & (1LL << (i + 4))) + tmp3 |= 1LL << i; + else + tmp3 &= ~(1LL << i); + } + } + + tmp4 = tmp3; + for (i = 0; i <=32; i++) { + int s; + + if (i & 0x1) + s = shift; + else + s = shiftx; + + if (s & 0x2) { + if (tmp3 & (1LL << (i + 2))) + tmp4 |= 1LL << i; + else + tmp4 &= ~(1LL << i); + } + } + + tmp5 = tmp4; + for (i = 0; i <=31; i++) { + int s; + + s = shift; + + if (s & 0x1) { + if (tmp4 & (1LL << (i + 1))) + tmp5 |= 1LL << i; + else + tmp5 &= ~(1LL << i); + } + } + + GPR[rt] = EXTEND32 (tmp5); +} + +:function:::void:do_lwc1xs:int ft, int rbase, int roffset +*nanomips32r6: +*nanomips64r6: +{ + check_fpu (SD_); + COP_LW (1, ft, do_load (SD_, AccessLength_WORD, GPR[rbase] << 2, + GPR[roffset])); +} + +:function:::void:do_lwpc_nanomips:int rt, uint32_t offset, address_word nia +*nanomips32r6: +*nanomips64r6: +{ + check_fpu (SD_); + GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, nia, offset)); +} + +:function:::void:check_nms_flag: +*nanomips32r6: +*nanomips64r6: +{ + if(nms_flag == 0) + sim_engine_abort (SD, CPU, CIA, "Error: NMS instruction generated\ + (nanoMIPS Subset is disabled - use -march=32r6s option)\n"); +} + +:function:::void:do_swc1xs:int ft, int rbase, int roffset, address_word instruction_0 +*nanomips32r6: +*nanomips64r6: +{ + address_word base = GPR[rbase] << 2; + address_word offset = GPR[roffset]; + check_fpu (SD_); + { + address_word vaddr = loadstore_ea (SD_, base, offset); + address_word paddr; + int uncached; + if ((vaddr & 3) != 0) + { + SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr, + write_transfer, sim_core_unaligned_signal); + } + else + { + if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, + isTARGET, isREAL)) + { + uword64 memval = 0; + uword64 memval1 = 0; + uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3); + address_word reverseendian = + (ReverseEndian ?(mask ^ AccessLength_WORD): 0); + address_word bigendiancpu = + (BigEndianCPU ?(mask ^ AccessLength_WORD): 0); + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); + byte = ((vaddr & mask) ^ bigendiancpu); + memval = (((uword64)COP_SW(1, ft)) << (8 * byte)); + StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr, + vaddr, isREAL); + } + } + } +} + +:function:::uint32_t:compute_gpr2_dest1_reg:int reg +*nanomips32r6: +*nanomips64r6: +{ + switch(reg) + { + case 0: return 4; + case 1: return 5; + case 2: return 6; + case 3: return 7; + default: return 4; + } +} + +:function:::uint32_t:compute_gpr4_zero:int reg +*nanomips32r6: +*nanomips64r6: +{ + if (reg == 3) return 0; + else if (reg >=4 && reg <= 7) return reg; + else return reg + 8; +} + +:function:::uint32_t:compute_gpr4:int reg +*nanomips32r6: +*nanomips64r6: +{ + if (reg >=4 && reg <= 7) return reg; + else return reg + 8; +} + +:function:::uint32_t:compute_gpr2_dest2_reg:int reg +*nanomips32r6: +*nanomips64r6: +{ + switch(reg) + { + case 0: return 5; + case 1: return 6; + case 2: return 7; + case 3: return 8; + default: return 5; + } +} + +:function:::uint32_t:compute_gpr1_dest_reg:int reg +*nanomips32r6: +*nanomips64r6: +{ + switch(reg) + { + case 0: return 4; + case 1: return 5; + default: return 4; + } +} + +:function:::unsigned:zero_extend:signed_word value, uint32_t from_nbits +{ + uint32_t low_bits_mask = (1 << from_nbits) - 1; + return value & low_bits_mask; +} + +:function:::void:do_save_gprs_to_stack_and_adjust_sp: int first_gpr, int count, int gp, int u +*nanomips32r6: +*nanomips64r6: +{ + int counter = 0; + + while (counter != count) { + int gpr = (first_gpr & 0x10) | ((first_gpr + counter) & 0x1F); + int offset = - ( (counter + 1) << 2 ); + + if ( gp && (counter == count - 1)) + gpr = 28; + + do_store (SD_, AccessLength_WORD, GPR[SPIDX], offset, GPR[gpr]); + + counter++; + COP0_COUNT++; + } + + GPR[SPIDX] -= u; +} + +:function:::void:do_restore_gprs_from_stack_and_adjust_sp: int first_gpr, int count, int gp, int u +*nanomips32r6: +*nanomips64r6: +{ + int counter = 0; + + while (counter != count) { + int gpr = (first_gpr & 0x10) | ((first_gpr + counter) & 0x1F); + int offset; + + if (gpr == 29) + Unpredictable(); + + offset = u - ((counter + 1) << 2); + + if ( gp && (counter == count - 1)) + gpr = 28; + + GPR[gpr] = EXTEND32 (do_load(SD_, AccessLength_WORD, GPR[SPIDX], offset)); + + counter++; + COP0_COUNT++; + } + + GPR[SPIDX] += u; +} + +:function:::address_word:do_eret:int nc, address_word nia +*nanomips32r6: +*nanomips64r6: +{ + if (SR & status_ERL) + { + /* Oops, not yet available */ + sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported"); + nia = EPC; + SR &= ~status_ERL; + } + else + { + nia = EPC; + SR &= ~status_EXL; + //if ( SRSCtl.HSS > 0 && Status.BEV == 0) + // SRSCtl.CSS = SRSCtl.PSS + } + + if (!nc) + LLBIT = 0; + + //TODO: ClearHazards() + return nia; +} + +:%s::::GPR_LIST_SAVE:int count +*nanomips32r6: +*nanomips64r6: +{ + int i; + static char gpr_list[100]; + + gpr_list[0] = '\0'; + + i = 0; + + while (i 1) + strcat (gpr_list,"-"); + } + i++; + } + return (gpr_list); +} + +:function:::void:do_break_nanomips:address_word instruction_0 +{ + /* Check for some break instruction which are reserved for use by the + simulator. */ + unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK_NANOMIPS; + if (break_code == (HALT_INSTRUCTION_NANOMIPS & HALT_INSTRUCTION_MASK_NANOMIPS)) + { + sim_engine_halt (SD, CPU, NULL, cia, + sim_exited, (unsigned int)(A0 & 0xFFFFFFFF)); + } + else if (break_code == (BREAKPOINT_INSTRUCTION_NANOMIPS & HALT_INSTRUCTION_MASK_NANOMIPS)) + { + PC = cia; + SignalException (BreakPoint, instruction_0); + } + + else + { + /* If we get this far, we're not an instruction reserved by the sim. Raise + the exception. */ + SignalException (BreakPoint, instruction_0); + } +} + +:function:::FP_formats:convert_fmt_micromips_mul:int fmt +*nanomips32r6: +*nanomips64r6: +{ + switch (fmt) + { + case 1: return fmt_single; + case 3: return fmt_double; + default: return fmt_unknown; + } +} + +:%s::::GP_SAVE:int gp +*nanomips32r6: +*nanomips64r6: +{ + return (gp > 0) ? "gp" : ""; +} + +:%s::::FP_SAVE:int fp +*nanomips32r6: +*nanomips64r6: +{ + return (fp > 0) ? "fp" : ""; +} + +11111111111111111111111111111111:R6DUMMY:32,f::DUMMY0.fmt +"dummy 0" +*nanomips32r6: +*nanomips64r6: +{ + /* Just needed so GNUSIM builds */ +} + +011100,3.RT,1,6.U:R6P16A1:16::ADDIUR1SP +"addiu r, SP, " +*nanomips32r6: +*nanomips64r6: +{ + do_addiu (SD_, SPIDX, TRT_NM, U_SHIFT_2BIT); +} + +100100,3.RT,3.RS,0,3.U:R6P16A2:16::ADDIUR2 +"addiu r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_addiu (SD_, TRS_NM, TRT_NM, U_SHIFT_2BIT); +} + +100100,5.RT,1.S1,1,3.S2:R6P16ADDIURS5:16::ADDIURS5 +"nop":RT==0 +"addiu r, " +*nanomips32r6: +*nanomips64r6: +{ + if (RT != 0) + do_addiu (SD_, RT, RT, S_4_BIT); +} + +000001,5.RT,20.S1,1.S2:R6P32:32::ADDIUPC +"addiu r, " +*nanomips32r6: +*nanomips64r6: +{ + GPR[RT] = ADDRESS22; +} + +011000,5.RT,00011,16.IMM48:R6POOL48I:32::ADDIUPC48 +"addiu r, " +*nanomips32r6: +*nanomips64r6: +{ + uint16_t U2; + uint32_t total; + check_nms_flag (SD_); + U2 = do_load (SD_, AccessLength_HALFWORD, CIA + 4, 0); + total = U2 << 16 | IMM48; + TRACE_ALU_INPUT2(GPR[RT], total); + GPR[RT] = CIA + 6 + EXTEND32(total); + TRACE_ALU_RESULT(GPR[RT]); + NIA = CIA + 6; +} + +101100,3.RT,3.RS,3.RD,0:R6P16ADDU:16::ADDU16 +"addu r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_addu (SD_, TRS_NM, TRT_NM, TRD_NM); +} + +001111,1.RT1,0,3.RT2,1.RS1,0,3.RS2:R6P164X4:16::ADDU4X4 +"addu r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_addu (SD_, RS_5_BIT_NM, RT_5_BIT_NM, RT_5_BIT_NM); +} + +010100,3.RT,3.RS,10,0,0:R6POOL16C00:16::AND16 +"and r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_and (SD_, TRS_NM, TRT_NM, TRT_NM); +} + +111100,3.RT,3.RS,4.EU:R6P16:16::ANDI16 +"andi r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_andi (SD_, TRS_NM, TRT_NM, EU_12_13); +} + +001110,9.S1,1.S2:R6P16:16::BALC16 +"balc " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT1(RA); + RA = NIA; + NIA = ADDRESS11; + TRACE_ALU_RESULT(RA); + + // For cycle counting + COP0_COUNT++; +} + +000110,9.S1,1.S2:R6P16:16::BC16 +"bc " +*nanomips32r6: +*nanomips64r6: +{ + NIA = ADDRESS11; +} + +110110,3.RT,3.RS,4.U!0:R6P16BR1:16::BxxC16 +"beqc r, r, ":RS, r, " +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + TRACE_ALU_INPUT2(GPR[TRS_NM], GPR[TRT_NM]); + if (RS < RT && GPR[TRS_NM] == GPR[TRT_NM]) + NIA = NIA + U_SHIFT_1BIT; //BEQC + else if (RS >= RT && GPR[TRS_NM] != GPR[TRT_NM]) + NIA = NIA + U_SHIFT_1BIT; //BNEC +} + +100110,3.RT,6.S1,1.S2:R6P16:16::BEQZC16 +"beqzc r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT1(GPR[TRT_NM]); + if(GPR[TRT_NM] == 0) + NIA = ADDRESS8; +} + +101110,3.RT,6.S1,1.S2:R6P16:16::BNEZC16 +"bnezc r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT1(GPR[TRT_NM]); + if(GPR[TRT_NM] != 0) + NIA = ADDRESS8; +} + +110110,5.RT,1,0000:R6P16JRC:16::JALRC16 +"jalrc r" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], RA); + RA = NIA; + NIA = GPR[RT]; + TRACE_ALU_RESULT(RA); + + // For cycle counting + COP0_COUNT++; +} + +110110,5.RT,0,0000:R6P16JRC:16::JRC16 +"jrc r" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT1(GPR[RT]); + NIA = GPR[RT]; +} + +010111,3.RT,3.RS,00,2.U:R6P16LB:16::LB16 +"lb r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lb (SD_, TRT_NM, U, TRS_NM); +} + +010111,3.RT,3.RS,10,2.U:R6P16LB:16::LBU16 +"lbu r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2 (U, GPR[TRS_NM]); + do_lbu (SD_, TRT_NM, U, TRS_NM); + TRACE_ALU_RESULT (GPR[TRT_NM]); +} + +011111,3.RT,3.RS,0,2.U,0:R6P16LH:16::LH16 +"lh r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lh (SD_, TRT_NM, U_SHIFT_1BIT, TRS_NM); +} + +011111,3.RT,3.RS,1,2.U,0:R6P16LH:16::LHU16 +"lhu r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lhu (SD_, TRT_NM, U_SHIFT_1BIT, TRS_NM); +} + +110100,3.RT,7.EU:R6P16:16::LI16 +"li r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT1(GPR[TRT_NM]); + GPR[TRT_NM] = EU_127; + TRACE_ALU_RESULT(GPR[TRT_NM]); +} + +011101,1.RT1,1.U2,3.RT2,1.RS1,1.U3,3.RS2:R6P16:16::LW4X4 +"lw r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_lw (SD_, RT_5_BIT_NM, U_LW4X4, RS_5_BIT_NM); +} + +000101,3.RT,3.RS,4.U:R6P16:16::LW16 +"lw r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lw (SD_, TRT_NM, U_SHIFT_2BIT, TRS_NM); +} + +010101,3.RT,7.U:R6P16:16::LWGP16 +"lw r, (gp)" +*nanomips32r6: +*nanomips64r6: +{ + do_lw (SD_, TRT_NM, U_SHIFT_2BIT, GPIDX); +} + +001101,5.RT,5.U:R6P16:16::LWSP +"lw r, (sp)" +*nanomips32r6: +*nanomips64r6: +{ + do_lw (SD_, RT, U_SHIFT_2BIT, SPIDX); +} + +010100,3.RT,3.RS,3.RD,1:R6P16C:16::LWXS16 +"lwxs r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lw (SD_, TRD_NM, GPR[TRS_NM] << 2, TRT_NM); +} + +// These four instructions are grouped together because of a bug in GNUSIM +// pattern recognition +000100,5.RT,2.RS1,1.RS_CODE_1,2.RS_CODE_2:R6P16MOVE:16::P16MOVE_P16RI +"move r, r": RT != 0 +"syscall ": RS1 == 1 +"sdbbp ": RS1 == 3 +"break " +*nanomips32r6: +*nanomips64r6: +{ + if (RT == 0) { + if (RS1 == 1) + SignalException (SystemCall, instruction_0); + else if (RS1 == 3) + SignalException (DebugBreakPoint, instruction_0); + else + do_break_nanomips (SD_, instruction_0); + } + else { + TRACE_ALU_INPUT2 (GPR[RT], GPR[RS_MOVE]); + GPR[RT] = GPR[RS_MOVE]; + TRACE_ALU_RESULT2 (GPR[RT], GPR[RS_MOVE]); + } +} + +101111,1.RT4,1.RD20,3.RT2_0,1.RS4,1.RD21,3.RS2_0:R6P16:16::MOVEP +"movep r, r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + TRACE_ALU_INPUT4 (GPR[TRD2], GPR[TRE2], GPR[TRS2], GPR[TRT2]); + GPR[TRD2] = GPR[TRS2]; + GPR[TRE2] = GPR[TRT2]; + TRACE_ALU_RESULT2 (GPR[TRD2], GPR[TRE2]); + + // For cycle counting + COP0_COUNT++; +} + +111111,1.RE4,1.RS20,3.RE2_0,1.RD4,1.RS21,3.RD2_0:R6P16:16::MOVEPREV +"movep r, r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + TRACE_ALU_INPUT4 (GPR[TRD2_REV], GPR[TRE2_REV], GPR[TRS2_REV], GPR[TRT2_REV]); + GPR[TRD2_REV] = GPR[TRS2_REV]; + GPR[TRE2_REV] = GPR[TRT2_REV]; + TRACE_ALU_RESULT2 (GPR[TRD2_REV], GPR[TRE2_REV]); + + // For cycle counting + COP0_COUNT++; +} + +010100,3.RT,3.RS,00,0,0:R6POOL16C00:16::NOT16 +"not r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_nor (SD_, 0, TRS_NM, TRT_NM); +} + +010100,3.RT,3.RS,11,0,0:R6POOL16C00:16::OR16 +"or r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_or (SD_, TRS_NM, TRT_NM, TRT_NM); +} + +000111,1.RT1,1,4.U,4.GPR_LIST_SAVE:R6P16SR:16::RESTORE.JRC16 +"restore.jrc ":GPR_LIST_SAVE==15 +"restore.jrc , ra, %s" +*nanomips32r6: +*nanomips64r6: +{ + if (RT1 == 0) + do_restore_gprs_from_stack_and_adjust_sp(SD_, 30, GPR_LIST_SAVE, 0, + U_SHIFT_4BIT); + else + do_restore_gprs_from_stack_and_adjust_sp(SD_, 31, GPR_LIST_SAVE, 0, + U_SHIFT_4BIT); + NIA = RA; +} + +000111,1.RT1,0,4.U,4.GPR_LIST_SAVE:R6P16SR:16::SAVE16 +"save , ra": GPR_LIST_SAVE == 0 +"save , ra, %s" +*nanomips32r6: +*nanomips64r6: +{ + if (RT1 == 0) + do_save_gprs_to_stack_and_adjust_sp(SD_, 30, GPR_LIST_SAVE, 0, U_SHIFT_4BIT); + else + do_save_gprs_to_stack_and_adjust_sp(SD_, 31, GPR_LIST_SAVE, 0, U_SHIFT_4BIT); + +} + +010111,3.RTZ,3.RS,01,2.U:R6P16LB:16::SB16 +"sb r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_BYTE, GPR[TRS_NM], U, GPR[TRTZ]); +} + +011111,3.RTZ,3.RS,0,2.U,1:R6P16LH:16::SH16 +"sh r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_HALFWORD, GPR[TRS_NM], U_SHIFT_1BIT, GPR[TRTZ]); +} + +001100,3.RT,3.RS,0,3.SHIFT:R6P16SHIFT:16::SLL16 +"sll r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_sll (SD_, TRS_NM, TRT_NM, SHIFT_DEC); +} + +001100,3.RT,3.RS,1,3.SHIFT:R6P16SHIFT:16::SRL16 +"srl r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_srl (SD_, TRS_NM, TRT_NM, SHIFT_DEC); +} + +101100,3.RT,3.RS,3.RD,1:R6P16ADDU:16::SUBU16 +"subu r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_subu (SD_, TRS_NM, TRT_NM, TRD_NM); +} + +100101,3.RTZ,3.RS,4.U:R6P16:16::SW16 +"sw r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_WORD, GPR[TRS_NM], U_SHIFT_2BIT, GPR[TRTZ]); +} + +101101,5.RT,5.U:R6P16:16::SWSP +"sw r, (sp)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_WORD, SP, U_SHIFT_2BIT, GPR[RT]); +} + +010100,3.RT,3.RS,01,0,0:R6POOL16C00:16::XOR16 +"xor r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_xor (SD_, TRT_NM, TRS_NM, TRT_NM); +} + +// 32-bit instructions + +001000,5.RT,5.RS,5.RD,1.X,0100010,000:R6POOL32A0:32::ADD +"add r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_add (SD_, RS, RT, RD); +} + +000000,5.RT!0,5.RS,16.U:R6PPADDIU:32::ADDIU +"addiu r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_addiu (SD_, RS, RT, U); +} + +010001,5.RT,011,18.U:R6PGPBH:32::ADDIUGPB +"addiu r, GP, " +*nanomips32r6: +*nanomips64r6: +{ + do_addiu (SD_, GPIDX, RT, U); +} + +010000,5.RT,19.U,00:R6PGPW:32::ADDIUGPW +"addiu r, GP, " +*nanomips32r6: +*nanomips64r6: +{ + do_addiu (SD_, GPIDX, RT, U_SHIFT_2BIT); +} + +111000,5.RT,9.S1,10.S2,1,1.S3:R6PLUI:32::ALUIPC +"aluipc r, " +*nanomips32r6: +*nanomips64r6: +{ + address_word address = NIA + AXUIPC_S; + + TRACE_ALU_INPUT2(GPR[RT], address); + GPR[RT] = address & ~0xfff; + TRACE_ALU_RESULT(GPR[RT]); +} + +001000,5.RT,5.RS,5.RD,1.X,0101010,000:R6POOL32A0:32::ADDU +"addu r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_addu (SD_, RS, RT, RD); +} + +001000,5.RT,5.RS,5.RD,5.IMMEDIATE,011,111:R6POOL32A0:32::EXTW +"prepend r, r, ": RD == RS +"align r, r, r, ": IMMEDIATE != 0 +"extw r, r, r, " +*nanomips32r6: +*nanomips64r6: +{ + if (IMMEDIATE != 0) { + uint64_t tmp = ((uint64_t)GPR[RT] << 32) | (0xffffffff & GPR[RS]); + TRACE_ALU_INPUT4 (GPR[RD], GPR[RS], GPR[RT], tmp); + GPR[RD] = EXTEND32 (tmp >> IMMEDIATE); + TRACE_ALU_RESULT (GPR[RD]); + } else { + TRACE_ALU_INPUT2 (GPR[RD], GPR[RT]); + GPR[RD] = GPR[RT]; + TRACE_ALU_RESULT (GPR[RD]); + } +} + +001000,5.RT,5.RS,5.RD,1.X,1001010,000:R6POOL32A0:32::AND +"and r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_and (SD_, RS, RT, RD); +} + +100000,5.RT,5.RS,0010,12.U:R6PU12:32::ANDI +"andi r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_andi (SD_, RS, RT, U); +} + +001010,1,24.S1,1.S2:R6PBAL:32::BALC +"balc " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT1(RA); + RA = NIA; + NIA = ADDRESS26; + TRACE_ALU_RESULT(RA); + + // For cycle counting + COP0_COUNT++; +} + +001010,0,24.S1,1.S2:R6PBAL:32::BC +"bc " +*nanomips32r6: +*nanomips64r6: +{ + NIA = ADDRESS26; +} + +100010,5.RT,5.RS,00,13.S1,1.S2:R6PBR1:32::BEQC +"beqc r, r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RS], GPR[RT]); + if (GPR[RS] == GPR[RT]) + NIA = ADDRESS15; +} + +110010,5.RT,000,7.U,10.S1,1.S2:P7PBRI:32::BEQIC +"beqic r, , " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], U); + if (GPR[RT] == U) { + NIA = ADDRESS12; + } +} + +100010,5.RT,5.RS,10,13.S1,1.S2:P7PBR1:32::BGEC +"bgec r, r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RS], GPR[RT]); + if ((signed_word) GPR[RS] >= (signed_word) GPR[RT]) + NIA = ADDRESS15; +} + +110010,5.RT,010,7.U,10.S1,1.S2:P7PBRI:32::BGEIC +"bgeic r, , " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], U); + if ((signed_word) GPR[RT] >= U) { + NIA = ADDRESS12; + } +} + +100010,5.RT,5.RS,11,13.S1,1.S2:P7PBR2:32::BGEUC +"bgeuc r, r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RS], GPR[RT]); + if ((unsigned_word) (GPR[RS]) >= (unsigned_word)(GPR[RT])) { + NIA = ADDRESS15; + } +} + +110010,5.RT,011,7.U,10.S1,1.S2:P7PBRI:32::BGEUIC +"bgeuic r, , " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], U); + if ((unsigned_word) GPR[RT] >= U) { + NIA = ADDRESS12; + } +} + +101010,5.RT,5.RS,10,13.S1,1.S2:P7PBR2:32::BLTC +"bltc r, r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RS], GPR[RT]); + if ((signed_word) GPR[RS] < (signed_word) GPR[RT]) + NIA = ADDRESS15; +} + +110010,5.RT,110,7.U,10.S1,1.S2:P7PBRI:32::BLTIC +"bltic r, , " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], U); + if ((signed_word) GPR[RT] < U) { + NIA = ADDRESS12; + } +} + +101010,5.RT,5.RS,11,13.S1,1.S2:P7PBR2:32::BLTUC +"bltuc r, r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RS], GPR[RT]); + if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT]) { + NIA = ADDRESS15; + } +} + +110010,5.RT,111,7.U,10.S1,1.S2:P7PBRI:32::BLTIUC +"bltiuc , , " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], U); + if ((unsigned_word) GPR[RT] < U) { + NIA = ADDRESS12; + } +} + +101010,5.RT,5.RS,00,13.S1,1.S2:R6PBR2:32::BNEC +"bnec r, r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RS], GPR[RT]); + if (GPR[RS] != GPR[RT]) + NIA = ADDRESS15; +} + +110010,5.RT,100,7.U,10.S1,1.S2:R6PBRI:32::BNEIC +"bneic r, , " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], U); + if (GPR[RT] != U) { + NIA = ADDRESS12; + } +} + +000000,00000,10,19.CODE:R6PRI:32::BREAK +"break %#lx" +*nanomips32r6: +*nanomips64r6: +{ + do_break_nanomips (SD_, instruction_0); +} + +101001,5.OP,5.RS,1.S1,0111,0,01,8.S2:R6PLSS1:32::CACHE +"cache , (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_cache (SD_, OP, RS, S_9_BIT, instruction_0); +} + +001000,5.RT,5.RS,0100101,100,111,111:R6POOL32AXF4:32::CLO +"clo r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_clo (SD_, RT, RS); +} + +001000,5.RT,5.RS,0101101,100,111,111:R6POOL32AXF4:32::CLZ +"clz r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_clz (SD_, RT, RS); +} + +001000,5.RT,5.X,01,00011,101,111,111:R6POOL32AXF5GROUP1:32::DI +"di":RT == 0 +"di r" +*nanomips32r6: +*nanomips64r6: +{ + do_di (SD_, RT); +} + +001000,5.RT,5.RS,5.RD,1.X,0100011,000:R6POOL32A0:32::DIV +"div r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_div (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.RD,1.X,0110011,000:R6POOL32A0:32::DIVU +"divu r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_divu (SD_, RD, RS, RT); +} + +001000,5.RT,5.X,01,01011,101,111,111:R6POOL32AXF5GROUP1:32::EI +"ei":RT == 0 +"ei r" +*nanomips32r6: +*nanomips64r6: +{ + do_ei (SD_, RT); +} + +001000,9.X,0,11,11001,101,111,111:R6ERETX:32::ERET +"eret" +*nanomips32r6: +*nanomips64r6: +{ + NIA = do_eret(SD_, 0, NIA); +} + +001000,9.X,1,11,11001,101,111,111:R6ERETX:32::ERETNC +"eretnc" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + SignalException (ReservedInstruction, instruction_0); + NIA = do_eret(SD_, 1, NIA); +} + +100000,5.RT,5.RS,1111,0,5.MSBD,0,5.LSB:R6PEXT:32::EXT +"ext r, r, , " +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + if (LSB + MSBD + 1 > 32) + Unpredictable (); + + do_ext (SD_, RT, RS, LSB, MSBD); +} + +100000,5.RT,5.RS,1110,0,5.MSBD,0,5.LSB:R6PINS:32::INS +"ins r, r, , " +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + if ((1 + MSBD - LSB) < 1) + Unpredictable (); + do_ins (SD_, RT, RS, LSB, MSBD); +} + +100000,5.RT,5.RS,1101,0,4.SHIFTX,1.STRIPE,0,5.SHIFT:R6PROTX:32::ROTX +"bitrev r, r": SHIFT == 31 && SHIFTX_1BIT == 0 +"bitswap r, r": SHIFT == 7 && SHIFTX_1BIT == 8 && STRIPE == 1 +"bitswap.h r, r": SHIFT == 15 && SHIFTX_1BIT == 16 +"byteswap r, r": SHIFT == 24 && SHIFTX_1BIT == 8 +"wsbh r, r": SHIFT == 8 && SHIFTX_1BIT == 24 +"rotx r, r, , ": STRIPE == 0 +"rotx r, r, , , " +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + + TRACE_ALU_INPUT4 (GPR[RT], GPR[RS], SHIFT, SHIFTX_1BIT); + do_rotx (SD_, RT, RS, SHIFT, SHIFTX_1BIT, STRIPE); + TRACE_ALU_RESULT (GPR[RT]); +} + +010010,5.RT,5.RS,0000,12.X:R6PJ:32::JALRC +"jalrc r, r" +*nanomips32r6: +*nanomips64r6: +{ + unsigned_word address; + TRACE_ALU_INPUT3(GPR[RT], GPR[RS], RA); + GPR[RT] = NIA; + address = GPR[RS]; + NIA = address; + + // For cycle counting + COP0_COUNT++; + TRACE_ALU_RESULT(NIA); + +} + +010010,5.RT,5.RS,0001,12.X:R6PJ:32::JALRC.HB +"jalrc.hb r, r" +*nanomips32r6: +*nanomips64r6: +{ + unsigned_word address; + GPR[RT] = NIA; + address = GPR[RS]; + NIA = address; + + // For cycle counting + COP0_COUNT++; +} + +100001,5.RT,5.RS,0000,12.U:R6PLSU12:32::LB +"lb r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lb (SD_, RT, U, RS); +} + +010001,5.RT,000,18.U:R6PLSGP:32::LBGP +"lb r, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + do_lb (SD_, RT, U, GPIDX); +} + +101001,5.RT,5.RS,1.S1,0000,0,00,8.S2:R6PLSS0:32::LBS9 +"lb r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lb (SD_, RT, S_9_BIT, RS); +} + +100001,5.RT,5.RS,0010,12.U:R6PLSU12:32::LBU +"lbu r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lbu (SD_, RT, U, RS); +} + +010001,5.RT,010,18.U:R6GPBH:32::LBUGP +"lbu r, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2 (U, GP); + do_lbu (SD_, RT, U, GPIDX); + TRACE_ALU_RESULT (GPR[RT]); +} + +101001,5.RT,5.RS,1.S1,0010,0,00,8.S2:R6PLSS0:32::LBUS9 +"lbu r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lbu (SD_, RT, S_9_BIT, RS); +} + +001000,5.RT,5.RS,5.RD,0010,0,000,111:R6PPLSX:32::LBUX +"lbux r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lbu (SD_, RD, GPR[RS], RT); +} + +001000,5.RT,5.RS,5.RD,0000,0,000,111:R6PPLSX:32::LBX +"lbx r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lb (SD_, RD, GPR[RS], RT); +} + +100001,5.RT,5.RS,0100,12.U:R6PLSU12:32::LH +"lh r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lh (SD_, RT, U, RS); +} + +010001,5.RT,100,17.U,0:R6PGPLH:32::LHGP +"lh r, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + do_lh (SD_, RT, U_SHIFT_1BIT, GPIDX); +} + +101001,5.RT,5.RS,1.S1,0100,0,00,8.S2:R6PLSS0:32::LHS9 +"lh r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lh (SD_, RT, S_9_BIT, RS); +} + +100001,5.RT,5.RS,0110,12.U:R6PLSU12:32::LHU +"lhu r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lhu (SD_, RT, U, RS); +} + +010001,5.RT,100,17.U,1:R6PLSGP:32::LHUGP +"lhu r, (gp)" +*nanomips32r6: +*nanomips64r6: +{ + do_lhu (SD_, RT, U_SHIFT_1BIT, GPIDX); +} + +101001,5.RT,5.RS,1.S1,0110,0,00,8.S2:R6PLSS0:32::LHUS9 +"lhu r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lhu (SD_, RT, S_9_BIT, RS); +} + +001000,5.RT,5.RS,5.RD,0110,0,000,111:R6PPLSX:32::LHUX +"lhux r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lhu (SD_, RD, GPR[RS], RT); +} + +001000,5.RT,5.RS,5.RD,0110,1,000,111:R6PPLSXS:32::LHUXS +"lhux r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lhu (SD_, RD, GPR[RS] << 1, RT); +} + +001000,5.RT,5.RS,5.RD,0100,0,000,111:R6PPLSX:32::LHX +"lhx r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lh (SD_, RD, GPR[RS], RT); +} + +001000,5.RT,5.RS,5.RD,0100,1,000,111:R6PPLSXS:32::LHXS +"lhxs r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lh (SD_, RD, GPR[RS] << 1, RT); +} + +101001,5.RT,5.RS,1.S1,1010,0,01,6.S2,00:R6PLL:32::LL +"ll r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(GPR[RT], S_9_BIT_LLSC, GPR[RS]); + do_ll (SD_, RT, S_9_BIT_LLSC, RS); + TRACE_ALU_RESULT(GPR[RT]); +} + +101001,5.RT,5.RS,1.X1,1010,0,01,5.RU,1.X2,01:R6PLL:32::LLWP +"llwp r, r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_llwp (SD_, RT, RU, 0, RS); +} + +001000,5.RT,5.RS,5.RD,2.U,3.X,001,111:R6POOL32A7:32::LSA +"lsa r, r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_lsa (SD_, RD, RS, RT, U); +} + +111000,5.RT,9.S1,10.S2,0,1.S3:R6PLUI:32::LUI +"lui r, , ":AXUIPC_S_LO != 0 +"lui r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2 (GPR[RT], AXUIPC_S); + GPR[RT] = AXUIPC_S; + TRACE_ALU_RESULT (GPR[RT]); +} + +100001,5.RT,5.RS,1000,12.U:R6PLSU12:32::LW +"lw r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3 (GPR[RT], U, GPR[RS]); + do_lw (SD_, RT, U, RS); + TRACE_ALU_RESULT (GPR[RT]); +} + +101001,5.RT,5.RS,1.S1,1000000,8.S2:R6PLSS0:32::LWS9 +"lw r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lw (SD_, RT, S_9_BIT, RS); +} + +101001,5.RT,5.RS,1.S1,3.COUNT3,0,1,00,8.S2:R6PLSWM:32::LWM +"lwm r, (r), " +*nanomips32r6: +*nanomips64r6: +{ + int counter = 0; + int dest; + int this_offset; + + check_nms_flag (SD_); + + while (counter != COUNT) + { + dest = (RT & 0x10) | ((RT + counter) & 0x1F); + + if ((dest == RS) && (counter != (COUNT - 1))) + Unpredictable (); + + this_offset = S_9_BIT + (counter << 2); + + do_lw (SD_, dest, this_offset, RS); + + counter++; + if (counter != 0) + COP0_COUNT++; + } +} + +010000,5.RT,19.U,10:R6PGPW:32::LWGP +"lw r, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], GPR[RT]); + do_lw (SD_, RT, U_SHIFT_2BIT, GPIDX); + TRACE_ALU_RESULT(GPR[RT]); +} + +011000,5.RT,01011,16.IMM48:R6POOL48I:32::LWPC48 +"lwpc r, " +*nanomips32r6: +*nanomips64r6: +{ + uint16_t S2; + uint32_t total; + check_nms_flag (SD_); + S2 = do_load(SD_, AccessLength_HALFWORD, CIA + 4, 0); + total = S2 << 16 | IMM48; + + do_lwpc_nanomips (SD_, RT, total, CIA + 6); + NIA = CIA + 6; +} + +001000,5.RT,5.RS,5.RD,1000,0,000,111:R6PPLSX:32::LWX +"lwx r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lw (SD_, RD, GPR[RS], RT); +} + +001000,5.RT,5.RS,5.RD,1000,1,000,111:R6PPLSXS:32::LWXS +"lwxs r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lw (SD_, RD, GPR[RS] << 2, RT); +} + +001000,5.RT,5.C0S,5.SEL,1.X,0000110,000:R6POOL32A0:32::MFC0 +"mfc0 r, r, " +*nanomips32r6: +*nanomips64r6: +{ + DecodeCoproc (instruction_0, 0, cp0_mfc0, RT, C0S, SEL); +} + +001000,5.RT,5.RS,5.RD,1.X,0101011,000:R6POOL32A0:32::MOD +"mod r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_mod (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.RD,1.X,0111011,000:R6POOL32A0:32::MODU +"modu r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_modu (SD_, RD, RS, RT); +} + +000010,1.RT1,1.RD,3.RT2,20.S1,1.S2:R6MOVEBALC:32::MOVE.BALC +"move.balc r, r, " +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + TRACE_ALU_INPUT2(GPR[RD1], GPR[RT_5_BIT_NM_Z]); + GPR[RD1] = GPR[RT_5_BIT_NM_Z]; + RA = NIA; + NIA = ADDRESS22; + TRACE_ALU_RESULT(GPR[RD1]); + + // For cycle counting + COP0_COUNT += 2; +} + +001000,5.RT,5.RS,5.RD,1,1000010,000:R6PCMOVE:32::MOVN +"movn r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RS], GPR[RT]); + do_movn (SD_, RD, RS, RT); + TRACE_ALU_RESULT(GPR[RD]); +} + +001000,5.RT,5.RS,5.RD,0,1000010,000:R6PCMOVE:32::MOVZ +"movz r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_movz (SD_, RD, RS, RT); +} + +001000,5.RT,5.C0S,5.SEL,1.X,0001110,000:R6POOL32A0:32::MTC0 +"mtc0 r, r, " +*nanomips32r6: +*nanomips64r6: +{ + DecodeCoproc (instruction_0, 0, cp0_mtc0, RT, C0S, SEL); +} + +001000,5.RT,5.RS,5.RD,1.X,0001011,000:R6POOL32A0:32::MUH +"muh r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_muh (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.RD,1.X,0011011,000:R6POOL32A0:32::MUHU +"muhu r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_muhu (SD_, RD, RS, RT); +} + +001000,5.RT,5.RS,5.RD,1.X,0000011,000:R6POOL32A0:32::MUL32 +"mul r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_mul (SD_, RD, RS, RT); +} + +001111,1.RT1,0,3.RT2,1.RS1,1,3.RS2:R6P164X4:16::MUL4X4 +"mul r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_mul (SD_, RT_5_BIT_NM, RS_5_BIT_NM, RT_5_BIT_NM); +} + +001000,5.RT,5.RS,5.RD,1.X,0010011,000:R6POOL32A0:32::MULU +"mulu r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_mulu (SD_, RD, RS, RT); +} + +100000,00000,5.X1,1100,3.X2,0000,00000:R6PSLL:32::NOP32 +"nop" +*nanomips32r6: +*nanomips64r6: +{ +} + +001000,5.RT,5.RS,5.RD,1.X,1011010,000:R6POOL32A0:32::NOR +"nor r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_nor (SD_, RS, RT, RD); +} + +001000,5.RT,5.RS,5.RD,1.X,1010010,000:R6POOL32A0:32::OR32 +"or r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_or (SD_, RS, RT, RD); +} + +100000,5.RT,5.RS,0000,12.U:R6PU12:32::ORI +"ori r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_ori (SD_, RS, RT, U); +} + +100000,00000,5.X1,1100,3.X2,0000,00101:R6PSLL:32::PAUSE +"pause" +*nanomips32r6: +*nanomips64r6: +{ + sim_io_printf (SD, "Not implemented"); +} + +101001,5.HINT!31,5.RS,1.S1,0011,0,00,8.S2:R6PPREFS9:32::PREFS9 +"pref , (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_pref (SD_, HINT, S_9_BIT, RS); +} + +100001,5.HINT,5.RS,0011,12.U:R6PLSU12:32::PREFU12 +"pref , (r)": HINT != 31 +"synci (r)" +*nanomips32r6: +*nanomips64r6: +{ + if (HINT != 31) + do_pref (SD_, HINT, U, RS); + else + { + // synci - nothing to do currently + sim_io_printf (SD, "Not implemented"); + } +} + +100000,5.RT,0,4.GPR_LIST_SAVE,0011,9.U,1.GP_SAVE,10:R6PPSR:32::RESTORE +"restore , r": GPR_LIST_SAVE == 0 +"restore , r, %s": !GP_SAVE && GPR_LIST_SAVE != 0 +"restore , r": !GP_SAVE && GPR_LIST_SAVE < 2 +"restore , r, %s" : !GP_SAVE && GPR_LIST_SAVE >=2 +"restore , r, %s": GP_SAVE && GPR_LIST_SAVE < 2 +"restore , r, %s, %s" : GP_SAVE && GPR_LIST_SAVE >=2 +"restore , r, %s": GP_SAVE && GPR_LIST_SAVE < 3 +"restore , r, %s, %s" +*nanomips32r6: +*nanomips64r6: +{ + do_restore_gprs_from_stack_and_adjust_sp(SD_, RT, GPR_LIST_SAVE, + GP_SAVE, U_SHIFT_3BIT); +} + +100000,5.RT,0,4.GPR_LIST_SAVE,0011,9.U,1.GP_SAVE,11:R6PPSR:32::RESTORE.JRC +"restore.jrc , r": GPR_LIST_SAVE == 0 +"restore.jrc , r, %s": !GP_SAVE && GPR_LIST_SAVE != 0 +"restore.jrc , r": !GP_SAVE && GPR_LIST_SAVE < 2 +"restore.jrc , r, %s" : !GP_SAVE && GPR_LIST_SAVE >=2 +"restore.jrc , r, %s": GP_SAVE && GPR_LIST_SAVE < 2 +"restore.jrc , r, %s, %s" : GP_SAVE && GPR_LIST_SAVE >=2 +"restore.jrc , r, %s": GP_SAVE && GPR_LIST_SAVE < 3 +"restore.jrc , r, %s, %s" +*nanomips32r6: +*nanomips64r6: +{ + do_restore_gprs_from_stack_and_adjust_sp(SD_, RT, GPR_LIST_SAVE, + GP_SAVE, U_SHIFT_3BIT); + + NIA = GPR[RAIDX]; +} + +100000,5.RT,5.RS,1100,3.X,0110,5.SHIFT:R6PSHIFT:32::ROTR +"rotr r, r, " +*nanomips32r6: +*nanomips64r6: +{ + GPR[RT] = do_ror (SD_, GPR[RS], SHIFT); +} + +001000,5.RT,5.RS,5.RD,1.X,0011010,000:R6POOL32A0:32::ROTRV +"rotrv r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + uint32_t shift = GPR[RT] & 0x1f; + GPR[RD] = do_ror (SD_, GPR[RS], shift); +} + +001000,5.RT,5.RS,5.RD,0,1100010,000:R6POOL32A0:32::XOR +"xor r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_xor (SD_, RS, RT, RD); +} + +100000,5.RT,5.RS,0001,12.U:R6PU12:32::XORI +"xori r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_xori (SD_, RS, RT, U); +} + +100000,5.RT,0,4.GPR_LIST_SAVE,0011,9.U,1.GP_SAVE,00:R6PPSR:32::SAVE +"save , r": GPR_LIST_SAVE == 0 +"save , r, %s": !GP_SAVE && GPR_LIST_SAVE != 0 +"save , r": !GP_SAVE && GPR_LIST_SAVE < 2 +"save , r %s" : !GP_SAVE && GPR_LIST_SAVE >=2 +"save , r, %s": GP_SAVE && GPR_LIST_SAVE < 2 +"save , r, %s, %s" : GP_SAVE && GPR_LIST_SAVE >=2 +"save , r, %s": GP_SAVE && GPR_LIST_SAVE < 3 +"save , r, %s, %s" +*nanomips32r6: +*nanomips64r6: +{ + do_save_gprs_to_stack_and_adjust_sp(SD_, RT, GPR_LIST_SAVE, + GP_SAVE, U_SHIFT_3BIT); +} + +100001,5.RT,5.RS,0001,12.U:R6PLSU12:32::SBU12 +"sb r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_BYTE, GPR[RS], U, GPR[RT]); +} + +010001,5.RT,001,18.U:R6PGPBH:32::SBGP +"sb r, (gp)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_BYTE, GP, U, GPR[RT]); +} + +101001,5.RT,5.RS,1.S1,0001,0,00,8.S2:R6PLSS0:32::SBS9 +"sb r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_BYTE, GPR[RS], S_9_BIT, GPR[RT]); +} + +001000,5.RT,5.RS,5.RD,0001,0,000,111:R6PPLSX:32::SBX +"sbx r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_store (SD_, AccessLength_BYTE, GPR[RT], GPR[RS], GPR[RD]); +} + +101001,5.RT,5.RS,1.S1,1011,0,01,6.S2,00:R6PSC:32::SC +"sc r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_sc (SD_, RT, S_9_BIT_LLSC, RS, instruction_0, 1); +} + +101001,5.RT,5.RS,1.X1,1011,0,01,5.RU,1.X,01:R6PSC:32::SCWP +"scwp r, r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + int offset = BigEndianCPU ? 0 : 4; + + do_sc (SD_, RU, offset, RS, instruction_0, 0); + do_sc (SD_, RT, offset ^ 4, RS, instruction_0, 1); +} + +001000,5.RT,5.RS,6.X,0000001,000:R6POOL32A0:32::SEB +"seb r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_seb (SD_, RT, RS); +} + +001000,5.RT,5.RS,6.X,0001001,000:R6POOL32A0:32::SEH +"seh r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_seh (SD_, RT, RS); +} + +100000,5.RT,5.RS,0110,12.IMMEDIATE:R6PU12:32::SEQI +"seqi r, r, " +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(GPR[RT], GPR[RS], IMMEDIATE); + GPR[RT] = (GPR[RS] == IMMEDIATE) ? 1 : 0; + TRACE_ALU_RESULT(GPR[RT]); +} + +100001,5.RT,5.RS,0101,12.U:R6PLSU12:32::SHU12 +"sh r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_HALFWORD, GPR[RS], U, GPR[RT]); +} + +010001,5.RT,101,17.U,0:R6PGPSH:32::SHGP +"sh r, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_HALFWORD, GP, U_SHIFT_1BIT, GPR[RT]); +} + +101001,5.RT,5.RS,1.S1,0101,0,00,8.S2:R6PLSS0:32::SHS9 +"sh r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_HALFWORD, GPR[RS], S_9_BIT, GPR[RT]); +} + +001000,5.RT,5.RS,5.RD,0101,0,000,111:R6PPLSX:32::SHX +"shx r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_store (SD_, AccessLength_HALFWORD, GPR[RT], GPR[RS], GPR[RD]); +} + +001000,5.RT,5.RS,5.RD,0101,1,000,111:R6PPLSXS:32::SHXS +"shxs r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_store (SD_, AccessLength_HALFWORD, GPR[RT], GPR[RS] << 1, GPR[RD]); +} + +000000,00000,00,19.CODE:R6PRI:32::SIGRIE +"sigrie %#lx" +*nanomips32r6: +*nanomips64r6: +{ + SignalException (ReservedInstruction, instruction_0); +} + +100000,5.RT!0,5.RS,1100,3.X,0000,5.SHIFT:R6PSLL:32::SLL32 +"sll r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_sll (SD_, RS, RT, SHIFT); +} + +001000,5.RT,5.RS,5.RD,1.X,0000010,000:R6POOL32A0:32::SLLV +"sllv r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_sllv (SD_, RT, RS, RD); +} + +001000,5.RT,5.RS,5.RD,1.X,1101010,000:R6POOL32A0:32::SLT +"slt r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_slt (SD_, RS, RT, RD); +} + +100000,5.RT,5.RS,0100,12.IMMEDIATE:R6PU12:32::SLTI +"slti r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_slti (SD_, RS, RT, EXTEND12(IMMEDIATE)); +} + +100000,5.RT,5.RS,0101,12.U:R6PU12:32::SLTIU +"sltiu r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_sltiu (SD_, RS, RT, EXTEND12(U)); +} + +001000,5.RT,5.RS,5.RD!0,1.X,1110010,000:R6PSLTU:32::SLTU +"sltu r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_sltu (SD_, RS, RT, RD); +} + +100000,5.RT,5.RS,1100,3.X,0100,5.SHIFT:R6PSHIFT:32::SRA +"sra r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_sra (SD_, RS, RT, SHIFT); +} + +001000,5.RT,5.RS,5.RD,1.X,0010010,000:R6POOL32A0:32::SRAV +"srav r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_srav (SD_, RT, RS, RD); +} + +100000,5.RT,5.RS,1100,3.X,0010,5.SHIFT:R6PSHIFT:32::SRL32 +"srl r, r, " +*nanomips32r6: +*nanomips64r6: +{ + do_srl (SD_, RS, RT, SHIFT); +} + +001000,5.RT,5.RS,5.RD,1.X,0001010,000:R6POOL32A0:32::SRLV +"srlv r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_srlv (SD_, RT, RS, RD); +} + +001000,5.RT,5.RS,5.RD,1.X,0110010,000:R6POOL32A0:32::SUB +"sub r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_sub (SD_, RS, RT, RD); +} + +001000,5.RT,5.RS,5.RD,1.X,0111010,000:R6POOL32A0:32::SUBU32 +"subu r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + do_subu (SD_, RS, RT, RD); +} + +100001,5.RT,5.RS,1001,12.U:R6PLSU12:32::SWU12 +"sw r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_WORD, GPR[RS], U, GPR[RT]); +} + +101001,5.RT,5.RS,1.S1,1001,0,00,8.S2:R6PLS0:32::SWS9 +"sw r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_WORD, GPR[RS], S_9_BIT, GPR[RT]); +} + +010000,5.RT,19.U,11:R6PGPW:32::SWGP +"sw r, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_WORD, GP, U_SHIFT_2BIT, GPR[RT]); +} + +011000,5.RT,01111,16.IMM48:R6POOL48I:32::SWPC48 +"swpc r, " +*nanomips32r6: +*nanomips64r6: +{ + uint16_t U2; + uint32_t total; + check_nms_flag (SD_); + U2 = do_load (SD_, AccessLength_HALFWORD, CIA + 4, 0); + total = U2 << 16 | IMM48; + TRACE_ALU_INPUT2(GPR[RT], total); + do_store(SD_, AccessLength_WORD, CIA + 6, total, GPR[RT]); + TRACE_ALU_RESULT(GPR[RT]); + NIA = CIA + 6; +} + + +110101,3.RTZ,7.U:R6P16:16::SWGP16 +"sw r, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + do_store (SD_, AccessLength_WORD, GP, U_SHIFT_2BIT, GPR[TRTZ]); +} + +001000,5.RT,5.RS,5.RD,1001,0,000,111:R6PPLSX:32::SWX +"swx r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_store (SD_, AccessLength_WORD, GPR[RT], GPR[RS], GPR[RD]); +} + +001000,5.RT,5.RS,5.RD,1001,1,000,111:R6PPLSXS:32::SWXS +"swxs r, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_store (SD_, AccessLength_WORD, GPR[RT], GPR[RS] << 2, GPR[RD]); +} + +111101,1.RT1,1.U2,3.RT2,1.RS1,1.U3,3.RS2:R6P16:16::SW4X4 +"sw r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_store (SD_, AccessLength_WORD, GPR[RS_5_BIT_NM], U_LW4X4, GPR[RT_5_BIT_NM_Z]); +} + +101001,5.RT,5.RS,1.S1,3.COUNT3,1,1,00,8.S2:R6PLSWM:32::SWM +"swm r, (r), " +*nanomips32r6: +*nanomips64r6: +{ + int counter = 0; + int source; + int offsetm; + + check_nms_flag (SD_); + + while (counter != COUNT) + { + if (RT == 0) + source = 0; + else + source = (RT & 0x10) | ((RT + counter) & 0x1F); + + offsetm = S_9_BIT + (counter << 2); + + do_sw (SD_, source, offsetm, RS); + + counter++; + + if (counter != 0) + COP0_COUNT++; + } +} + +100000,00000,5.STYPE,1100,3.X,0000,00110:R6PHB:32::SYNC +"sync":STYPE==0 +"sync " +*nanomips32r6: +*nanomips64r6: +{ + SyncOperation (STYPE); +} + +101001,11111,5.RS,1.S1,0011,0,00,8.S2:R6PPREFS:32::SYNCI +"synci (r)" +*nanomips32r6: +*nanomips64r6: +{ + // sync i-cache - nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + +000000,00000,11,19.CODE:R6PRI:32::SDBBP32 +"sdbbp %#lx" +*nanomips32r6: +*nanomips64r6: +{ + SignalException (DebugBreakPoint, instruction_0); +} + +001000,10.X,00,00001,101,111,111:R6POOL32AXF5GROUP0:32::TLBP +"tlbp" +*nanomips32r6: +*nanomips64r6: +{ + // nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + +001000,10.X,00,10001,101,111,111:R6POOL32AXF5GROUP0:32::TLBWI +"tlbwi" +*nanomips32r6: +*nanomips64r6: +{ + // nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + +001000,10.X,00,11001,101,111,111:R6POOL32AXF5GROUP0:32::TLBWR +"tlbwr" +*nanomips32r6: +*nanomips64r6: +{ + // nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + + +001000,0000000000,01,00001,101,111,111:R6POOL32AXF5GROUP1:32::TLBINV +"tlbinv" +*nanomips32r6: +*nanomips64r6: +{ + // invalidate a set of TLB entries based on ASID and Index match - nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + +001000,0000000000,01,01001,101,111,111:R6POOL32AXF5GROUP1:32::TLBINVF +"tlbinvf" +*nanomips32r6: +*nanomips64r6: +{ + // invalidate a set of TLB entries based on Index match - nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + +001000,10.CODE,10,00101,101,111,111:R6PSYSCALL:32::SYSCALL +"syscall %#lx" +*nanomips32r6: +*nanomips64r6: +{ + SignalException (SystemCall, instruction_0); +} + +100000,00000,5.X1,1100,3.X2,0000,00011:R6PHB:32::EHB +"ehb" +*nanomips32r6: +*nanomips64r6: +{ + // Do nothing, there are no hazards to clear +} + +001000,5.RT,5.RS,5.X,0,0000000,000:R6PTRAP:32::TEQ +"teq r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + + if (GPR[RS] == GPR[RT]) + SignalException(Trap, instruction_0); +} + +001000,5.RT,5.RS,5.X,1,0000000,000:R6PTRAP:32::TNE +"tne r, r" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + + if (GPR[RS] != GPR[RT]) + SignalException(Trap, instruction_0); +} + +101001,5.RT,5.RS,1.S1,0100,0,01,8.S2:R6PLSS1:32::UALH +"ualh r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + + TRACE_ALU_INPUT3(GPR[RT], S_9_BIT, GPR[RS]); + do_lh (SD_, RT, S_9_BIT, RS); + TRACE_ALU_RESULT(GPR[RT]); +} + +101001,5.RT,5.RS,1.S1,3.COUNT3,0,1,01,8.S2:R6PLSUAWM:32::UALWM +"ualwm r, (r), ":COUNT != 1 +"ualw r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + int i; + int dest; + int this_offset; + + address_word base = GPR[RS]; + for(i = 0; i< COUNT; i++) + { + dest = (RT & 0x10) | ((RT + i) & 0x1F); + + if (dest == RS && i != COUNT - 1) + Unpredictable (); + + this_offset = S_9_BIT + (i << 2); + + if(BigEndianCPU) { + GPR[dest] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, base, + EXTEND16 (this_offset), GPR[dest])); + GPR[dest] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, base, + EXTEND16 (this_offset + AccessLength_WORD), GPR[dest])); + } else { + GPR[dest] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, base, + EXTEND16 (this_offset), GPR[dest])); + GPR[dest] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, base, + EXTEND16 (this_offset + AccessLength_WORD), GPR[dest])); + } + + if (i != 0) + COP0_COUNT++; + } +} + +101001,5.RT,5.RS,1.S1,0101,0,01,8.S2:R6PLSS1:32::UASH +"uash r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + + do_store (SD_, AccessLength_HALFWORD, GPR[RS], S_9_BIT, GPR[RT]); +} + +101001,5.RT,5.RS,1.S1,3.COUNT3,1,1,01,8.S2:R6PLSUAWM:32::UASWM +"uaswm r, (r), ":COUNT != 1 +"uasw r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + + int i; + int source; + int offsetm; + + for(i = 0; i< COUNT; i++) + { + if (RT == 0) + source = 0; + else + source = (RT & 0x10) | ((RT + i) & 0x1F); + + offsetm = S_9_BIT + (i << 2); + + if(BigEndianCPU) { + do_store_left (SD_, AccessLength_WORD, GPR[RS], EXTEND16 (offsetm), GPR[source]); + do_store_right (SD_, AccessLength_WORD, GPR[RS], + EXTEND16 (offsetm + AccessLength_WORD), GPR[source]); + } else { + do_store_right (SD_, AccessLength_WORD, GPR[RS], EXTEND16 (offsetm), GPR[source]); + do_store_left (SD_, AccessLength_WORD, GPR[RS], + EXTEND16 (offsetm + AccessLength_WORD), GPR[source]); + } + + if (i != 0) + COP0_COUNT++; + } +} + +001000,5.RT,5.X,00000,0,1110010,000:R6PDVP:32::DVP +"dvp r" +*nanomips32r6: +*nanomips64r6: +{ + // nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + + +001000,5.RT,5.HS,2.X1,3.SEL,1.X2,0111000,000:R6POOL32A0:32::RDHWR +"rdhwr r, r, " +*nanomips32r6: +*nanomips64r6: +{ + check_nms_flag (SD_); + do_rdhwr (SD_, RT, HS); +} + +001000,5.RT,5.RS,11,10000,101,111,111:R6POOL32AXF5GROUP3:32::RDPGPR +"rdpgpr r, r" +*nanomips32r6: +*nanomips64r6: +{ + // nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + +001000,5.RT,5.RS,11,11000,101,111,111:R6POOL32AXF5GROUP3:32::WRPGPR +"wrpgpr r, r" +*nanomips32r6: +*nanomips64r6: +{ + // TODO: implement as given in the specification + sim_io_printf (SD, "Not implemented"); +} + +001000,5.RT,5.RS,5.RD,1.X,1111010,000:R6POOL32A0:32::SOV +"SOV r, r, r" +*nanomips32r6: +*nanomips64r6: +{ + if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT])) + Unpredictable (); + TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]); + { + ALU32_BEGIN (GPR[RS]); + ALU32_ADD (GPR[RT]); + if (ALU32_HAD_OVERFLOW) + GPR[RD] = 1; + else + GPR[RD] = 0; + } + TRACE_ALU_RESULT (GPR[RD]); +} + +001000,10.X,11,10001,101,111,111:R6POOL32A0:32::DERET +"deret" +*nanomips32r6: +*nanomips64r6: +{ + // nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + +001000,5.RT,5.X,00000,1,1110010,000:R6PDVP:32::EVP +"evp r" : RT!=0 +"evp" +*nanomips32r6: +*nanomips64r6: +{ + // nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + +001000,10.CODE,110000110,1111111:R6POOL32AXF5GROUP2:32::WAIT +"wait" +*nanomips32r6: +*nanomips64r6: +{ + // nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + +011000,5.RT,00000,16.IMM48:R6POOL48I:32::LI48 +"li r, " +*nanomips32r6: +*nanomips64r6: +{ + uint16_t U2; + uint32_t total; + check_nms_flag (SD_); + U2 = do_load (SD_, AccessLength_HALFWORD, CIA + 4, 0); + total = U2 << 16 | IMM48; + TRACE_ALU_INPUT2(GPR[RT], total); + GPR[RT] = EXTEND32(total); + TRACE_ALU_RESULT(GPR[RT]); + NIA = CIA + 6; +} + +011000,5.RT,00001,16.IMM48:R6POOL48I:32::ADDIU48 +"addiu r, " +*nanomips32r6: +*nanomips64r6: +{ + uint16_t S2; + uint32_t total; + check_nms_flag (SD_); + S2 = do_load(SD_, AccessLength_HALFWORD, CIA + 4, 0); + total = S2 << 16 | IMM48; + do_addiu(SD_, RT, RT, total); + NIA = CIA + 6; +} + +100000,5.RT,5.RS,1000,12.U:R6PU12:32::ADDIUNEG +"addiu r, r, -" +*nanomips32r6: +*nanomips64r6: +{ + do_addiu (SD_, RS, RT, -U); +} + +011000,5.RT,00010,16.IMM48:R6POOL48I:32::ADDIUGP48 +"addiu r, GP, " +*nanomips32r6: +*nanomips64r6: +{ + uint16_t S2; + uint32_t total; + check_nms_flag (SD_); + S2 = do_load(SD_, AccessLength_HALFWORD, CIA + 4, 0); + total = S2 << 16 | IMM48; + do_addiu (SD_, GPIDX, RT, total); + NIA = CIA + 6; +} + +010010,00000,5.RS,1000,12.X:R6BALRSC:32::BRSC +"brsc r" +*nanomips32r6: +*nanomips64r6: +{ + unsigned_word address = NIA + (GPR[RS] << 1); + NIA = address; +} + +010010,5.RT!0,5.RS,1000,12.X:R6PBALRSC:32::BALRSC +"balrsc r, r" +*nanomips32r6: +*nanomips64r6: +{ + unsigned_word address = NIA + (GPR[RS] << 1); + + GPR[RT] = NIA; + NIA = address; + + // For cycle counting + COP0_COUNT++; +} + +110010,5.RT,001,1.X,6.BIT,10.S1,1.S2:R6PBRI:32::BBEQZC +"bbeqzc r, , " +*nanomips32r6: +*nanomips64r6: +{ + int testbit = (GPR[RT] >> BIT) & 1; + + check_nms_flag (SD_); + + if (testbit == 0) + NIA = ADDRESS12; +} + +110010,5.RT,101,1.X,6.BIT,10.S1,1.S2:R6PBRI:32::BBNEZC +"bbnezc r, , " +*nanomips32r6: +*nanomips64r6: +{ + int testbit = (GPR[RT] >> BIT) & 1; + + check_nms_flag (SD_); + + if (testbit == 1) + NIA = ADDRESS12; +} + +////////////////////////////////////////////////////////////////////// +// Not yet in the specification. +////////////////////////////////////////////////////////////////////// + +100001,5.FT,5.RS,1111,12.U:R6PLSU12:32::SDC1 +"sdc1 f, (r)" +*nanomips32r6: +*nanomips64r6: +{ + check_fpu (SD_); + TRACE_ALU_INPUT3(FGR[FT], U, GPR[RS]); + do_store (SD_, AccessLength_DOUBLEWORD, GPR[RS], EXTEND16 (U), COP_SD (1, FT)); +} + +100001,5.FT,5.RS,1110,12.OFFSET:R6PLSU12:32::LDC1 +"ldc1 f, (r)" +*nanomips32r6: +*nanomips64r6: +{ + check_fpu (SD_); + TRACE_ALU_INPUT3(FGR[FT], OFFSET, GPR[RS]); + COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[RS], EXTEND16 (OFFSET))); + TRACE_ALU_RESULT(FGR[FT]); +} + +100001,5.FT,5.BASE,1010,12.OFFSET:R6PLSU12:32::LWC1 +"lwc1 f, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_lwc1 (SD_, FT, OFFSET, BASE); +} + +100001,5.FT,5.BASE,1011,12.OFFSET:R6PLSU12:32::SWC1 +"swc1 f, (fp)": BASE == 30 +"swc1 f, (r)" +*nanomips32r6: +*nanomips64r6: +{ + if(BASE == 30) + do_swc1 (SD_, FT, OFFSET, 30, instruction_0); + else + do_swc1 (SD_, FT, OFFSET, BASE, instruction_0); +} + +001000,10.X,00,01001,101,111,111:R6POOL32AXF5GROUP0:32::TLBR +"tlbr" +*nanomips32r6: +*nanomips64r6: +{ + // nothing to do currently + sim_io_printf (SD, "Not implemented"); +} + +101000,5.RT,5.FS,2.X,101000,00,111,011:R6POOL32FXF0:32,f::MTC1 +"mtc1 r, f" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], FGR[FS]); + do_mtc1b (SD_, RT, FS); + TRACE_ALU_RESULT(FGR[FS]); +} + +101000,5.RT,5.FS,2.X,111000,00,111,011:R6POOL32FXF0:32,f::MTHC1 +"mthc1 r, f" +*nanomips32r6: +*nanomips64r6: +{ +TRACE_ALU_INPUT2(GPR[RT],FGR[FS]); + do_mthc1 (SD_, RT, FS); + TRACE_ALU_RESULT(FGR[FS]); +} + +101000,5.FT,5.FS,5.FD,1.X,0,1.FMT_MICROMIPS,00110,000:R6POOLADDFMT1:32,f::ADD.fmt1 +"add.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(FGR[FT], FGR[FS]); + do_add_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FS, FT, + instruction_0); + TRACE_ALU_RESULT(FGR[FD]); +} + +101000,5.FT,5.FS,5.FD,5.R6COND,0,1.FMT,0101:R6POOL32F5:32,f::CMP.cond.fmt +"cmp.%s.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_cmp (SD_, FD, FS, FT, FMT, R6COND); +} + +101000,5.FT,5.FS,1.X,0,1.FMT_MICROMIPS,00000,01,111,011:R6POOLMOVFMT:32,f::MOV.fmt +"mov.%s f, f" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(FGR[FT], FGR[FS]); + do_mov_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FT, FS, + instruction_0); + TRACE_ALU_RESULT(FGR[FT]); +} + +010001,5.FT,110,16.U,00:R6PLSGPCP1:32::LWC1GP +"lwc1 f, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + do_lwc1 (SD_, FT, U_SHIFT_2BIT, GPIDX); +} + +010001,5.FT,110,16.U,01:R6PLSGPCP1:32::SWC1GP +"swc1 f, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + do_swc1 (SD_, FT, U_SHIFT_2BIT, GPIDX, instruction_0); +} + +101001,5.FT,5.RS,1.S1,1011000,8.S2:R6PLSGPCP1:32::SWC1S9 +"swc1 f, (r)" +*nanomips32r6: +*nanomips64r6: +{ + do_swc1 (SD_, FT, S_9_BIT, RS, instruction_0); +} + +010001,5.FT,110,16.U,10:R6PLSGPCP1:32::LDC1GP +"ldc1 f, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(FGR[FT], U_SHIFT_2BIT, GP); + COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GP, U_SHIFT_2BIT)); + TRACE_ALU_RESULT(FGR[FT]); +} + +100010,5.FT,00001,01,13.S2,1.S1:R6POOLPBR3A:32,f::BC1NEZC +"bc1nezc f, " +*nanomips32r6: +*nanomips64r6: +{ + check_fpu (SD_); + TRACE_ALU_INPUT2(NIA, S_14_BIT); + if ((FGR[FT] & 0x01) != 0) + NIA = NIA + (S_14_BIT << 1); + TRACE_ALU_RESULT(NIA); +} + +100010,5.FT,00000,01,13.S2,1.S1:R6POOLPBR3A:32,f::BC1EQZC +"bc1eqzc f, " +*nanomips32r6: +*nanomips64r6: +{ + check_fpu (SD_); + TRACE_ALU_INPUT2(NIA, S_14_BIT); + if ((FGR[FT] & 0x01) == 0) + NIA = NIA + (S_14_BIT << 1); + TRACE_ALU_RESULT(NIA); +} + +101000,5.RT,5.FS,2.X,100000,00,111,011:R6POOL32FXF0:32,f::MFC1 +"mfc1 r, f" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], FGR[FS]); + do_mfc1b (SD_, RT, FS); + TRACE_ALU_RESULT(GPR[RT]); +} + +101000,5.RT,5.FS,2.X,110000,00,111,011:R6POOL32FXF0:32,f::MFHC1 +"mfhc1 r, f" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(GPR[RT], FGR[FS]); + do_mfhc1 (SD_, RT, FS); + TRACE_ALU_RESULT(GPR[RT]); +} + +101000,5.FT,5.FS,1.X,2.FMT_MICROMIPS_CVT_D!3,10011,01,111,011:R6CVTDFMT:32,f::CVT.D.fmt +"cvt.d.%s f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_cvt_d_fmt (SD_, convert_fmt_micromips_cvt_d (SD_, FMT_MICROMIPS_CVT_D), + FT, FS, instruction_0); +} + +:%s::::FMT_MICROMIPS_MUL:int fmt +{ + switch (fmt) + { + case 1: return "s"; + case 3: return "d"; + default: return "?"; + } +} + +101000,5.FT,5.FS,5.FD,1.X,0,2.FMT_MICROMIPS_MUL!2!0,0110,000:R6MULFMT1:32,f::MUL.fmt +"mul.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(FGR[FS], FGR[FT]); + do_mul_fmt (SD_, convert_fmt_micromips_mul (SD_, FMT_MICROMIPS_MUL), FD, FS, FT, + instruction_0); + TRACE_ALU_RESULT(FGR[FD]); +} + + +101000,5.FT,5.FS,5.FD,1.X,0,2.FMT_MICROMIPS_MUL!2!0,1110,000:R6DIVFMT1:32,f::DIV.fmt +"div.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(FGR[FS], FGR[FT]); + if (FMT_MICROMIPS_MUL == 1) + do_div_fmt (SD_, 0, FD, FS, FT, instruction_0); + else + do_div_fmt (SD_, 1, FD, FS, FT, instruction_0); + TRACE_ALU_RESULT(FGR[FD]); +} + +101000,5.FT,5.FS,1.X,1.FMT_MICROMIPS,101011,00,111,011:R6POOL32FXF0:32,f::TRUNC.W.fmt +"trunc.w.%s f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_trunc_fmt (SD_, fmt_word, FMT_MICROMIPS, FT, FS); +} + +101000,5.FT,5.FS,1.X,2.FMT_MICROMIPS_CVT_S!3,11011,01,111,011:R6CVTSFMT:32,f::CVT.S.dsw +"cvt.s.%s f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_cvt_s_fmt (SD_, convert_fmt_micromips_cvt_s (SD_, FMT_MICROMIPS_CVT_S), + FT, FS, instruction_0); +} + +010001,5.FT,110,16.U,11:R6PLSU12:32::SDC1GP +"sdc1 f, (GP)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(FGR[FT], U_SHIFT_2BIT, GP); + do_store (SD_, AccessLength_DOUBLEWORD, GP, U_SHIFT_2BIT, COP_SD (1, FT)); +} + +101000,5.FT,5.FS,5.FD,1.X,0,1.FMT_MICROMIPS,01110,000:R6SUBFMT1:32,f::SUB.fmt +"sub.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(FGR[FS], FGR[FT]); + do_sub_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FS, FT, + instruction_0); + TRACE_ALU_RESULT(FGR[FD]); +} + +101000,5.FT,5.FS,1.X,2.FMT_MICROMIPS!3!2,00011,01,111,011:R6POOL32FXF1:32,f::::ABS.fmt +"abs.%s f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_abs_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FT, FS, + instruction_0); +} + +101000,5.FT,5.FS,5.FD,1.X,1.FMT_MICROMIPS,110111,000:R6POOL32F0:32,f::MADDF.fmt +"maddf.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT2(FGR[FS], FGR[FT]); + do_maddf (SD_, FD, FS, FT, convert_fmt_micromips (SD_, FMT_MICROMIPS), instruction_0); + TRACE_ALU_RESULT(FGR[FD]); +} + +101000,5.FT,5.FS,1.X,2.FMT_MICROMIPS!3!2,01011,01,111,011:R6POOL32FXF1:32,f::NEG.fmt +"neg.%s f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_neg_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FT, FS, + instruction_0); +} + +101000,5.FT,5.FS,1.X,1.FMT_MICROMIPS,100011,00,111,011:R6POOL32FXF0:32,f::TRUNC.L.fmt +"trunc.l.%s f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_trunc_fmt (SD_, fmt_long, FMT_MICROMIPS, FT, FS); +} + +001000,5.RT,5.RS,5.FT,1011,1,000,111:R6POOLPPLSXS:32,f::SWC1XS +"swc1xs f, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_swc1xs(SD_, FT, RS, RT, instruction_0); +} + +001000,5.RT,5.RS,5.FT,1111,0,000,111:R6POOLPPLSX:32,f::SDC1X +"sdc1x f, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + check_fpu (SD_); + TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]); + do_store (SD_, AccessLength_DOUBLEWORD, GPR[RS], GPR[RT], COP_SD (1, FT)); +} + +001000,5.RT,5.RS,5.FT,1111,1,000,111:R6POOLPPLSXS:32,f::SDC1XS +"sdc1xs f, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + check_fpu (SD_); + TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]); + do_store (SD_, AccessLength_DOUBLEWORD, GPR[RS] << 3, GPR[RT], COP_SD (1, FT)); +} + +001000,5.RT,5.RS,5.FT,1110,0,000,111:R6POOLPPLSXS:32::LDC1X +"ldc1x f, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]); + COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[RS], GPR[RT])); + TRACE_ALU_RESULT(FGR[FT]); +} + +001000,5.RT,5.RS,5.FT,1110,1,000,111:R6POOLPPLSXS:32::LDC1XS +"ldc1xs f, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]); + COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[RS] << 3, GPR[RT])); + TRACE_ALU_RESULT(FGR[FT]); +} + +001000,5.RT,5.RS,5.FT,1010,1,000,111:R6POOLPPLSXS:32::LWC1XS +"lwc1xs f, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]); + do_lwc1xs (SD_, FT, RS, RT); + TRACE_ALU_RESULT(FGR[FT]); +} + +001000,5.RT,5.RS,5.FT,1010,0,000,111:R6PPLSX:32,f::LWC1X +"lwc1x f, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]); + do_lwxc1 (SD_, FT, RT, RS, instruction_0); + TRACE_ALU_RESULT(FGR[FT]); +} + +001000,5.RT,5.RS,5.FT,1011,0,000,111:R6PPLSX:32,f::SWC1X +"swc1x f, r(r)" +*nanomips32r6: +*nanomips64r6: +{ + do_swxc1 (SD_, FT, RT, RS, instruction_0); +} + +101001,5.FT,5.RS,1.S1,1110,0,00,8.S2:R6PLSS0:32,f::LDC1S9 +"ldc1 r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(GPR[FT], S_9_BIT, GPR[RS]); + COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[RS], S_9_BIT)); + TRACE_ALU_RESULT(GPR[FT]); +} + +101001,5.FT,5.RS,1.S1,1111,0,00,8.S2:R6PLSS0:32,f::SDC1S9 +"sdc1 r, (r)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(GPR[FT], S_9_BIT, GPR[RS]); + do_store (SD_, AccessLength_DOUBLEWORD, GPR[RS], S_9_BIT, COP_SD (1, FT)); +} + +101001,5.FT,5.RS,1.S1,1010,0,00,8.S2:R6PLSS0:32::LWC1S9 +"lwc1 f, (r)" +*nanomips32r6: +*nanomips64r6: +{ + TRACE_ALU_INPUT3(GPR[FT], S_9_BIT, GPR[RS]); + do_lwc1 (SD_, FT, S_9_BIT, RS); + TRACE_ALU_RESULT(GPR[FT]); +} + +101000,5.FT,5.FS,5.FD,2.FMT,000000011:R6POOL32F3:32,f::MIN.fmt +"min.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_min (SD_, FD, FS, FT, FMT, instruction_0); +} + +101000,5.FT,5.FS,5.FD,2.FMT,000001,011:R6POOL32F3:32,f::MAX.fmt +"max.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_max (SD_, FD, FS, FT, FMT, instruction_0); +} + +101000,5.FT,5.FS,5.FD,2.FMT,000100,011:R6POOL32F3:32,f::MINA.fmt +"mina.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_mina (SD_, FD, FS, FT, FMT, instruction_0); +} + +101000,5.FT,5.FS,5.FD,2.FMT,000101,011:R6POOL32F3:32,f::MAXA.fmt +"maxa.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_maxa (SD_, FD, FS, FT, FMT, instruction_0); +} + +101000,5.FT,5.FS,5.FD,2.FMT,111111,000:R6POOL32F0:32,f::MSUBF.fmt +"msubf.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_msubf (SD_, FD, FS, FT, FMT, instruction_0); +} + +101000,5.FS,5.FD,00000,2.FMT,000100,000:R6POOL32F0:32,f::RINT.fmt +"rint.%s f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_rint (SD_, FD, FS, FMT, instruction_0); +} + +101000,5.FS,5.FD,00000,2.FMT,001100,000:R6POOL32F0:32,f::CLASS.fmt +"class.%s f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_class (SD_, FD, FS, FMT, instruction_0); +} + +101000,5.FT,5.FS,5.FD,2.FMT,010111,000:R6POOL32F0:32,f::SEL.fmt +"sel.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_self (SD_, FD, FS, FT, FMT, instruction_0); +} + +101000,5.FT,5.FS,5.FD,2.FMT,000111,000:R6POOL32F0:32,f::SELEQZ.fmt +"seleqz.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_seleqzf (SD_, FD, FS, FT, FMT, instruction_0); +} + +101000,5.FT,5.FS,5.FD,2.FMT,001111,000:R6POOL32F0:32,f::SELNEZ.fmt +"selnez.%s f, f, f" +*nanomips32r6: +*nanomips64r6: +{ + do_selnezf (SD_, FD, FS, FT, FMT, instruction_0); +} + +:function:::void:do_lb:int rt, int offset, int base +*nanomips32r6: +*nanomips64r6: +{ + GPR[rt] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[base], offset)); +} + +:function:::void:do_lh:int rt, int offset, int base +*nanomips32r6: +*nanomips64r6: +{ + GPR[rt] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base], offset)); +} + +:function:::void:do_lw:int rt, int offset, int base +*nanomips32r6: +*nanomips64r6: +{ + GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base], offset)); +} + +:function:::void:do_lhu:int rt, int offset, int base +*nanomips32r6: +*nanomips64r6: +{ + GPR[rt] = do_load (SD_, AccessLength_HALFWORD, GPR[base], offset); +} + +:function:::void:do_addiu:int rs, int rt, int immediate +*nanomips32r6: +*nanomips64r6: +{ + if (NotWordValue (GPR[rs])) + Unpredictable (); + TRACE_ALU_INPUT2 (GPR[rs], immediate); + GPR[rt] = EXTEND32 (GPR[rs] + immediate); + TRACE_ALU_RESULT (GPR[rt]); +} diff --git a/sim/mips/nanomipsrun.c b/sim/mips/nanomipsrun.c new file mode 100644 index 00000000000..6321fd441ec --- /dev/null +++ b/sim/mips/nanomipsrun.c @@ -0,0 +1,109 @@ +/* Run function for the nanomips simulator + + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + Written by Andrew Bennett . + + This file is part of GDB, the GNU debugger. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "sim-main.h" +#include "nanomips16_idecode.h" +#include "nanomips32_idecode.h" +#include "bfd.h" + + +#define SD sd +#define CPU cpu +#define SIM_MONITOR_ADDRESS 0xBFC00000 + +void +sim_engine_run (SIM_DESC sd, int next_cpu_nr, int nr_cpus, int signal); + +address_word +nanomips_instruction_decode (SIM_DESC sd, sim_cpu * cpu, + address_word cia, + int instruction_size); + +address_word +nanomips_instruction_decode (SIM_DESC sd, sim_cpu * cpu, + address_word cia, + int instruction_size) +{ + + nanomips16_instruction_word instruction_0 = IMEM16_NANOMIPS (cia); + + if((cia & 0xFFF00000) == SIM_MONITOR_ADDRESS) { + nanomips32_instruction_word instruction_0 = IMEM32 (cia); + return nanomips32_idecode_issue (sd, instruction_0, cia); + } else if ((STATE_ARCHITECTURE (sd)->mach == bfd_mach_nanomipsisa32r6 + || STATE_ARCHITECTURE (sd)->mach == bfd_mach_nanomipsisa64r6) + && (NANOMIPS_MAJOR_OPCODE_3_5 (instruction_0) & 0x4) == 4) + return nanomips16_idecode_issue (sd, instruction_0, cia); + else + { + nanomips32_instruction_word instruction_0 = IMEM32_NANOMIPS (cia); + return nanomips32_idecode_issue (sd, instruction_0, cia); + } +} + +void +sim_engine_run (SIM_DESC sd, int next_cpu_nr, int nr_cpus, + int signal) +{ + nanomips32_instruction_word instruction_0; + sim_cpu *cpu = STATE_CPU (sd, next_cpu_nr); + nanomips32_instruction_address cia = CIA_GET (cpu); + unsigned long bfdmach; + is_nanomips = 1; + + bfdmach = STATE_ARCHITECTURE(SD)->mach; + + if (is_nms_flag_set == 0 && (bfdmach == bfd_mach_nanomipsisa64r6 + || bfdmach == bfd_mach_nanomipsisa32r6)) + set_nms_flag (sd); + + while (1) + { + nanomips32_instruction_address nia; + + cia = cia & ~0x1; + +#if defined (ENGINE_ISSUE_PREFIX_HOOK) + ENGINE_ISSUE_PREFIX_HOOK (); +#endif + + nia = + nanomips_instruction_decode (sd, cpu, cia, + MICROMIPS_DELAYSLOT_SIZE_ANY); + +#if defined (ENGINE_ISSUE_POSTFIX_HOOK) + ENGINE_ISSUE_POSTFIX_HOOK (); +#endif + // Cycle counting + COP0_COUNT++; + + /* Update the instruction address */ + cia = nia; + + /* process any events */ + if (sim_events_tick (sd)) + { + CIA_SET (CPU, cia); + sim_events_process (sd); + cia = CIA_GET (CPU); + } + } +} diff --git a/sim/mips/nms.c b/sim/mips/nms.c new file mode 100644 index 00000000000..fd957d69e8b --- /dev/null +++ b/sim/mips/nms.c @@ -0,0 +1,44 @@ +/* Run function for the nanomips simulator + + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + Written by Andrew Bennett . + + This file is part of GDB, the GNU debugger. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "sim-main.h" +#include "elf/mips-common.h" +#include "elf/nanomips.h" + +/* NMS Flag */ +int nms_flag = -1; + +int is_nms_flag_set = 0; + +void +set_nms_flag (SIM_DESC sd) +{ + Elf_Internal_ABIFlags_v0 *abiflags; + abiflags = bfd_nanomips_elf_get_abiflags (STATE_PROG_BFD(sd)); + + nms_flag = 0; + + if (abiflags != NULL + && ((abiflags->ases & NANOMIPS_ASE_xNMS) != 0)) + nms_flag = 1; + + is_nms_flag_set = 1; +} diff --git a/sim/mips/sim-main.c b/sim/mips/sim-main.c index 250310eceb3..183082ab7c7 100644 --- a/sim/mips/sim-main.c +++ b/sim/mips/sim-main.c @@ -32,6 +32,81 @@ /*---------------------------------------------------------------------------*/ +/* Description from page A-22 of the "MIPS IV Instruction Set" manual + (revision 3.1) */ +/* Translate a virtual address to a physical address and cache + coherence algorithm describing the mechanism used to resolve the + memory reference. Given the virtual address vAddr, and whether the + reference is to Instructions ot Data (IorD), find the corresponding + physical address (pAddr) and the cache coherence algorithm (CCA) + used to resolve the reference. If the virtual address is in one of + the unmapped address spaces the physical address and the CCA are + determined directly by the virtual address. If the virtual address + is in one of the mapped address spaces then the TLB is used to + determine the physical address and access type; if the required + translation is not present in the TLB or the desired access is not + permitted the function fails and an exception is taken. + + NOTE: Normally (RAW == 0), when address translation fails, this + function raises an exception and does not return. */ + +INLINE_SIM_MAIN +(int) +address_translation (SIM_DESC sd, + sim_cpu * cpu, + address_word cia, + address_word vAddr, + int IorD, + int LorS, + address_word * pAddr, + int *CCA, + int raw) +{ + int res = -1; /* TRUE : Assume good return */ + +#ifdef DEBUG + sim_io_printf (sd, "AddressTranslation(0x%s,%s,%s,...);\n", pr_addr (vAddr), (IorD ? "isDATA" : "isINSTRUCTION"), (LorS ? "iSTORE" : "isLOAD")); +#endif + + /* Check that the address is valid for this memory model */ + + /* For a simple (flat) memory model, we simply pass virtual + addressess through (mostly) unchanged. */ + vAddr &= 0xFFFFFFFF; + + *pAddr = vAddr; /* default for isTARGET */ + *CCA = Uncached; /* not used for isHOST */ + + return (res); +} + + + +/* Description from page A-23 of the "MIPS IV Instruction Set" manual + (revision 3.1) */ +/* Prefetch data from memory. Prefetch is an advisory instruction for + which an implementation specific action is taken. The action taken + may increase performance, but must not change the meaning of the + program, or alter architecturally-visible state. */ + +INLINE_SIM_MAIN (void) +prefetch (SIM_DESC sd, + sim_cpu *cpu, + address_word cia, + int CCA, + address_word pAddr, + address_word vAddr, + int DATA, + int hint) +{ +#ifdef DEBUG + sim_io_printf(sd,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA,pr_addr(pAddr),pr_addr(vAddr),DATA,hint); +#endif /* DEBUG */ + + /* For our simple memory model we do nothing */ + return; +} + /* Description from page A-22 of the "MIPS IV Instruction Set" manual (revision 3.1) */ /* Load a value from memory. Use the cache and main memory as @@ -266,13 +341,15 @@ ifetch32 (SIM_DESC SD, address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0); address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0); unsigned int byte; - address_word paddr = vaddr; + address_word paddr; + int uncached; uint64_t memval; if ((vaddr & access) != 0) SignalExceptionInstructionFetch (); + AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL); paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); - LoadMemory (&memval, NULL, access, paddr, vaddr, isINSTRUCTION, isREAL); + LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isINSTRUCTION, isREAL); byte = ((vaddr & mask) ^ bigendiancpu); return (memval >> (8 * byte)); } @@ -290,13 +367,15 @@ ifetch16 (SIM_DESC SD, address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0); address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0); unsigned int byte; - address_word paddr = vaddr; + address_word paddr; + int uncached; uint64_t memval; if ((vaddr & access) != 0) SignalExceptionInstructionFetch (); + AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL); paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); - LoadMemory (&memval, NULL, access, paddr, vaddr, isINSTRUCTION, isREAL); + LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isINSTRUCTION, isREAL); byte = ((vaddr & mask) ^ bigendiancpu); return (memval >> (8 * byte)); } diff --git a/sim/mips/sim-main.h b/sim/mips/sim-main.h index 418c6599118..1397202c787 100644 --- a/sim/mips/sim-main.h +++ b/sim/mips/sim-main.h @@ -262,6 +262,8 @@ struct _sim_cpu { /* The following are internal simulator state variables: */ +#define CIA_GET(CPU) ((CPU)->registers[PCIDX] + 0) +#define CIA_SET(CPU,CIA) ((CPU)->registers[PCIDX] = (CIA)) address_word dspc; /* delay-slot PC */ #define DSPC ((CPU)->dspc) @@ -318,9 +320,9 @@ struct _sim_cpu { #define LAST_EMBED_REGNUM (96) #define NUM_REGS (LAST_EMBED_REGNUM + 1) -#define FP0_REGNUM 38 /* Floating point register 0 (single float) */ -#define FCRCS_REGNUM 70 /* FP control/status */ -#define FCRIR_REGNUM 71 /* FP implementation/revision */ +#define FP0_REGNUM 36 /* Floating point register 0 (single float) */ +#define FCRCS_REGNUM 68 /* FP control/status */ +#define FCRIR_REGNUM 69 /* FP implementation/revision */ #endif @@ -336,16 +338,16 @@ struct _sim_cpu { #define GPR (®ISTERS[0]) #define GPR_SET(N,VAL) (REGISTERS[(N)] = (VAL)) -#define LO (REGISTERS[33]) -#define HI (REGISTERS[34]) -#define PCIDX 37 +#define HI (REGISTERS[70]) +#define LO (REGISTERS[71]) +#define PCIDX (is_nanomips?32:35) #define PC (REGISTERS[PCIDX]) -#define CAUSE (REGISTERS[36]) +#define CAUSE (REGISTERS[34]) #define SRIDX (32) #define SR (REGISTERS[SRIDX]) /* CPU status register */ -#define FCR0IDX (71) +#define FCR0IDX (69) #define FCR0 (REGISTERS[FCR0IDX]) /* really a 32bit register */ -#define FCR31IDX (70) +#define FCR31IDX (68) #define FCR31 (REGISTERS[FCR31IDX]) /* really a 32bit register */ #define FCSR (FCR31) #define Debug (REGISTERS[86]) @@ -353,19 +355,19 @@ struct _sim_cpu { #define EPC (REGISTERS[88]) #define ACX (REGISTERS[89]) -#define AC0LOIDX (33) /* Must be the same register as LO */ -#define AC0HIIDX (34) /* Must be the same register as HI */ -#define AC1LOIDX (90) -#define AC1HIIDX (91) -#define AC2LOIDX (92) -#define AC2HIIDX (93) -#define AC3LOIDX (94) -#define AC3HIIDX (95) +#define AC0HIIDX (70) /* Must be the same register as HI */ +#define AC0LOIDX (71) /* Must be the same register as LO */ +#define AC1HIIDX (72) +#define AC1LOIDX (73) +#define AC2HIIDX (74) +#define AC2LOIDX (75) +#define AC3HIIDX (76) +#define AC3LOIDX (77) #define DSPLO(N) (REGISTERS[DSPLO_REGNUM[N]]) #define DSPHI(N) (REGISTERS[DSPHI_REGNUM[N]]) -#define DSPCRIDX (96) /* DSP control register */ +#define DSPCRIDX (79) /* DSP control register */ #define DSPCR (REGISTERS[DSPCRIDX]) #define DSPCR_POS_SHIFT (0) @@ -420,6 +422,8 @@ struct _sim_cpu { #define A3 (REGISTERS[7]) #define T8IDX 24 #define T8 (REGISTERS[T8IDX]) +#define GPIDX 28 +#define GP (REGISTERS[GPIDX]) #define SPIDX 29 #define SP (REGISTERS[SPIDX]) #define RAIDX 31 @@ -433,6 +437,7 @@ struct _sim_cpu { unsigned_word cop0_gpr[NR_COP0_GPR]; #define COP0_GPR ((CPU)->cop0_gpr) #define COP0_BADVADDR (COP0_GPR[8]) +#define COP0_COUNT (COP0_GPR[9]) /* While space is allocated for the floating point registers in the main registers array, they are stored separatly. This is because @@ -476,6 +481,17 @@ struct _sim_cpu { sim_cpu_base base; }; +extern int is_nanomips; + +#define SET_RV0(VAL) \ + do { \ + if (is_nanomips) \ + A0 = VAL; \ + else \ + V0 = VAL; \ + } while (0) + + extern void mips_sim_close (SIM_DESC sd, int quitting); #define SIM_CLOSE_HOOK(...) mips_sim_close (__VA_ARGS__) @@ -643,13 +659,16 @@ enum ExceptionCause { is used by gdb for break-points. NOTE: Care must be taken, since this value may be used in later revisions of the MIPS ISA. */ #define HALT_INSTRUCTION_MASK (0x03FFFFC0) +#define HALT_INSTRUCTION_MASK_NANOMIPS (0x0007FFFF) #define HALT_INSTRUCTION (0x03ff000d) #define HALT_INSTRUCTION2 (0x0000ffcd) +#define HALT_INSTRUCTION_NANOMIPS (0x001003FF) #define BREAKPOINT_INSTRUCTION (0x0005000d) #define BREAKPOINT_INSTRUCTION2 (0x0000014d) +#define BREAKPOINT_INSTRUCTION_NANOMIPS (0x00101400) @@ -728,6 +747,44 @@ void store_fcr (SIM_STATE, int fcr, unsigned_word value); void test_fcsr (SIM_STATE); #define TestFCSR() test_fcsr (SIM_ARGS) +/* FPU operations. */ +/* Non-signalling */ +#define FP_R6CMP_AF 0x0 +#define FP_R6CMP_EQ 0x2 +#define FP_R6CMP_LE 0x6 +#define FP_R6CMP_LT 0x4 +#define FP_R6CMP_NE 0x13 +#define FP_R6CMP_OR 0x11 +#define FP_R6CMP_UEQ 0x3 +#define FP_R6CMP_ULE 0x7 +#define FP_R6CMP_ULT 0x5 +#define FP_R6CMP_UN 0x1 +#define FP_R6CMP_UNE 0x12 + +/* Signalling */ +#define FP_R6CMP_SAF 0x8 +#define FP_R6CMP_SEQ 0xa +#define FP_R6CMP_SLE 0xe +#define FP_R6CMP_SLT 0xc +#define FP_R6CMP_SNE 0x1b +#define FP_R6CMP_SOR 0x19 +#define FP_R6CMP_SUEQ 0xb +#define FP_R6CMP_SULE 0xf +#define FP_R6CMP_SULT 0xd +#define FP_R6CMP_SUN 0x9 +#define FP_R6CMP_SUNE 0x1a + +/* FPU Class */ +#define FP_R6CLASS_SNAN (1<<0) +#define FP_R6CLASS_QNAN (1<<1) +#define FP_R6CLASS_NEGINF (1<<2) +#define FP_R6CLASS_NEGNORM (1<<3) +#define FP_R6CLASS_NEGSUB (1<<4) +#define FP_R6CLASS_NEGZERO (1<<5) +#define FP_R6CLASS_POSINF (1<<6) +#define FP_R6CLASS_POSNORM (1<<7) +#define FP_R6CLASS_POSSUB (1<<8) +#define FP_R6CLASS_POSZERO (1<<9) /* FPU operations. */ /* Non-signalling */ @@ -812,21 +869,21 @@ uint64_t fp_fmadd (SIM_STATE, uint64_t op1, uint64_t op2, uint64_t op3, FP_formats fmt); #define FusedMultiplySub(op1,op2,op3,fmt) fp_fmsub(SIM_ARGS, op1, op2, op3, fmt) uint64_t fp_fmsub (SIM_STATE, uint64_t op1, uint64_t op2, - uint64_t op3, FP_formats fmt); + uint64_t op3, FP_formats fmt); #define MultiplyAdd(op1,op2,op3,fmt) fp_madd(SIM_ARGS, op1, op2, op3, fmt) uint64_t fp_msub (SIM_STATE, uint64_t op1, uint64_t op2, - uint64_t op3, FP_formats fmt); + uint64_t op3, FP_formats fmt); #define MultiplySub(op1,op2,op3,fmt) fp_msub(SIM_ARGS, op1, op2, op3, fmt) uint64_t fp_nmadd (SIM_STATE, uint64_t op1, uint64_t op2, - uint64_t op3, FP_formats fmt); + uint64_t op3, FP_formats fmt); #define NegMultiplyAdd(op1,op2,op3,fmt) fp_nmadd(SIM_ARGS, op1, op2, op3, fmt) uint64_t fp_nmsub (SIM_STATE, uint64_t op1, uint64_t op2, - uint64_t op3, FP_formats fmt); + uint64_t op3, FP_formats fmt); #define NegMultiplySub(op1,op2,op3,fmt) fp_nmsub(SIM_ARGS, op1, op2, op3, fmt) uint64_t convert (SIM_STATE, int rm, uint64_t op, FP_formats from, FP_formats to); #define Convert(rm,op,from,to) convert (SIM_ARGS, rm, op, from, to) uint64_t convert_ps (SIM_STATE, int rm, uint64_t op, FP_formats from, - FP_formats to); + FP_formats to); #define ConvertPS(rm,op,from,to) convert_ps (SIM_ARGS, rm, op, from, to) @@ -959,6 +1016,12 @@ uint64_t mdmx_shuffle (SIM_STATE, int, uint64_t, uint64_t); /* The following are generic to all versions of the MIPS architecture to date: */ +/* Memory Access Types (for CCA): */ +#define Uncached (0) +#define CachedNoncoherent (1) +#define CachedCoherent (2) +#define Cached (3) + #define isINSTRUCTION (1 == 0) /* FALSE */ #define isDATA (1 == 1) /* TRUE */ #define isLOAD (1 == 0) /* FALSE */ @@ -985,13 +1048,17 @@ uint64_t mdmx_shuffle (SIM_STATE, int, uint64_t, uint64_t); ? AccessLength_DOUBLEWORD /*7*/ \ : AccessLength_WORD /*3*/) +INLINE_SIM_MAIN (int) address_translation (SIM_DESC sd, sim_cpu *, address_word cia, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int raw); +#define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \ +address_translation (SD, CPU, cia, vAddr, IorD, LorS, pAddr, CCA, raw) + INLINE_SIM_MAIN (void) load_memory (SIM_DESC sd, sim_cpu *cpu, address_word cia, uword64* memvalp, uword64* memval1p, int CCA, unsigned int AccessLength, address_word pAddr, address_word vAddr, int IorD); -#define LoadMemory(memvalp,memval1p,AccessLength,pAddr,vAddr,IorD,raw) \ -load_memory (SD, CPU, cia, memvalp, memval1p, 0, AccessLength, pAddr, vAddr, IorD) +#define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \ +load_memory (SD, CPU, cia, memvalp, memval1p, CCA, AccessLength, pAddr, vAddr, IorD) INLINE_SIM_MAIN (void) store_memory (SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, unsigned int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr); -#define StoreMemory(AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \ -store_memory (SD, CPU, cia, 0, AccessLength, MemElem, MemElem1, pAddr, vAddr) +#define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \ +store_memory (SD, CPU, cia, CCA, AccessLength, MemElem, MemElem1, pAddr, vAddr) INLINE_SIM_MAIN (void) cache_op (SIM_DESC sd, sim_cpu *cpu, address_word cia, int op, address_word pAddr, address_word vAddr, unsigned int instruction); #define CacheOp(op,pAddr,vAddr,instruction) \ @@ -1001,6 +1068,10 @@ INLINE_SIM_MAIN (void) sync_operation (SIM_DESC sd, sim_cpu *cpu, address_word c #define SyncOperation(stype) \ sync_operation (SD, CPU, cia, (stype)) +INLINE_SIM_MAIN (void) prefetch (SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, address_word pAddr, address_word vAddr, int DATA, int hint); +#define Prefetch(CCA,pAddr,vAddr,DATA,hint) \ +prefetch (SD, CPU, cia, CCA, pAddr, vAddr, DATA, hint) + void unpredictable_action (sim_cpu *cpu, address_word cia); #define NotWordValue(val) not_word_value (SD_, (val)) #define Unpredictable() unpredictable (SD_) @@ -1022,6 +1093,16 @@ INLINE_SIM_MAIN (uint16_t) ifetch16 (SIM_DESC sd, sim_cpu *cpu, address_word cia #define MICROMIPS_DELAYSLOT_SIZE_16 2 #define MICROMIPS_DELAYSLOT_SIZE_32 4 +#define IMEM32_NANOMIPS(CIA) \ + (ifetch16 (SD, CPU, (CIA), (CIA)) << 16 | ifetch16 (SD, CPU, (CIA + 2), \ + (CIA + 2))) +#define IMEM16_NANOMIPS(CIA) ifetch16 (SD, CPU, (CIA), ((CIA))) + + +#define NANOMIPS_MAJOR_OPCODE_3_5(INSN) ((INSN & 0x1c00) >> 10) + +#define NANOMIPS_DELAYSLOT_SIZE_ANY 0 + extern int isa_mode; #define ISA_MODE_MIPS32 0 @@ -1041,6 +1122,13 @@ extern FILE *tracefh; extern int DSPLO_REGNUM[4]; extern int DSPHI_REGNUM[4]; +/* NMS Flag */ +extern int nms_flag; +extern int is_nms_flag_set; + +void +set_nms_flag (SIM_DESC sd); + INLINE_SIM_MAIN (void) pending_tick (SIM_DESC sd, sim_cpu *cpu, address_word cia); extern SIM_CORE_SIGNAL_FN mips_core_signal; @@ -1055,10 +1143,16 @@ void mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception); void mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception); #ifdef MIPS_MACH_MULTI -extern int mips_mach_multi(SIM_DESC sd); -#define MIPS_MACH(SD) mips_mach_multi(SD) +extern address_word micromips_instruction_decode_multi(SIM_DESC sd, + sim_cpu* cpu, + address_word cia, + int instruction_size); +#define MICROMIPS_INSTRUCTION_DECODE(SD, cpu, cia, size) \ + micromips_instruction_decode_multi (SD, cpu, cia, size); #else -#define MIPS_MACH(SD) MIPS_MACH_DEFAULT +#define MIPS_MACH(SD) MIPS_MACH_DEFAULT +#define MICROMIPS_INSTRUCTION_DECODE(SD, cpu, cia, size) \ + micromips_instruction_decode (SD, cpu, cia, size); #endif /* Macros for determining whether a MIPS IV or MIPS V part is subject -- 2.25.1