From patchwork Sun Sep 26 13:24:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dragan Mladjenovic X-Patchwork-Id: 45447 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6F172385840A for ; Sun, 26 Sep 2021 13:26:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6F172385840A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1632662781; bh=Bq3OAy66LXx8H/6YIlQ5Nv1nW/1b/meziY3p/ih247s=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=ab3vmv+DrkNhWfx6R3KCxh2nhC/jjfqIQnbaCMv2TmDtaJavYHhlvp50q0hsNOwhp B97eayMIW7lThD0+P9eA0TLgbeRomrB3KkYHkpBURW3qWK9MqKX5BUsOeaDq/aI0xR xN6C3YVCYBCp5NjUXSz/DCm4BRtuKkZJccHPSsEg= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mailgw02.mediatek.com (mailgw02.mediatek.com [216.200.240.185]) by sourceware.org (Postfix) with ESMTPS id 8E3963858403; Sun, 26 Sep 2021 13:24:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8E3963858403 X-UUID: 320096a04551470e8b710418c5d46c13-20210926 X-UUID: 320096a04551470e8b710418c5d46c13-20210926 Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 2116990207; Sun, 26 Sep 2021 06:24:45 -0700 Received: from MTKMBS62N1.mediatek.inc (172.29.193.41) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sun, 26 Sep 2021 06:24:44 -0700 Received: from MTKMBS62N1.mediatek.inc ([fe80::697c:586d:7cff:34e7]) by MTKMBS62N1.mediatek.inc ([fe80::697c:586d:7cff:34e7%12]) with mapi id 15.00.1497.015; Sun, 26 Sep 2021 06:24:44 -0700 To: "gcc-patches@gcc.gnu.org" Subject: [RFC 1/7] Avoid references to register names in instruction output patterns. Thread-Topic: [RFC 1/7] Avoid references to register names in instruction output patterns. Thread-Index: AQHXstneSWaf24jQQEW0QL55ADB2cg== Date: Sun, 26 Sep 2021 13:24:44 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [172.29.193.239] MIME-Version: 1.0 X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, HTML_MESSAGE, SPF_HELO_NONE, SPF_PASS, TXREP, UNPARSEABLE_RELAY 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-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Dragan Mladjenovic via Gcc-patches From: Dragan Mladjenovic Reply-To: Dragan Mladjenovic Cc: Jeff Law , Matthew Fortune , Jakub Jelinek , YunQiang Su , "Petar.Jovanovic@syrmia.com" , Faraz Shahbazker , Vince Del Vecchio Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This allows us to choose the different names if needed in the future. gcc/ChangeLog: * config/mips/mips.c (mips_print_operand_punctuation): Handle '&' punctuation. (mips_output_probe_stack_range): Use '%.' instead of $0. * config/mips/mips.h (GLOBAL_POINTER_REGNUM): Move to ... * config/mips/mips.md (GLOBAL_POINTER_REGNUM): ... here. (trap, *conditional_trap_reg, *msac, *muls, *muls_di, msubsidi4): Use '%.' instead of $0. (clear_hazard_): Use '%&' instead of $31. --- gcc/config/mips/mips.c | 9 +++++++-- gcc/config/mips/mips.h | 4 ---- gcc/config/mips/mips.md | 17 +++++++++-------- 3 files changed, 16 insertions(+), 14 deletions(-) 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index ce60c5500b7..ab63575eb26 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -8816,6 +8816,7 @@ mips_pop_asm_switch (struct mips_asm_switch *asm_switch) '^' Print the name of the pic call-through register (t9 or $25). '+' Print the name of the gp register (usually gp or $28). '$' Print the name of the stack pointer register (sp or $29). + '&' Print the name of the return register (ra or $31). ':' Print "c" to use the compact version if the delay slot is a nop. '!' Print "s" to use the short version if the delay slot contains a 16-bit instruction. @@ -8902,6 +8903,10 @@ mips_print_operand_punctuation (FILE *file, int ch) fputs (reg_names[STACK_POINTER_REGNUM], file); break; + case '&': + fputs (reg_names[RETURN_ADDR_REGNUM], file); + break; + case ':': /* When final_sequence is 0, the delay slot will be a nop. We can use the compact version where available. The %: formatter will @@ -12133,9 +12138,9 @@ mips_output_probe_stack_range (rtx reg1, rtx reg2) strcpy (tmp, "%(%" @@ -1860,7 +1861,7 @@ else if (TARGET_MIPS5500) return "msub\t%2,%3"; else - return "msac\t$0,%2,%3"; + return "msac\t%.,%2,%3"; } [(set_attr "type" "imadd") (set_attr "accum_in" "1") @@ -2060,7 +2061,7 @@ (clobber (match_scratch:SI 3 "=X,l"))] "ISA_HAS_MULS" "@ - muls\t$0,%1,%2 + muls\t%.,%1,%2 muls\t%0,%1,%2" [(set_attr "type" "imul,imul3") (set_attr "mode" "SI")]) @@ -2243,7 +2244,7 @@ (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))] "!TARGET_64BIT && ISA_HAS_MULS" - "muls\t$0,%1,%2" + "muls\t%.,%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")]) @@ -2268,7 +2269,7 @@ else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB) return "msub\t%1,%2"; else - return "msac\t$0,%1,%2"; + return "msac\t%.,%1,%2"; } [(set_attr "type" "imadd") (set_attr "accum_in" "3") @@ -5622,8 +5623,8 @@ { return "%(%addiu\t$31,$31,12\n" - "\tjr.hb\t$31\n" + "1:\taddiu\t%&,%&,12\n" + "\tjr.hb\t%&\n" "\tnop%>%)"; } From patchwork Sun Sep 26 13:24:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dragan Mladjenovic X-Patchwork-Id: 45448 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 03AB13858424 for ; Sun, 26 Sep 2021 13:27:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 03AB13858424 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1632662839; bh=5CdX3FeAaymVqbJ4Dzwukiez6FcX75P0dH4Brk0V2B4=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=ng4ZoXad4FEwORYvBtXmuXr61XXN//aOIrNGhvBh++62h1gAAUL+h3bBJsu6LuQCq AqDz3gh1Yt26ybh7H3oyaKpoVJnwVyV9uAXfn3C7BvD/XcmM/wQCLZFUiALz1D1fkU fvTQRxuVjSWhAfYIcPC8y4rv4egCIQ8wcPhggpVU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mailgw02.mediatek.com (mailgw02.mediatek.com [216.200.240.185]) by sourceware.org (Postfix) with ESMTPS id 517E7385802B; Sun, 26 Sep 2021 13:25:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 517E7385802B X-UUID: 92c0d0236e5a4674a1723457af7bac8e-20210926 X-UUID: 92c0d0236e5a4674a1723457af7bac8e-20210926 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 35288155; Sun, 26 Sep 2021 06:24:59 -0700 Received: from MTKMBS62N1.mediatek.inc (172.29.193.41) by MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sun, 26 Sep 2021 06:24:57 -0700 Received: from MTKMBS62N1.mediatek.inc ([fe80::697c:586d:7cff:34e7]) by MTKMBS62N1.mediatek.inc ([fe80::697c:586d:7cff:34e7%12]) with mapi id 15.00.1497.015; Sun, 26 Sep 2021 06:24:57 -0700 To: "gcc-patches@gcc.gnu.org" Subject: [RFC 2/7] Make mips-classic.md entry point for mips*-*-* targets Thread-Topic: [RFC 2/7] Make mips-classic.md entry point for mips*-*-* targets Thread-Index: AQHXstnm0C+1s2vU9k+lwa6PYAMHPg== Date: Sun, 26 Sep 2021 13:24:57 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [172.29.193.239] MIME-Version: 1.0 X-Spam-Status: No, score=-10.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, HTML_MESSAGE, KAM_SHORT, MEDICAL_SUBJECT, SPF_HELO_NONE, SPF_PASS, TXREP, UNPARSEABLE_RELAY 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-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Dragan Mladjenovic via Gcc-patches From: Dragan Mladjenovic Reply-To: Dragan Mladjenovic Cc: Jeff Law , Matthew Fortune , Jakub Jelinek , YunQiang Su , "Petar.Jovanovic@syrmia.com" , Faraz Shahbazker , Vince Del Vecchio Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Make parts of the code and options conditional on compile-time defines. gcc/ChangeLog: * config/mips/mips.h (MIPS_SUPPORT_DSP, MIPS_SUPPORT_PS_3D, MIPS_SUPPORT_MSA, MIPS_SUPPORT_LOONGSON MIPS_SUPPORT_MICROMIPS, MIPS_SUPPORT_LEGACY MIPS_SUPPORT_FRAME_HEADER_OPT): New defines. * config/mips/mips.c (MIPS_BUILTIN_MOVF, MIPS_BUILTIN_MOVT, mips_expand_vcondv2sf, pll_ps, pul_ps, plu_ps, mips_expand_builtin_movtf, mips_expand_builtin_compare): Make conditional on MIPS_SUPPORT_PS_3D. (MIPS_BUILTIN_BPOSGE32, mips_emit_compare, dspalu_bypass_table, CODE_FOR_mips_sqrt_ps, ... CODE_FOR_mips_multu, addq_ph ... dpsqx_sa_w_ph, mips_expand_builtin_bposge): Make conditional on MIPS_SUPPORT_DSP. (mips_split_move_p, mips_split_move, CODE_FOR_msa_adds_s_b ... CODE_FOR_msa_ldi_d, mips_builtin_vectorized_function, mips_expand_builtin_insn, mips_expand_msa_shuffle, mips_msa_vec_parallel_const_half, mips_expand_vector_init, mips_expand_vec_reduc): Make conditional on MIPS_SUPPORT_MSA. (struct mips_ls2, mips_ls2_init_dfa_post_cycle_insn, mips_sched_init, mips_ls2_variable_issue, mips_variable_issue, CODE_FOR_loongson_packsswh ... CODE_FOR_loongson_psubusb, mips_expand_vpc_loongson_even_odd mips_expand_vec_perm_const_1, mips_expand_vi_broadcast, mips_expand_vi_loongson_one_pinsrh, mips_expand_vector_init, TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN, TARGET_SCHED_DFA_POST_ADVANCE_CYCLE): Make conditional on MIPS_SUPPORT_LOONGSON. (vr4130_reorder, mips_sched_init, mips_sched_reorder_1, mips_variable_issue): Make conditional on MIPS_SUPPORT_LEGACY. (mips_expand_epilogue): Make conditional on MIPS_SUPPORT_MICROMIPS. (mips_compute_frame_info, mips_option_override): Make conditional on MIPS_SUPPORT_FRAME_HEADER_OPT. * config/mips/mips.md (processor): (unspec): Move into ... * config/mips/mips-classic.md: ... here. * config.gcc [mips*-*-*]: Use mips-classic.md. * config/mips/mips.opt: Conditionalize options. --- gcc/config.gcc | 1 + gcc/config/mips/mips-classic.md (new) | 142 ++++++++++++++++++++++++ gcc/config/mips/mips.c | 154 ++++++++++++++++++++++---- gcc/config/mips/mips.h | 8 ++ gcc/config/mips/mips.md | 117 ------------------- gcc/config/mips/mips.opt | 122 ++++++++++---------- 6 files changed, 346 insertions(+), 198 deletions(-) 6 files changed, 346 insertions(+), 198 deletions(-) create mode 100644 gcc/config/mips/mips-classic.md diff --git a/gcc/config.gcc b/gcc/config.gcc index 498c51e619d..58e38f70aa6 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -448,6 +448,7 @@ microblaze*-*-*) ;; mips*-*-*) cpu_type=mips + md_file=mips/mips-classic.md d_target_objs="mips-d.o" extra_headers="loongson.h loongson-mmiintrin.h msa.h" extra_objs="frame-header-opt.o" diff --git a/gcc/config/mips/mips-classic.md b/gcc/config/mips/mips-classic.md new file mode 100644 index 00000000000..0f7efc4d5d8 --- /dev/null +++ b/gcc/config/mips/mips-classic.md @@ -0,0 +1,142 @@ +;; Mips.md Machine Description for MIPS based processors +;; Copyright (C) 1989-2021 Free Software Foundation, Inc. +;; Contributed by A. Lichnewsky, lich@inria.inria.fr +;; Changes by Michael Meissner, meissner@osf.org +;; 64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and +;; Brendan Eich, brendan@microunity.com. + +;; This file is part of GCC. + +;; GCC 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, or (at your option) +;; any later version. + +;; GCC 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 GCC; see the file COPYING3. If not see +;; . + +(define_enum "processor" [ + r3000 + 4kc + 4kp + 5kc + 5kf + 20kc + 24kc + 24kf2_1 + 24kf1_1 + 74kc + 74kf2_1 + 74kf1_1 + 74kf3_2 + loongson_2e + loongson_2f + gs464 + gs464e + gs264e + m4k + octeon + octeon2 + octeon3 + r3900 + r6000 + r4000 + r4100 + r4111 + r4120 + r4130 + r4300 + r4600 + r4650 + r4700 + r5000 + r5400 + r5500 + r5900 + r7000 + r8000 + r9000 + r10000 + sb1 + sb1a + sr71000 + xlr + xlp + p5600 + m5100 + i6400 + p6600 +]) + +(include "mips.md") + +(include "i6400.md") +(include "p5600.md") +(include "m5100.md") +(include "p6600.md") +(include "4k.md") +(include "5k.md") +(include "20kc.md") +(include "24k.md") +(include "74k.md") +(include "3000.md") +(include "4000.md") +(include "4100.md") +(include "4130.md") +(include "4300.md") +(include "4600.md") +(include "5000.md") +(include "5400.md") +(include "5500.md") +(include "6000.md") +(include "7000.md") +(include "9000.md") +(include "10000.md") +(include "loongson2ef.md") +(include "gs464.md") +(include "gs464e.md") +(include "gs264e.md") +(include "octeon.md") +(include "sb1.md") +(include "sr71k.md") +(include "xlr.md") +(include "xlp.md") +(include "generic.md") + +;; Synchronization instructions. + +(include "sync.md") + +; The MIPS Paired-Single Floating Point and MIPS-3D Instructions. + +(include "mips-ps-3d.md") + +; The MIPS DSP Instructions. + +(include "mips-dsp.md") + +; The MIPS DSP REV 2 Instructions. + +(include "mips-dspr2.md") + +; MIPS fixed-point instructions. +(include "mips-fixed.md") + +; microMIPS patterns. +(include "micromips.md") + +; Loongson MultiMedia extensions Instructions (MMI) patterns. +(include "loongson-mmi.md") + +; The MIPS MSA Instructions. +(include "mips-msa.md") + +(define_c_enum "unspec" [ + UNSPEC_ADDRESS_FIRST +]) diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index ab63575eb26..8f125a4ddec 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -234,12 +234,14 @@ enum mips_builtin_type { value and the arguments are mapped to operands 0 and above. */ MIPS_BUILTIN_DIRECT_NO_TARGET, +#ifdef MIPS_SUPPORT_PS_3D /* The function corresponds to a comparison instruction followed by a mips_cond_move_tf_ps pattern. The first two arguments are the values to compare and the second two arguments are the vector operands for the movt.ps or movf.ps instruction (in assembly order). */ MIPS_BUILTIN_MOVF, MIPS_BUILTIN_MOVT, +#endif /* The function corresponds to a V2SF comparison instruction. Operand 0 of this instruction is the result of the comparison, which has mode @@ -263,8 +265,10 @@ enum mips_builtin_type { combined with a compare instruction. */ MIPS_BUILTIN_MSA_TEST_BRANCH, +#ifdef MIPS_SUPPORT_DSP /* For generating bposge32 branch instructions in MIPS32 DSP ASE. */ MIPS_BUILTIN_BPOSGE32 +#endif }; /* Invoke MACRO (COND) for each C.cond.fmt condition. */ @@ -4797,9 +4801,11 @@ mips_split_move_p (rtx dest, rtx src, enum mips_split_type split_type) return false; } +#ifdef MIPS_SUPPORT_MSA /* Check if MSA moves need splitting. */ if (MSA_SUPPORTED_MODE_P (GET_MODE (dest))) return mips_split_128bit_move_p (dest, src); +#endif /* Otherwise split all multiword moves. */ return size > UNITS_PER_WORD; @@ -4815,9 +4821,13 @@ mips_split_move (rtx dest, rtx src, enum mips_split_type split_type, rtx insn_) rtx low_dest; gcc_checking_assert (mips_split_move_p (dest, src, split_type)); +#ifdef MIPS_SUPPORT_MSA if (MSA_SUPPORTED_MODE_P (GET_MODE (dest))) mips_split_128bit_move (dest, src); else if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src)) +#else + if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src)) +#endif { if (!TARGET_64BIT && GET_MODE (dest) == DImode) emit_insn (gen_move_doubleword_fprdi (dest, src)); @@ -4916,6 +4926,7 @@ mips_insn_split_type (rtx insn) return SPLIT_IF_NECESSARY; } +#ifdef MIPS_SUPPORT_MSA /* Return true if a 128-bit move from SRC to DEST should be split. */ bool @@ -5108,6 +5119,7 @@ mips_split_msa_fill_d (rtx dest, rtx src) emit_insn (gen_msa_insert_w (new_dest, high, new_dest, GEN_INT (1 << 1))); emit_insn (gen_msa_insert_w (new_dest, high, new_dest, GEN_INT (1 << 3))); } +#endif /* Return true if a move from SRC to DEST in INSN should be split. */ @@ -5639,6 +5651,7 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p) *op1 = const0_rtx; } } +#ifdef MIPS_SUPPORT_DSP else if (ALL_FIXED_POINT_MODE_P (GET_MODE (cmp_op0))) { *op0 = gen_rtx_REG (CCDSPmode, CCDSP_CC_REGNUM); @@ -5646,6 +5659,7 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p) *code = NE; *op1 = const0_rtx; } +#endif else { enum rtx_code cmp_code; @@ -5728,6 +5742,7 @@ mips_expand_conditional_branch (rtx *operands) emit_jump_insn (gen_condjump (condition, operands[3])); } +#ifdef MIPS_SUPPORT_PS_3D /* Implement: (set temp (COND:CCV2 CMP_OP0 CMP_OP1)) @@ -5751,6 +5766,7 @@ mips_expand_vcondv2sf (rtx dest, rtx true_src, rtx false_src, emit_insn (gen_mips_cond_move_tf_ps (dest, true_src, false_src, cmp_result)); } +#endif /* Perform the comparison in OPERANDS[1]. Move OPERANDS[2] into OPERANDS[0] if the condition holds, otherwise move OPERANDS[3] into OPERANDS[0]. */ @@ -9589,6 +9605,7 @@ mips_dwarf_frame_reg_mode (int regno) return mode; } +#ifdef MIPS_SUPPORT_DSP /* DSP ALU can bypass data with no delays for the following pairs. */ enum insn_code dspalu_bypass_table[][2] = { @@ -9619,6 +9636,8 @@ mips_dspalu_bypass_p (rtx out_insn, rtx in_insn) return false; } +#endif + /* Implement ASM_OUTPUT_ASCII. */ void @@ -11203,6 +11222,7 @@ mips_compute_frame_info (void) frame->cop0_sp_offset = offset - UNITS_PER_WORD; } +#ifdef MIPS_SUPPORT_FRAME_HEADER_OPT /* Determine if we can save the callee-saved registers in the frame header. Restrict this to functions where there is no other reason to allocate stack space so that we can eliminate the instructions @@ -11231,6 +11251,7 @@ mips_compute_frame_info (void) frame->gp_sp_offset = REG_PARM_STACK_SPACE(cfun) - UNITS_PER_WORD; cfun->machine->use_frame_header_for_callee_saved_regs = true; } +#endif /* Move above the callee-allocated varargs save area. */ offset += MIPS_STACK_ALIGN (cfun->machine->varargs_size); @@ -12783,8 +12804,10 @@ mips_expand_epilogue (bool sibcall_p) rtx reg = gen_rtx_REG (Pmode, GP_REG_FIRST + 7); pat = gen_return_internal (reg); } +#ifdef MIPS_SUPPORT_MICROMIPS else if (use_jraddiusp_p) pat = gen_jraddiusp (GEN_INT (step2)); +#endif else { rtx reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); @@ -14640,7 +14663,7 @@ mips_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn) return store_data_bypass_p (out_insn, in_insn); } - +#ifdef MIPS_SUPPORT_LOONGSON /* Variables and flags used in scheduler hooks when tuning for Loongson 2E/2F. */ static struct @@ -14674,6 +14697,7 @@ static struct rtx_insn *falu1_turn_enabled_insn; rtx_insn *falu2_turn_enabled_insn; } mips_ls2; +#endif /* Implement TARGET_SCHED_ADJUST_COST. We assume that anti and output dependencies have no cost, except on the 20Kc where output-dependence @@ -14746,6 +14770,7 @@ mips_issue_rate (void) } } +#ifdef MIPS_SUPPORT_LOONGSON /* Implement TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN hook for Loongson2. */ static void @@ -14854,6 +14879,7 @@ mips_dfa_post_advance_cycle (void) if (TUNE_LOONGSON_2EF) mips_ls2_dfa_post_advance_cycle (curr_state); } +#endif /* Implement TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD. This should be as wide as the scheduling freedom in the DFA. */ @@ -14951,6 +14977,7 @@ mips_macc_chains_reorder (rtx_insn **ready, int nready) } } +#ifdef MIPS_SUPPORT_LEGACY /* The last instruction to be scheduled. */ static rtx_insn *vr4130_last_insn; @@ -15050,6 +15077,7 @@ vr4130_reorder (rtx_insn **ready, int nready) if (vr4130_swap_insns_p (ready[nready - 1], ready[nready - 2])) mips_promote_ready (ready, nready - 2, nready - 1); } +#endif /* Record whether last 74k AGEN instruction was a load or store. */ static enum attr_type mips_last_74k_agen_insn = TYPE_UNKNOWN; @@ -15131,14 +15159,18 @@ mips_sched_init (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, int max_ready ATTRIBUTE_UNUSED) { mips_macc_chains_last_hilo = 0; +#ifdef MIPS_SUPPORT_LEGACY vr4130_last_insn = 0; +#endif mips_74k_agen_init (NULL); +#ifdef MIPS_SUPPORT_LOONGSON /* When scheduling for Loongson2, branch instructions go to ALU1, therefore basic block is most likely to start with round-robin counter pointed to ALU2. */ mips_ls2.alu1_turn_p = false; mips_ls2.falu1_turn_p = true; +#endif } /* Subroutine used by TARGET_SCHED_REORDER and TARGET_SCHED_REORDER2. */ @@ -15152,11 +15184,13 @@ mips_sched_reorder_1 (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, && *nreadyp > 0) mips_macc_chains_reorder (ready, *nreadyp); +#ifdef MIPS_SUPPORT_LEGACY if (reload_completed && TUNE_MIPS4130 && !TARGET_VR4130_ALIGN && *nreadyp > 1) vr4130_reorder (ready, *nreadyp); +#endif if (TUNE_74K) mips_74k_agen_reorder (ready, *nreadyp); @@ -15182,6 +15216,7 @@ mips_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, return cached_can_issue_more; } +#ifdef MIPS_SUPPORT_LOONGSON /* Update round-robin counters for ALU1/2 and FALU1/2. */ static void @@ -15212,6 +15247,7 @@ mips_ls2_variable_issue (rtx_insn *insn) if (recog_memoized (insn) >= 0) mips_ls2.cycle_has_multi_p |= (get_attr_type (insn) == TYPE_MULTI); } +#endif /* Implement TARGET_SCHED_VARIABLE_ISSUE. */ @@ -15226,11 +15262,15 @@ mips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, more--; if (!reload_completed && TUNE_MACC_CHAINS) mips_macc_chains_record (insn); +#ifdef MIPS_SUPPORT_LEGACY vr4130_last_insn = insn; +#endif if (TUNE_74K) mips_74k_agen_init (insn); +#ifdef MIPS_SUPPORT_LOONGSON else if (TUNE_LOONGSON_2EF) mips_ls2_variable_issue (insn); +#endif } /* Instructions of type 'multi' should all be split before @@ -15335,17 +15375,25 @@ struct mips_builtin_description { }; AVAIL_ALL (hard_float, TARGET_HARD_FLOAT_ABI) +#ifdef MIPS_SUPPORT_PS_3D AVAIL_NON_MIPS16 (paired_single, TARGET_PAIRED_SINGLE_FLOAT) AVAIL_NON_MIPS16 (sb1_paired_single, TARGET_SB1 && TARGET_PAIRED_SINGLE_FLOAT) AVAIL_NON_MIPS16 (mips3d, TARGET_MIPS3D) +#endif +#ifdef MIPS_SUPPORT_DSP AVAIL_NON_MIPS16 (dsp, TARGET_DSP) AVAIL_NON_MIPS16 (dspr2, TARGET_DSPR2) AVAIL_NON_MIPS16 (dsp_32, !TARGET_64BIT && TARGET_DSP) AVAIL_NON_MIPS16 (dsp_64, TARGET_64BIT && TARGET_DSP) AVAIL_NON_MIPS16 (dspr2_32, !TARGET_64BIT && TARGET_DSPR2) +#endif +#ifdef MIPS_SUPPORT_LOONGSON AVAIL_NON_MIPS16 (loongson, TARGET_LOONGSON_MMI) +#endif AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN) +#ifdef MIPS_SUPPORT_MSA AVAIL_NON_MIPS16 (msa, TARGET_MSA) +#endif /* Construct a mips_builtin_description from the given arguments. @@ -15511,6 +15559,7 @@ AVAIL_NON_MIPS16 (msa, TARGET_MSA) "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT_NO_TARGET, \ FUNCTION_TYPE, mips_builtin_avail_msa, false } +#ifdef MIPS_SUPPORT_DSP #define CODE_FOR_mips_sqrt_ps CODE_FOR_sqrtv2sf2 #define CODE_FOR_mips_addq_ph CODE_FOR_addv2hi3 #define CODE_FOR_mips_addu_qb CODE_FOR_addv4qi3 @@ -15519,7 +15568,9 @@ AVAIL_NON_MIPS16 (msa, TARGET_MSA) #define CODE_FOR_mips_mul_ph CODE_FOR_mulv2hi3 #define CODE_FOR_mips_mult CODE_FOR_mulsidi3_32bit #define CODE_FOR_mips_multu CODE_FOR_umulsidi3_32bit +#endif +#ifdef MIPS_SUPPORT_LOONGSON #define CODE_FOR_loongson_packsswh CODE_FOR_vec_pack_ssat_v2si #define CODE_FOR_loongson_packsshb CODE_FOR_vec_pack_ssat_v4hi #define CODE_FOR_loongson_packushb CODE_FOR_vec_pack_usat_v4hi @@ -15550,7 +15601,9 @@ AVAIL_NON_MIPS16 (msa, TARGET_MSA) #define CODE_FOR_loongson_psubsb CODE_FOR_sssubv8qi3 #define CODE_FOR_loongson_psubush CODE_FOR_ussubv4hi3 #define CODE_FOR_loongson_psubusb CODE_FOR_ussubv8qi3 +#endif +#ifdef MIPS_SUPPORT_MSA #define CODE_FOR_msa_adds_s_b CODE_FOR_ssaddv16qi3 #define CODE_FOR_msa_adds_s_h CODE_FOR_ssaddv8hi3 #define CODE_FOR_msa_adds_s_w CODE_FOR_ssaddv4si3 @@ -15747,6 +15800,7 @@ AVAIL_NON_MIPS16 (msa, TARGET_MSA) #define CODE_FOR_msa_ldi_h CODE_FOR_msa_ldiv8hi #define CODE_FOR_msa_ldi_w CODE_FOR_msa_ldiv4si #define CODE_FOR_msa_ldi_d CODE_FOR_msa_ldiv2di +#endif static const struct mips_builtin_description mips_builtins[] = { #define MIPS_GET_FCSR 0 @@ -15754,6 +15808,7 @@ static const struct mips_builtin_description mips_builtins[] = { #define MIPS_SET_FCSR 1 DIRECT_NO_TARGET_BUILTIN (set_fcsr, MIPS_VOID_FTYPE_USI, hard_float), +#ifdef MIPS_SUPPORT_PS_3D DIRECT_BUILTIN_PURE (pll_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, paired_single), DIRECT_BUILTIN_PURE (pul_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, paired_single), DIRECT_BUILTIN_PURE (plu_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, paired_single), @@ -15787,7 +15842,9 @@ static const struct mips_builtin_description mips_builtins[] = { /* Built-in functions for the SB-1 processor. */ DIRECT_BUILTIN (sqrt_ps, MIPS_V2SF_FTYPE_V2SF, sb1_paired_single), +#endif +#ifdef MIPS_SUPPORT_DSP /* Built-in functions for the DSP ASE (32-bit and 64-bit). */ DIRECT_BUILTIN_PURE (addq_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dsp), DIRECT_BUILTIN_PURE (addq_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, dsp), @@ -15933,7 +15990,9 @@ static const struct mips_builtin_description mips_builtins[] = { DIRECT_BUILTIN_PURE (dpaqx_sa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32), DIRECT_BUILTIN_PURE (dpsqx_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32), DIRECT_BUILTIN_PURE (dpsqx_sa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32), +#endif +#ifdef MIPS_SUPPORT_LOONGSON /* Builtin functions for ST Microelectronics Loongson-2E/2F cores. */ LOONGSON_BUILTIN (packsswh, MIPS_V4HI_FTYPE_V2SI_V2SI), LOONGSON_BUILTIN (packsshb, MIPS_V8QI_FTYPE_V4HI_V4HI), @@ -16034,10 +16093,12 @@ static const struct mips_builtin_description mips_builtins[] = { LOONGSON_BUILTIN_SUFFIX (punpcklbh, s, MIPS_V8QI_FTYPE_V8QI_V8QI), LOONGSON_BUILTIN_SUFFIX (punpcklhw, s, MIPS_V4HI_FTYPE_V4HI_V4HI), LOONGSON_BUILTIN_SUFFIX (punpcklwd, s, MIPS_V2SI_FTYPE_V2SI_V2SI), +#endif /* Sundry other built-in functions. */ DIRECT_NO_TARGET_BUILTIN (cache, MIPS_VOID_FTYPE_SI_CVPOINTER, cache), +#ifdef MIPS_SUPPORT_MSA /* Built-in functions for MSA. */ MSA_BUILTIN_PURE (sll_b, MIPS_V16QI_FTYPE_V16QI_V16QI), MSA_BUILTIN_PURE (sll_h, MIPS_V8HI_FTYPE_V8HI_V8HI), @@ -16569,6 +16630,7 @@ static const struct mips_builtin_description mips_builtins[] = { MSA_NO_TARGET_BUILTIN (ctcmsa, MIPS_VOID_FTYPE_UQI_SI), MSA_BUILTIN_PURE (cfcmsa, MIPS_SI_FTYPE_UQI), MSA_BUILTIN_PURE (move_v, MIPS_V16QI_FTYPE_V16QI), +#endif }; /* Index I is the function declaration for mips_builtins[I], or null if the @@ -16739,20 +16801,19 @@ mips_builtin_decl (unsigned int code, bool initialize_p ATTRIBUTE_UNUSED) /* Implement TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION. */ static tree -mips_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in) +mips_builtin_vectorized_function (unsigned int fn ATTRIBUTE_UNUSED, + tree type_out, tree type_in) { - machine_mode in_mode, out_mode; - int in_n, out_n; - if (TREE_CODE (type_out) != VECTOR_TYPE || TREE_CODE (type_in) != VECTOR_TYPE || !ISA_HAS_MSA) return NULL_TREE; - out_mode = TYPE_MODE (TREE_TYPE (type_out)); - out_n = TYPE_VECTOR_SUBPARTS (type_out); - in_mode = TYPE_MODE (TREE_TYPE (type_in)); - in_n = TYPE_VECTOR_SUBPARTS (type_in); +#ifdef MIPS_SUPPORT_MSA + machine_mode out_mode = TYPE_MODE (TREE_TYPE (type_out)); + int out_n = TYPE_VECTOR_SUBPARTS (type_out); + machine_mode in_mode = TYPE_MODE (TREE_TYPE (type_in)); + int in_n = TYPE_VECTOR_SUBPARTS (type_in); /* INSN is the name of the associated instruction pattern, without the leading CODE_FOR_. */ @@ -16774,6 +16835,7 @@ mips_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in) default: break; } +#endif return NULL_TREE; } @@ -16804,10 +16866,11 @@ static rtx mips_expand_builtin_insn (enum insn_code icode, unsigned int nops, struct expand_operand *ops, bool has_target_p) { - machine_mode imode; + machine_mode imode ATTRIBUTE_UNUSED; int rangelo = 0, rangehi = 0, error_opno = 0; - rtx sireg; + rtx sireg ATTRIBUTE_UNUSED; +#ifdef MIPS_SUPPORT_MSA switch (icode) { /* The third operand of these instructions is in SImode, so we need to @@ -17092,6 +17155,7 @@ mips_expand_builtin_insn (enum insn_code icode, unsigned int nops, default: break; } +#endif if (error_opno != 0) { @@ -17160,6 +17224,7 @@ mips_expand_builtin_direct (enum insn_code icode, rtx target, tree exp, return mips_expand_builtin_insn (icode, opno, ops, has_target_p); } +#ifdef MIPS_SUPPORT_PS_3D /* Expand a __builtin_mips_movt_*_ps or __builtin_mips_movf_*_ps function; TYPE says which. EXP is the CALL_EXPR that calls the function, ICODE is the instruction that should be used to compare @@ -17190,6 +17255,7 @@ mips_expand_builtin_movtf (enum mips_builtin_type type, return mips_expand_builtin_insn (CODE_FOR_mips_cond_move_tf_ps, 4, ops, true); } +#endif /* Expand an MSA built-in for a compare and branch instruction specified by ICODE, set a general-purpose register to 1 if the branch was taken, @@ -17273,7 +17339,7 @@ mips_expand_builtin_compare (enum mips_builtin_type builtin_type, enum insn_code icode, enum mips_fp_condition cond, rtx target, tree exp) { - rtx offset, condition, cmp_result; + rtx offset ATTRIBUTE_UNUSED, condition, cmp_result; if (target == 0 || GET_MODE (target) != SImode) target = gen_reg_rtx (SImode); @@ -17290,12 +17356,14 @@ mips_expand_builtin_compare (enum mips_builtin_type builtin_type, return mips_builtin_branch_and_move (condition, target, const0_rtx, const1_rtx); +#ifdef MIPS_SUPPORT_PS_3D case MIPS_BUILTIN_CMP_UPPER: case MIPS_BUILTIN_CMP_LOWER: offset = GEN_INT (builtin_type == MIPS_BUILTIN_CMP_UPPER); condition = gen_single_cc (cmp_result, offset); return mips_builtin_branch_and_move (condition, target, const1_rtx, const0_rtx); +#endif default: condition = gen_rtx_NE (VOIDmode, cmp_result, const0_rtx); @@ -17304,6 +17372,7 @@ mips_expand_builtin_compare (enum mips_builtin_type builtin_type, } } +#ifdef MIPS_SUPPORT_DSP /* Expand a bposge built-in function of type BUILTIN_TYPE. TARGET, if nonnull, suggests a good place to put the boolean result. */ @@ -17327,6 +17396,7 @@ mips_expand_builtin_bposge (enum mips_builtin_type builtin_type, rtx target) return mips_builtin_branch_and_move (condition, target, const1_rtx, const0_rtx); } +#endif /* Implement TARGET_EXPAND_BUILTIN. */ @@ -17358,10 +17428,12 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, case MIPS_BUILTIN_DIRECT_NO_TARGET: return mips_expand_builtin_direct (d->icode, target, exp, false); +#ifdef MIPS_SUPPORT_PS_3D case MIPS_BUILTIN_MOVT: case MIPS_BUILTIN_MOVF: return mips_expand_builtin_movtf (d->builtin_type, d->icode, d->cond, target, exp); +#endif case MIPS_BUILTIN_CMP_ANY: case MIPS_BUILTIN_CMP_ALL: @@ -17374,8 +17446,10 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, case MIPS_BUILTIN_MSA_TEST_BRANCH: return mips_expand_builtin_msa_test_branch (d->icode, exp); +#ifdef MIPS_SUPPORT_DSP case MIPS_BUILTIN_BPOSGE32: return mips_expand_builtin_bposge (d->builtin_type, target); +#endif } gcc_unreachable (); } @@ -20525,7 +20599,9 @@ mips_option_override (void) if (TARGET_HARD_FLOAT_ABI && TARGET_MIPS5900) REAL_MODE_FORMAT (SFmode) = &spu_single_format; +#ifdef MIPS_SUPPORT_FRAME_HEADER_OPT mips_register_frame_header_opt (); +#endif } /* Swap the register information for registers I and I + 1, which @@ -20558,9 +20634,11 @@ mips_conditional_register_usage (void) if (ISA_HAS_DSP) { +#ifdef MIPS_SUPPORT_DSP /* These DSP control register fields are global. */ global_regs[CCDSP_PO_REGNUM] = 1; global_regs[CCDSP_SC_REGNUM] = 1; +#endif } else accessible_reg_set &= ~reg_class_contents[DSP_ACC_REGS]; @@ -21469,6 +21547,7 @@ mips_expand_vselect_vconcat (rtx target, rtx op0, rtx op1, return mips_expand_vselect (target, x, perm, nelt); } +#ifdef MIPS_SUPPORT_LOONGSON /* Recognize patterns for even-odd extraction. */ static bool @@ -21619,11 +21698,12 @@ mips_expand_vpc_loongson_bcast (struct expand_vec_perm_d *d) emit_move_insn (d->target, gen_lowpart (V8QImode, t1)); return true; } +#endif /* Construct (set target (vec_select op0 (parallel selector))) and return true if that's a valid instruction in the active ISA. */ -static bool +static bool ATTRIBUTE_UNUSED mips_expand_msa_shuffle (struct expand_vec_perm_d *d) { rtx x, elts[MAX_VECT_LEN]; @@ -21683,14 +21763,18 @@ mips_expand_vec_perm_const_1 (struct expand_vec_perm_d *d) return true; } +#ifdef MIPS_SUPPORT_LOONGSON if (mips_expand_vpc_loongson_even_odd (d)) return true; if (mips_expand_vpc_loongson_pshufh (d)) return true; if (mips_expand_vpc_loongson_bcast (d)) return true; +#endif +#ifdef MIPS_SUPPORT_MSA if (mips_expand_msa_shuffle (d)) return true; +#endif return false; } @@ -21803,6 +21887,7 @@ mips_sched_reassociation_width (unsigned int opc ATTRIBUTE_UNUSED, return 1; } +#ifdef MIPS_SUPPORT_MSA /* Expand an integral vector unpack operation. */ void @@ -21922,6 +22007,7 @@ mips_msa_vec_parallel_const_half (machine_mode mode, bool high_p) return gen_rtx_PARALLEL (VOIDmode, v); } +#endif /* A subroutine of mips_expand_vec_init, match constant vector elements. */ @@ -21948,12 +22034,14 @@ mips_expand_vi_broadcast (machine_mode vmode, rtx target, rtx elt) t1 = gen_reg_rtx (vmode); switch (vmode) { +#ifdef MIPS_SUPPORT_LOONGSON case E_V8QImode: emit_insn (gen_loongson_vec_init1_v8qi (t1, elt)); break; case E_V4HImode: emit_insn (gen_loongson_vec_init1_v4hi (t1, elt)); break; +#endif default: gcc_unreachable (); } @@ -21982,7 +22070,7 @@ mips_gen_const_int_vector (machine_mode mode, HOST_WIDE_INT val) /* Return a vector of repeated 4-element sets generated from immediate VAL in mode MODE. */ -static rtx +static rtx ATTRIBUTE_UNUSED mips_gen_const_int_vector_shuffle (machine_mode mode, int val) { int nunits = GET_MODE_NUNITS (mode); @@ -22021,6 +22109,7 @@ mips_expand_vi_constant (machine_mode vmode, unsigned nelt, } +#ifdef MIPS_SUPPORT_LOONGSON /* A subroutine of mips_expand_vec_init, expand via pinsrh. */ static void @@ -22031,6 +22120,7 @@ mips_expand_vi_loongson_one_pinsrh (rtx target, rtx vals, unsigned one_var) emit_insn (gen_vec_setv4hi (target, target, XVECEXP (vals, 0, one_var), GEN_INT (one_var))); } +#endif /* A subroutine of mips_expand_vec_init, expand anything via memory. */ @@ -22062,7 +22152,10 @@ mips_expand_vector_init (rtx target, rtx vals) machine_mode vmode = GET_MODE (target); machine_mode imode = GET_MODE_INNER (vmode); unsigned i, nelt = GET_MODE_NUNITS (vmode); - unsigned nvar = 0, one_var = -1u; + unsigned nvar = 0; +#ifdef MIPS_SUPPORT_LOONGSON + unsigned one_var = -1u; +#endif bool all_same = true; rtx x; @@ -22070,7 +22163,11 @@ mips_expand_vector_init (rtx target, rtx vals) { x = XVECEXP (vals, 0, i); if (!mips_constant_elt_p (x)) +#ifdef MIPS_SUPPORT_LOONGSON nvar++, one_var = i; +#else + nvar++; +#endif if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0))) all_same = false; } @@ -22117,6 +22214,7 @@ mips_expand_vector_init (rtx target, rtx vals) mips_emit_move (target, gen_rtx_VEC_DUPLICATE (vmode, temp)); break; +#ifdef MIPS_SUPPORT_MSA case E_V4SFmode: emit_insn (gen_msa_splati_w_f_scalar (target, temp)); break; @@ -22124,11 +22222,13 @@ mips_expand_vector_init (rtx target, rtx vals) case E_V2DFmode: emit_insn (gen_msa_splati_d_f_scalar (target, temp)); break; +#endif default: gcc_unreachable (); } } +#if defined (MIPS_SUPPORT_MSA) || defined (MIPS_SUPPORT_LOONGSON) else { emit_move_insn (target, CONST0_RTX (vmode)); @@ -22168,6 +22268,7 @@ mips_expand_vector_init (rtx target, rtx vals) } } } +#endif return; } @@ -22198,12 +22299,14 @@ mips_expand_vector_init (rtx target, rtx vals) return; } +#ifdef MIPS_SUPPORT_LOONGSON /* If we've only got one non-variable V4HImode, use PINSRH. */ if (nvar == 1 && vmode == V4HImode) { mips_expand_vi_loongson_one_pinsrh (target, vals, one_var); return; } +#endif mips_expand_vi_general (vmode, imode, nelt, nvar, target, vals); } @@ -22215,7 +22318,10 @@ mips_expand_vec_reduc (rtx target, rtx in, rtx (*gen)(rtx, rtx, rtx)) { machine_mode vmode = GET_MODE (in); unsigned char perm2[2]; - rtx last, next, fold, x; + rtx last, fold; +#ifdef MIPS_SUPPORT_LOONGSON + rtx next, x; +#endif bool ok; last = in; @@ -22233,6 +22339,7 @@ mips_expand_vec_reduc (rtx target, rtx in, rtx (*gen)(rtx, rtx, rtx)) gcc_assert (ok); break; +#ifdef MIPS_SUPPORT_LOONGSON case E_V2SImode: /* Use interleave to produce { H, L } op { H, H }. */ emit_insn (gen_loongson_punpckhwd (fold, last, last)); @@ -22271,6 +22378,7 @@ mips_expand_vec_reduc (rtx target, rtx in, rtx (*gen)(rtx, rtx, rtx)) x = force_reg (SImode, GEN_INT (8)); emit_insn (gen_vec_shr_v8qi (fold, last, x)); break; +#endif default: gcc_unreachable (); @@ -22379,10 +22487,12 @@ mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1) case LTGT: cond = NE; break; case UNGE: cond = UNLE; std::swap (op0, op1); break; case UNGT: cond = UNLT; std::swap (op0, op1); break; +#ifdef MIPS_SUPPORT_MSA case LE: unspec = UNSPEC_MSA_FSLE; break; case LT: unspec = UNSPEC_MSA_FSLT; break; case GE: unspec = UNSPEC_MSA_FSLE; std::swap (op0, op1); break; case GT: unspec = UNSPEC_MSA_FSLT; std::swap (op0, op1); break; +#endif default: gcc_unreachable (); } @@ -22700,10 +22810,14 @@ mips_asm_file_end (void) #define TARGET_SCHED_ADJUST_COST mips_adjust_cost #undef TARGET_SCHED_ISSUE_RATE #define TARGET_SCHED_ISSUE_RATE mips_issue_rate -#undef TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN -#define TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN mips_init_dfa_post_cycle_insn -#undef TARGET_SCHED_DFA_POST_ADVANCE_CYCLE -#define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE mips_dfa_post_advance_cycle + +#ifdef MIPS_SUPPORT_LOONGSON +# undef TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN +# define TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN mips_init_dfa_post_cycle_insn +# undef TARGET_SCHED_DFA_POST_ADVANCE_CYCLE +# define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE mips_dfa_post_advance_cycle +#endif + #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ mips_multipass_dfa_lookahead diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index a44ccada0bc..c188cfdbeaa 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -24,6 +24,14 @@ along with GCC; see the file COPYING3. If not see #include "config/vxworks-dummy.h" +#define MIPS_SUPPORT_DSP 1 +#define MIPS_SUPPORT_PS_3D 1 +#define MIPS_SUPPORT_MSA 1 +#define MIPS_SUPPORT_LOONGSON 1 +#define MIPS_SUPPORT_MICROMIPS 1 +#define MIPS_SUPPORT_LEGACY 1 +#define MIPS_SUPPORT_FRAME_HEADER_OPT 1 + #ifdef GENERATOR_FILE /* This is used in some insn conditions, so needs to be declared, but does not need to be defined. */ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 1c8b3b98b20..089faf86c2f 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -21,59 +21,6 @@ ;; along with GCC; see the file COPYING3. If not see ;; . -(define_enum "processor" [ - r3000 - 4kc - 4kp - 5kc - 5kf - 20kc - 24kc - 24kf2_1 - 24kf1_1 - 74kc - 74kf2_1 - 74kf1_1 - 74kf3_2 - loongson_2e - loongson_2f - gs464 - gs464e - gs264e - m4k - octeon - octeon2 - octeon3 - r3900 - r6000 - r4000 - r4100 - r4111 - r4120 - r4130 - r4300 - r4600 - r4650 - r4700 - r5000 - r5400 - r5500 - r5900 - r7000 - r8000 - r9000 - r10000 - sb1 - sb1a - sr71000 - xlr - xlp - p5600 - m5100 - i6400 - p6600 -]) - (define_c_enum "unspec" [ ;; Unaligned accesses. UNSPEC_LOAD_LEFT @@ -1160,38 +1107,6 @@ (eq_attr "type" "ghost") "nothing") -(include "i6400.md") -(include "p5600.md") -(include "m5100.md") -(include "p6600.md") -(include "4k.md") -(include "5k.md") -(include "20kc.md") -(include "24k.md") -(include "74k.md") -(include "3000.md") -(include "4000.md") -(include "4100.md") -(include "4130.md") -(include "4300.md") -(include "4600.md") -(include "5000.md") -(include "5400.md") -(include "5500.md") -(include "6000.md") -(include "7000.md") -(include "9000.md") -(include "10000.md") -(include "loongson2ef.md") -(include "gs464.md") -(include "gs464e.md") -(include "gs264e.md") -(include "octeon.md") -(include "sb1.md") -(include "sr71k.md") -(include "xlr.md") -(include "xlp.md") -(include "generic.md") ;; ;; .................... @@ -7792,35 +7707,3 @@ (any_extend:SI (match_dup 3)))])] "") - -;; Synchronization instructions. - -(include "sync.md") - -; The MIPS Paired-Single Floating Point and MIPS-3D Instructions. - -(include "mips-ps-3d.md") - -; The MIPS DSP Instructions. - -(include "mips-dsp.md") - -; The MIPS DSP REV 2 Instructions. - -(include "mips-dspr2.md") - -; MIPS fixed-point instructions. -(include "mips-fixed.md") - -; microMIPS patterns. -(include "micromips.md") - -; Loongson MultiMedia extensions Instructions (MMI) patterns. -(include "loongson-mmi.md") - -; The MIPS MSA Instructions. -(include "mips-msa.md") - -(define_c_enum "unspec" [ - UNSPEC_ADDRESS_FIRST -]) diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index 6af8037e9bd..2e647d703b4 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -28,7 +28,7 @@ EL Driver mabi= -Target RejectNegative Joined Enum(mips_abi) Var(mips_abi) Init(MIPS_ABI_DEFAULT) +Target RejectNegative Joined Enum(mips_abi) Var(mips_abi) Init(MIPS_ABI_DEFAULT) Condition(MIPS_SUPPORT_LEGACY) -mabi=ABI Generate code that conforms to the given ABI. Enum @@ -51,15 +51,15 @@ EnumValue Enum(mips_abi) String(eabi) Value(ABI_EABI) mabicalls -Target Mask(ABICALLS) +Target Mask(ABICALLS) Condition(MIPS_SUPPORT_LEGACY) Generate code that can be used in SVR4-style dynamic objects. mmad -Target Var(TARGET_MAD) +Target Var(TARGET_MAD) Condition(MIPS_SUPPORT_LEGACY) Use PMC-style 'mad' instructions. mimadd -Target Mask(IMADD) +Target Mask(IMADD) Condition(MIPS_SUPPORT_DSP) Use integer madd/msub instructions. march= @@ -71,11 +71,11 @@ Target RejectNegative Joined UInteger Var(mips_branch_cost) -mbranch-cost=COST Set the cost of branches to roughly COST instructions. mbranch-likely -Target Mask(BRANCHLIKELY) +Target Mask(BRANCHLIKELY) Condition(MIPS_SUPPORT_LEGACY) Use Branch Likely instructions, overriding the architecture default. mflip-mips16 -Target Var(TARGET_FLIP_MIPS16) +Target Var(TARGET_FLIP_MIPS16) Condition(MIPS_SUPPORT_LEGACY) Switch on/off MIPS16 ASE on alternating functions for compiler testing. mcheck-zero-division @@ -83,7 +83,7 @@ Target Mask(CHECK_ZERO_DIV) Trap on integer divide by zero. mcode-readable= -Target RejectNegative Joined Enum(mips_code_readable_setting) Var(mips_code_readable) Init(CODE_READABLE_YES) +Target RejectNegative Joined Enum(mips_code_readable_setting) Var(mips_code_readable) Init(CODE_READABLE_YES) Condition(MIPS_SUPPORT_LEGACY) -mcode-readable=SETTING Specify when instructions are allowed to access code. Enum @@ -100,7 +100,7 @@ EnumValue Enum(mips_code_readable_setting) String(no) Value(CODE_READABLE_NO) mdivide-breaks -Target RejectNegative Mask(DIVIDE_BREAKS) +Target RejectNegative Mask(DIVIDE_BREAKS) Condition(MIPS_SUPPORT_LEGACY) Use branch-and-break sequences to check for integer divide by zero. mdivide-traps @@ -108,7 +108,7 @@ Target RejectNegative InverseMask(DIVIDE_BREAKS, DIVIDE_TRAPS) Use trap instructions to check for integer divide by zero. mdmx -Target RejectNegative Var(TARGET_MDMX) +Target RejectNegative Var(TARGET_MDMX) Condition(MIPS_SUPPORT_LEGACY) Allow the use of MDMX instructions. mdouble-float @@ -120,14 +120,14 @@ Target Var(TARGET_DSP) Use MIPS-DSP instructions. mdspr2 -Target Var(TARGET_DSPR2) +Target Var(TARGET_DSPR2) Condition(MIPS_SUPPORT_DSP) Use MIPS-DSP REV 2 instructions. mdebug -Target Var(TARGET_DEBUG_MODE) Undocumented +Target Var(TARGET_DEBUG_MODE) Undocumented Condition(MIPS_SUPPORT_LEGACY) mdebugd -Target Var(TARGET_DEBUG_D_MODE) Undocumented +Target Var(TARGET_DEBUG_D_MODE) Undocumented Condition(MIPS_SUPPORT_LEGACY) meb Target RejectNegative Mask(BIG_ENDIAN) @@ -146,7 +146,7 @@ Target Var(TARGET_EVA) Use Enhanced Virtual Addressing instructions. mexplicit-relocs -Target Mask(EXPLICIT_RELOCS) +Target Mask(EXPLICIT_RELOCS) Condition(MIPS_SUPPORT_LEGACY) Use NewABI-style %reloc() assembly operators. mextern-sdata @@ -154,15 +154,15 @@ Target Var(TARGET_EXTERN_SDATA) Init(1) Use -G for data that is not defined by the current object. mfix-24k -Target Var(TARGET_FIX_24K) +Target Var(TARGET_FIX_24K) Condition(MIPS_SUPPORT_LEGACY) Work around certain 24K errata. mfix-r4000 -Target Mask(FIX_R4000) +Target Mask(FIX_R4000) Condition(MIPS_SUPPORT_LEGACY) Work around certain R4000 errata. mfix-r4400 -Target Mask(FIX_R4400) +Target Mask(FIX_R4400) Condition(MIPS_SUPPORT_LEGACY) Work around certain R4400 errata. mfix-r5900 @@ -170,43 +170,43 @@ Target Mask(FIX_R5900) Work around the R5900 short loop erratum. mfix-rm7000 -Target Var(TARGET_FIX_RM7000) +Target Var(TARGET_FIX_RM7000) Condition(MIPS_SUPPORT_LEGACY) Work around certain RM7000 errata. mfix-r10000 -Target Mask(FIX_R10000) +Target Mask(FIX_R10000) Condition(MIPS_SUPPORT_LEGACY) Work around certain R10000 errata. mfix-sb1 -Target Var(TARGET_FIX_SB1) +Target Var(TARGET_FIX_SB1) Condition(MIPS_SUPPORT_LEGACY) Work around errata for early SB-1 revision 2 cores. mfix-vr4120 -Target Var(TARGET_FIX_VR4120) +Target Var(TARGET_FIX_VR4120) Condition(MIPS_SUPPORT_LEGACY) Work around certain VR4120 errata. mfix-vr4130 -Target Var(TARGET_FIX_VR4130) +Target Var(TARGET_FIX_VR4130) Condition(MIPS_SUPPORT_LEGACY) Work around VR4130 mflo/mfhi errata. mfix4300 -Target Var(TARGET_4300_MUL_FIX) +Target Var(TARGET_4300_MUL_FIX) Condition(MIPS_SUPPORT_LEGACY) Work around an early 4300 hardware bug. mfp-exceptions -Target Var(TARGET_FP_EXCEPTIONS) Init(1) +Target Var(TARGET_FP_EXCEPTIONS) Init(1) Condition(MIPS_SUPPORT_LEGACY) FP exceptions are enabled. mfp32 -Target RejectNegative InverseMask(FLOAT64) +Target RejectNegative InverseMask(FLOAT64) Condition(MIPS_SUPPORT_LEGACY) Use 32-bit floating-point registers. mfpxx -Target RejectNegative Mask(FLOATXX) +Target RejectNegative Mask(FLOATXX) Condition(MIPS_SUPPORT_LEGACY) Conform to the o32 FPXX ABI. mfp64 -Target RejectNegative Mask(FLOAT64) +Target RejectNegative Mask(FLOAT64) Condition(MIPS_SUPPORT_LEGACY) Use 64-bit floating-point registers. mflush-func= @@ -214,11 +214,11 @@ Target RejectNegative Joined Var(mips_cache_flush_func) Init(CACHE_FLUSH_FUNC) -mflush-func=FUNC Use FUNC to flush the cache before calling stack trampolines. mabs= -Target RejectNegative Joined Enum(mips_ieee_754_value) Var(mips_abs) Init(MIPS_IEEE_754_DEFAULT) +Target RejectNegative Joined Enum(mips_ieee_754_value) Var(mips_abs) Init(MIPS_IEEE_754_DEFAULT) Condition(MIPS_SUPPORT_LEGACY) -mabs=MODE Select the IEEE 754 ABS/NEG instruction execution mode. mnan= -Target RejectNegative Joined Enum(mips_ieee_754_value) Var(mips_nan) Init(MIPS_IEEE_754_DEFAULT) +Target RejectNegative Joined Enum(mips_ieee_754_value) Var(mips_nan) Init(MIPS_IEEE_754_DEFAULT) Condition(MIPS_SUPPORT_LEGACY) -mnan=ENCODING Select the IEEE 754 NaN data encoding. Enum @@ -244,7 +244,7 @@ Target Var(TARGET_GPOPT) Init(1) Use GP-relative addressing to access small data. mplt -Target Var(TARGET_PLT) +Target Var(TARGET_PLT) Condition(MIPS_SUPPORT_LEGACY) When generating -mabicalls code, allow executables to use PLTs and copy relocations. mhard-float @@ -252,27 +252,27 @@ Target RejectNegative InverseMask(SOFT_FLOAT_ABI, HARD_FLOAT_ABI) Allow the use of hardware floating-point ABI and instructions. minterlink-compressed -Target Var(TARGET_INTERLINK_COMPRESSED) Init(0) +Target Var(TARGET_INTERLINK_COMPRESSED) Init(0) Condition(MIPS_SUPPORT_LEGACY) Generate code that is link-compatible with MIPS16 and microMIPS code. minterlink-mips16 -Target Var(TARGET_INTERLINK_COMPRESSED) Init(0) +Target Var(TARGET_INTERLINK_COMPRESSED) Init(0) Condition(MIPS_SUPPORT_LEGACY) An alias for minterlink-compressed provided for backward-compatibility. mips -Target RejectNegative Joined ToLower Enum(mips_mips_opt_value) Var(mips_isa_option) +Target RejectNegative Joined ToLower Enum(mips_mips_opt_value) Var(mips_isa_option) Condition(MIPS_SUPPORT_LEGACY) -mipsN Generate code for ISA level N. mips16 -Target RejectNegative Mask(MIPS16) +Target RejectNegative Mask(MIPS16) Condition(MIPS_SUPPORT_LEGACY) Generate MIPS16 code. mips3d -Target RejectNegative Var(TARGET_MIPS3D) +Target RejectNegative Var(TARGET_MIPS3D) Condition(MIPS_SUPPORT_LEGACY) Use MIPS-3D instructions. mllsc -Target Mask(LLSC) +Target Mask(LLSC) Condition(MIPS_SUPPORT_LEGACY) Use ll, sc and sync instructions. mlocal-sdata @@ -284,15 +284,15 @@ Target Var(TARGET_LONG_CALLS) Use indirect calls. mlong32 -Target RejectNegative InverseMask(LONG64, LONG32) +Target RejectNegative InverseMask(LONG64, LONG32) Condition(MIPS_SUPPORT_LEGACY) Use a 32-bit long type. mlong64 -Target RejectNegative Mask(LONG64) +Target RejectNegative Mask(LONG64) Condition(MIPS_SUPPORT_LEGACY) Use a 64-bit long type. mmcount-ra-address -Target Var(TARGET_MCOUNT_RA_ADDRESS) +Target Var(TARGET_MCOUNT_RA_ADDRESS) Condition(MIPS_SUPPORT_LEGACY) Pass the address of the ra save location to _mcount in $12. mmemcpy @@ -300,11 +300,11 @@ Target Mask(MEMCPY) Don't optimize block moves. mmicromips -Target Mask(MICROMIPS) +Target Mask(MICROMIPS) Condition(MIPS_SUPPORT_LEGACY) Use microMIPS instructions. mmsa -Target Mask(MSA) +Target Var(TARGET_MSA) Condition(MIPS_SUPPORT_MSA) Use MIPS MSA Extension instructions. mmt @@ -324,23 +324,23 @@ Target RejectNegative Do not use a cache-flushing function before calling stack trampolines. mno-mdmx -Target RejectNegative Var(TARGET_MDMX, 0) +Target RejectNegative Var(TARGET_MDMX, 0) Condition(MIPS_SUPPORT_LEGACY) Do not use MDMX instructions. mno-mips16 -Target RejectNegative InverseMask(MIPS16) +Target RejectNegative InverseMask(MIPS16) Condition(MIPS_SUPPORT_LEGACY) Generate normal-mode code. mno-mips3d -Target RejectNegative Var(TARGET_MIPS3D, 0) +Target RejectNegative Var(TARGET_MIPS3D, 0) Condition(MIPS_SUPPORT_LEGACY) Do not use MIPS-3D instructions. mpaired-single -Target Mask(PAIRED_SINGLE_FLOAT) +Target Mask(PAIRED_SINGLE_FLOAT) Condition(MIPS_SUPPORT_LEGACY) Use paired-single floating-point instructions. mr10k-cache-barrier= -Target Joined RejectNegative Enum(mips_r10k_cache_barrier_setting) Var(mips_r10k_cache_barrier) Init(R10K_CACHE_BARRIER_NONE) +Target Joined RejectNegative Enum(mips_r10k_cache_barrier_setting) Var(mips_r10k_cache_barrier) Init(R10K_CACHE_BARRIER_NONE) Condition(MIPS_SUPPORT_LEGACY) -mr10k-cache-barrier=SETTING Specify when r10k cache barriers should be inserted. Enum @@ -357,11 +357,11 @@ EnumValue Enum(mips_r10k_cache_barrier_setting) String(none) Value(R10K_CACHE_BARRIER_NONE) mrelax-pic-calls -Target Mask(RELAX_PIC_CALLS) +Target Mask(RELAX_PIC_CALLS) Condition(MIPS_SUPPORT_LEGACY) Try to allow the linker to turn PIC calls into direct calls. mshared -Target Var(TARGET_SHARED) Init(1) +Target Var(TARGET_SHARED) Init(1) Condition(MIPS_SUPPORT_LEGACY) When generating -mabicalls code, make the code suitable for use in shared libraries. msingle-float @@ -369,7 +369,7 @@ Target RejectNegative Mask(SINGLE_FLOAT) Restrict the use of hardware floating-point instructions to 32-bit operations. msmartmips -Target Mask(SMARTMIPS) +Target Mask(SMARTMIPS) Condition(MIPS_SUPPORT_LEGACY) Use SmartMIPS instructions. msoft-float @@ -377,7 +377,7 @@ Target RejectNegative Mask(SOFT_FLOAT_ABI) Prevent the use of all hardware floating-point instructions. msplit-addresses -Target Mask(SPLIT_ADDRESSES) +Target Mask(SPLIT_ADDRESSES) Condition(MIPS_SUPPORT_LEGACY) Optimize lui/addiu address loads. msym32 @@ -385,11 +385,11 @@ Target Var(TARGET_SYM32) Assume all symbols have 32-bit values. msynci -Target Mask(SYNCI) +Target Mask(SYNCI) Condition(MIPS_SUPPORT_LEGACY) Use synci instruction to invalidate i-cache. mlra -Target Var(mips_lra_flag) Init(1) Save +Target Var(mips_lra_flag) Init(1) Save Condition(MIPS_SUPPORT_LEGACY) Use LRA instead of reload. mlxc1-sxc1 @@ -425,30 +425,30 @@ Target Var(TARGET_GINV) Use Global INValidate (GINV) instructions. mvr4130-align -Target Mask(VR4130_ALIGN) +Target Mask(VR4130_ALIGN) Condition(MIPS_SUPPORT_LEGACY) Perform VR4130-specific alignment optimizations. mxgot -Target Var(TARGET_XGOT) +Target Var(TARGET_XGOT) Condition(MIPS_SUPPORT_LEGACY) Lift restrictions on GOT size. modd-spreg -Target Mask(ODD_SPREG) +Target Mask(ODD_SPREG) Condition(MIPS_SUPPORT_LEGACY) Enable use of odd-numbered single-precision registers. mframe-header-opt -Target Var(flag_frame_header_optimization) Optimization +Target Var(flag_frame_header_optimization) Optimization Condition(MIPS_SUPPORT_FRAME_HEADER_OPT) Optimize frame header. noasmopt -Driver +Driver Condition(MIPS_SUPPORT_LEGACY) mload-store-pairs -Target Var(TARGET_LOAD_STORE_PAIRS) Init(1) +Target Var(TARGET_LOAD_STORE_PAIRS) Init(1) Condition(MIPS_SUPPORT_LEGACY) Enable load/store bonding. mcompact-branches= -Target RejectNegative JoinedOrMissing Var(mips_cb) Enum(mips_cb_setting) Init(MIPS_CB_OPTIMAL) +Target RejectNegative JoinedOrMissing Var(mips_cb) Enum(mips_cb_setting) Init(MIPS_CB_OPTIMAL) Condition(MIPS_SUPPORT_LEGACY) Specify the compact branch usage policy. Enum @@ -465,13 +465,13 @@ EnumValue Enum(mips_cb_setting) String(always) Value(MIPS_CB_ALWAYS) mloongson-mmi -Target Mask(LOONGSON_MMI) +Target Mask(LOONGSON_MMI) Condition(MIPS_SUPPORT_LOONGSON) Use Loongson MultiMedia extensions Instructions (MMI) instructions. mloongson-ext -Target Mask(LOONGSON_EXT) +Target Mask(LOONGSON_EXT) Condition(MIPS_SUPPORT_LOONGSON) Use Loongson EXTension (EXT) instructions. mloongson-ext2 -Target Var(TARGET_LOONGSON_EXT2) +Target Var(TARGET_LOONGSON_EXT2) Condition(MIPS_SUPPORT_LOONGSON) Use Loongson EXTension R2 (EXT2) instructions. From patchwork Sun Sep 26 13:25:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dragan Mladjenovic X-Patchwork-Id: 45449 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8BAAE385800C for ; Sun, 26 Sep 2021 13:35:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8BAAE385800C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1632663341; bh=6Nmi2E4PjczCl/Glf/6HjoSdaP1DHFYA9JRY5ovPnOg=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=K0G9HWakb41uXaFTyR0D+Mpd9YwRjQDtzyBRz6RYBfq+6yJquJO35yH3AxB8beEgz s+DLssNJ8L/UpFs7FtGLI47w5fZp70w0oqlKTCgld0QVFLNXH0cu6xkz0V8Usqi9CB VbbLG9tGK+0G1i9UJZmu5JXaxM5BcQ20nN/gAV6A= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mailgw01.mediatek.com (mailgw01.mediatek.com [216.200.240.184]) by sourceware.org (Postfix) with ESMTPS id BF1AA3858C60; Sun, 26 Sep 2021 13:35:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BF1AA3858C60 X-UUID: 56fd8c14bc104271802a24b6f4721612-20210926 X-UUID: 56fd8c14bc104271802a24b6f4721612-20210926 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1951553952; Sun, 26 Sep 2021 06:35:05 -0700 Received: from MTKMBS62N1.mediatek.inc (172.29.193.41) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sun, 26 Sep 2021 06:25:35 -0700 Received: from MTKMBS62N1.mediatek.inc ([fe80::697c:586d:7cff:34e7]) by MTKMBS62N1.mediatek.inc ([fe80::697c:586d:7cff:34e7%12]) with mapi id 15.00.1497.015; Sun, 26 Sep 2021 06:25:35 -0700 To: "gcc-patches@gcc.gnu.org" Subject: [RFC 5/7] Fix unhelpful messages for disabled options. Thread-Topic: [RFC 5/7] Fix unhelpful messages for disabled options. Thread-Index: AQHXstn9aU1cFnm7hU24KO2CeVyYTg== Date: Sun, 26 Sep 2021 13:25:35 +0000 Message-ID: <5f83621c703c41b79fbc26b4b41d28f3@MTKMBS62N1.mediatek.inc> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [172.29.193.239] MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, HTML_MESSAGE, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP, UNPARSEABLE_RELAY 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-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Dragan Mladjenovic via Gcc-patches From: Dragan Mladjenovic Reply-To: Dragan Mladjenovic Cc: Jeff Law , Matthew Fortune , Jakub Jelinek , YunQiang Su , "Petar.Jovanovic@syrmia.com" , Faraz Shahbazker , Vince Del Vecchio Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Firstly, the option handling was building suggestions without checking if an option is disabled. This could have caused other unhelpful messages for other mistyped options. Secondly, the key issue here appears to be the lack of CL_JOINED flag for the false 'Condition' i.e. an option is disabled but other flags are zeroed out too. This caused find_opt() not to return the right index to an option e.g. for -mabi= we would expect OPT_mabi_ rather than OPT_SPECIAL_unknown, hence, the option did not appear to be correctly marked as disabled. The patch aims to retain the extra flag but to keep an option as disabled. I do not see any fallout with this, -m= are now rejected on the command line and not printed with --target-help. gcc/ChangeLog: * opt-suggestions.c (option_proposer::build_option_suggestions): Ignore disabled options. * opts.c (print_filtered_help): Likewise. * optc-gen.awk: Preserve flags in both cases. gcc/testsuite/ChangeLog: * gcc.target/nanomips/nanomips-err-mabi32.c: New test. --- gcc/opt-suggestions.c | 3 +++ gcc/optc-gen.awk | 5 +++-- gcc/opts.c | 4 ++++ .../gcc.target/nanomips/nanomips-err-mabi32.c (new) | 4 ++++ 4 files changed, 14 insertions(+), 2 deletions(-) 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/nanomips/nanomips-err-mabi32.c diff --git a/gcc/opt-suggestions.c b/gcc/opt-suggestions.c index 5c36fc8cc8c..03bccd5379f 100644 --- a/gcc/opt-suggestions.c +++ b/gcc/opt-suggestions.c @@ -108,6 +108,9 @@ option_proposer::build_option_suggestions (const char *prefix) switch (i) { default: + /* We don't want to suggest disabled options. */ + if (option->cl_disabled) + continue; if (option->var_type == CLVC_ENUM) { const struct cl_enum *e = &cl_enums[option->var_enum]; diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk index 77e598efd60..eb725fdb8ce 100644 --- a/gcc/optc-gen.awk +++ b/gcc/optc-gen.awk @@ -412,10 +412,11 @@ for (i = 0; i < n_opts; i++) { " %s,\n" \ " 0, %s,\n" \ "#else\n" \ - " 0,\n" \ + " %s,\n" \ " 1 /* Disabled. */, %s,\n" \ "#endif\n", - condition, cl_flags, cl_bit_fields, cl_zero_bit_fields) + condition, cl_flags, cl_bit_fields, + cl_flags, cl_zero_bit_fields) else printf(" %s,\n" \ " 0, %s,\n", diff --git a/gcc/opts.c b/gcc/opts.c index 1d2d22d7a3f..d85fc2adf8a 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1435,6 +1435,10 @@ print_filtered_help (unsigned int include_flags, continue; } + /* Skip disabled options. */ + if (option->cl_disabled) + continue; + /* Skip unwanted switches. */ if ((option->flags & exclude_flags) != 0) continue; diff --git a/gcc/testsuite/gcc.target/nanomips/nanomips-err-mabi32.c b/gcc/testsuite/gcc.target/nanomips/nanomips-err-mabi32.c new file mode 100644 index 00000000000..1bf233a36e3 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/nanomips-err-mabi32.c @@ -0,0 +1,4 @@ +/* Verify that we get an error for unsupported -mabi=32 option. */ +/* { dg-additional-options "-mabi=32" } */ +/* { dg-error "not supported by this configuration" "" { target *-*-* } 0 } */ +void foo (void) {} From patchwork Sun Sep 26 13:25:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dragan Mladjenovic X-Patchwork-Id: 45451 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2491F3858409 for ; Sun, 26 Sep 2021 13:37:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2491F3858409 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1632663463; bh=7AopWOhCQgtLjQW5I90E8bIcWYnp+HgrKigvWuZ09xQ=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=kFXdH5BfT5DnWwFZEyyr1g94UDXdFCx5DdAcFr6zvY+Ch1450OvO17fa9wGQeh4IP vE354Gr3Pn35JYjBml1KMQdE7FSvSsDIIb51RhP6Urfkh93VFFVYLs+gkXtpa179xv +O26qPl2foyFC0+0NYv89UUBvCXe7hFqXw2aPPkU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mailgw02.mediatek.com (mailgw02.mediatek.com [216.200.240.185]) by sourceware.org (Postfix) with ESMTPS id 8190F3858022; Sun, 26 Sep 2021 13:35:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8190F3858022 X-UUID: df113a4c92484601b27fc60a3722d220-20210926 X-UUID: df113a4c92484601b27fc60a3722d220-20210926 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1370337343; Sun, 26 Sep 2021 06:35:27 -0700 Received: from MTKMBS62N1.mediatek.inc (172.29.193.41) by MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sun, 26 Sep 2021 06:25:52 -0700 Received: from MTKMBS62N1.mediatek.inc ([fe80::697c:586d:7cff:34e7]) by MTKMBS62N1.mediatek.inc ([fe80::697c:586d:7cff:34e7%12]) with mapi id 15.00.1497.015; Sun, 26 Sep 2021 06:25:52 -0700 To: "gcc-patches@gcc.gnu.org" Subject: [RFC 6/7] Enable MIPS DSP rev3 ASE for nanoMIPS Thread-Topic: [RFC 6/7] Enable MIPS DSP rev3 ASE for nanoMIPS Thread-Index: AQHXstoHXXAnhx6vFUS7cB/ZGwEGYw== Date: Sun, 26 Sep 2021 13:25:52 +0000 Message-ID: <9150198c8a0148ed963ee487c66b8dcf@MTKMBS62N1.mediatek.inc> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [172.29.193.239] MIME-Version: 1.0 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, HTML_MESSAGE, KAM_SHORT, SCC_10_SHORT_WORD_LINES, SCC_5_SHORT_WORD_LINES, SPF_HELO_NONE, SPF_PASS, TXREP, UNPARSEABLE_RELAY 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-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Dragan Mladjenovic via Gcc-patches From: Dragan Mladjenovic Reply-To: Dragan Mladjenovic Cc: Jeff Law , Matthew Fortune , Jakub Jelinek , YunQiang Su , "Petar.Jovanovic@syrmia.com" , Faraz Shahbazker , Vince Del Vecchio Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" gcc/ChangeLog: * config/mips/mips-dsp.md (mips_bposge): Output bposgec for TARGET_DSPR3. * config/mips/mips.c (mips_output_move): Use $ac0 for $lo if base isa doesn't have md registers. (mips_option_override) [TARGET_DSPR3]: Enable TARGET_DSP and TARGET_DSPR2. (mips_conditional_register_usage) [ISA_HAS_DSP]: Don't disable md registers. * config/mips/mips.h (TARGET_CPU_CPP_BUILTINS) [TARGET_DSPR3]: Define __mips_dsp_rev=3 and __mips_dspr3. (ASM_SPEC): Forward mdspr3 and mno-dspr3. * config/mips/mips.md (mulsidi3_32bit): Enable for ISA_HAS_DSP. (mfhi_, mthi_): Use $ac0 for $lo if base isa doesn't have md registers. * config/mips/mips.opt (mdspr3): New option. Enabled for TARGET_NANOMIPS. (mdspr2): Disabled for TARGET_NANOMIPS. gcc/testsuite/ChangeLog: * gcc.target/nanomips/dpaq_sa_l_w.c: New test. * gcc.target/nanomips/dpsq_sa_l_w.c: New test. * gcc.target/nanomips/dsp-ctrl.c: New test. * gcc.target/nanomips/dsp-lhxs.c: New test. * gcc.target/nanomips/dsp-no-lhx.c: New test. * gcc.target/nanomips/fixed-scalar-type.c: New test. * gcc.target/nanomips/fixed-vector-type.c: New test. * gcc.target/nanomips/madd-4.c: New test. * gcc.target/nanomips/maddu-3.c: New test. * gcc.target/nanomips/maddu-4.c: New test. * gcc.target/nanomips/mips-prepend-1.c: New test. * gcc.target/nanomips/mips32-dsp-run.c: New test. * gcc.target/nanomips/mips32-dspr2.c: New test. * gcc.target/nanomips/msub-4.c: New test. * gcc.target/nanomips/msubu-4.c: New test. * gcc.target/nanomips/nanomips-dsp-accinit-2.c: New test. * gcc.target/nanomips/nanomips-dsp.c: New test. * gcc.target/nanomips/nanomips-dspr3-type-1.c: New test. * gcc.target/nanomips/nanomips-dspr3-type-2.c: New test. --- gcc/config/mips/mips-dsp.md | 17 +- gcc/config/mips/mips.c | 22 +- gcc/config/mips/mips.h | 6 + gcc/config/mips/mips.md | 12 +- gcc/config/mips/mips.opt | 6 +- .../gcc.target/nanomips/dpaq_sa_l_w.c (new) | 51 + .../gcc.target/nanomips/dpsq_sa_l_w.c (new) | 37 + .../gcc.target/nanomips/dsp-ctrl.c (new) | 69 + .../gcc.target/nanomips/dsp-lhxs.c (new) | 11 + .../gcc.target/nanomips/dsp-no-lhx.c (new) | 11 + .../nanomips/fixed-scalar-type.c (new) | 218 ++++ .../nanomips/fixed-vector-type.c (new) | 133 ++ .../gcc.target/nanomips/madd-4.c (new) | 27 + .../gcc.target/nanomips/maddu-3.c (new) | 30 + .../gcc.target/nanomips/maddu-4.c (new) | 30 + .../nanomips/mips-prepend-1.c (new) | 8 + .../nanomips/mips32-dsp-run.c (new) | 1063 +++++++++++++++ .../gcc.target/nanomips/mips32-dspr2.c (new) | 541 ++++++++ .../gcc.target/nanomips/msub-4.c (new) | 21 + .../gcc.target/nanomips/msubu-4.c (new) | 24 + .../nanomips/nanomips-dsp-accinit-2.c (new) | 23 + .../gcc.target/nanomips/nanomips-dsp.c (new) | 1160 +++++++++++++++++ .../nanomips/nanomips-dspr3-type-1.c (new) | 30 + .../nanomips/nanomips-dspr3-type-2.c (new) | 12 + 24 files changed, 3552 insertions(+), 10 deletions(-) 24 files changed, 3552 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.target/nanomips/dpaq_sa_l_w.c create mode 100644 gcc/testsuite/gcc.target/nanomips/dpsq_sa_l_w.c create mode 100644 gcc/testsuite/gcc.target/nanomips/dsp-ctrl.c create mode 100644 gcc/testsuite/gcc.target/nanomips/dsp-lhxs.c create mode 100644 gcc/testsuite/gcc.target/nanomips/dsp-no-lhx.c create mode 100644 gcc/testsuite/gcc.target/nanomips/fixed-scalar-type.c create mode 100644 gcc/testsuite/gcc.target/nanomips/fixed-vector-type.c create mode 100644 gcc/testsuite/gcc.target/nanomips/madd-4.c create mode 100644 gcc/testsuite/gcc.target/nanomips/maddu-3.c create mode 100644 gcc/testsuite/gcc.target/nanomips/maddu-4.c create mode 100644 gcc/testsuite/gcc.target/nanomips/mips-prepend-1.c create mode 100644 gcc/testsuite/gcc.target/nanomips/mips32-dsp-run.c create mode 100644 gcc/testsuite/gcc.target/nanomips/mips32-dspr2.c create mode 100644 gcc/testsuite/gcc.target/nanomips/msub-4.c create mode 100644 gcc/testsuite/gcc.target/nanomips/msubu-4.c create mode 100644 gcc/testsuite/gcc.target/nanomips/nanomips-dsp-accinit-2.c create mode 100644 gcc/testsuite/gcc.target/nanomips/nanomips-dsp.c create mode 100644 gcc/testsuite/gcc.target/nanomips/nanomips-dspr3-type-1.c create mode 100644 gcc/testsuite/gcc.target/nanomips/nanomips-dspr3-type-2.c diff --git a/gcc/config/mips/mips-dsp.md b/gcc/config/mips/mips-dsp.md index 5a5694f3f9e..d71ad95aa40 100644 --- a/gcc/config/mips/mips-dsp.md +++ b/gcc/config/mips/mips-dsp.md @@ -1152,8 +1152,21 @@ (label_ref (match_operand 0 "" "")) (pc)))] "ISA_HAS_DSP" - "%*bposge%1\t%0%/" - [(set_attr "type" "branch")]) +{ + if (TARGET_DSPR3 && TARGET_CB_MAYBE) + return "%*bposge%1%:\t%0"; + else + return "%*bposge%1\t%0%/"; +} + [(set_attr "type" "branch") + (set (attr "compact_form") (if_then_else (match_test "TARGET_DSPR3 + && TARGET_CB_MAYBE") + (const_string "maybe") + (const_string "never"))) + (set (attr "hazard") (if_then_else (match_test "TARGET_DSPR3 + && TARGET_CB_MAYBE") + (const_string "forbidden_slot") + (const_string "none")))]) (define_expand "mips_madd" [(set (match_operand:DI 0 "register_operand") diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index f1a1842b815..c13db20fdd9 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -5822,7 +5822,12 @@ mips_output_move (rtx dest, rtx src) /* Moves to HI are handled by special .md insns. */ if (REGNO (dest) == LO_REGNUM) - return "mtlo\t%z1"; + { + if (ISA_HAS_MULT) + return "mtlo\t%z1"; + else + return "mtlo\t%z1,$ac0"; + } if (DSP_ACC_REG_P (REGNO (dest))) { @@ -5868,7 +5873,10 @@ mips_output_move (rtx dest, rtx src) -mfix-vr4130. */ if (ISA_HAS_MACCHI) return dbl_p ? "dmacc\t%0,%.,%." : "macc\t%0,%.,%."; - return "mflo\t%0"; + if (ISA_HAS_MULT) + return "mflo\t%0"; + else + return "mflo\t%0,$ac0"; } if (DSP_ACC_REG_P (REGNO (src))) @@ -21039,7 +21047,7 @@ mips_mult_zero_zero_cost (struct mips_sim *state, bool setting) static void mips_set_fast_mult_zero_zero_p (struct mips_sim *state) { - if (TARGET_MIPS16 || !ISA_HAS_HILO) + if (TARGET_MIPS16 || (!ISA_HAS_HILO && !TARGET_DSP)) /* No MTLO or MTHI available for MIPS16. Also, when there are no HI or LO registers then there is no reason to zero them, arbitrarily choose to say that "MULT $0,$0" would be faster. */ @@ -23115,6 +23123,12 @@ mips_option_override (void) target_flags |= MASK_LOONGSON_EXT; } + if (TARGET_DSPR3) + { + TARGET_DSP = true; + TARGET_DSPR2 = true; + } + /* .eh_frame addresses should be the same width as a C pointer. Most MIPS ABIs support only one pointer size, so the assembler will usually know exactly how big an .eh_frame address is. @@ -23316,7 +23330,7 @@ mips_conditional_register_usage (void) else accessible_reg_set &= ~reg_class_contents[DSP_ACC_REGS]; - if (!ISA_HAS_HILO) + if (!ISA_HAS_HILO && !ISA_HAS_DSP) accessible_reg_set &= ~reg_class_contents[MD_REGS]; if (!TARGET_HARD_FLOAT) diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 2912287a711..b30cc7a46b3 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -538,6 +538,11 @@ struct mips_cpu_info { builtin_define ("__mips_dspr2"); \ builtin_define ("__mips_dsp_rev=2"); \ } \ + else if (TARGET_DSPR3) \ + { \ + builtin_define ("__mips_dspr3"); \ + builtin_define ("__mips_dsp_rev=3"); \ + } \ else \ builtin_define ("__mips_dsp_rev=1"); \ } \ @@ -1536,6 +1541,7 @@ struct mips_cpu_info { %{mdmx} %{mno-mdmx:-no-mdmx} \ %{mdsp} %{mno-dsp} \ %{mdspr2} %{mno-dspr2} \ +%{mdspr3} %{mno-dspr3} \ %{mmcu} %{mno-mcu} \ %{meva} %{mno-eva} \ %{mvirt} %{mno-virt} \ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 700b46c955e..516596c4345 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -2167,7 +2167,7 @@ [(set (match_operand:DI 0 "muldiv_target_operand" "=ka") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))] - "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP) && ISA_HAS_MULT" + "!TARGET_64BIT && ((!TARGET_FIX_R4000 && ISA_HAS_MULT) || ISA_HAS_DSP)" { if (ISA_HAS_DSP_MULT) return "mult\t%q0,%1,%2"; @@ -5643,7 +5643,8 @@ (unspec:GPR [(match_operand:HILO 1 "hilo_operand" "x")] UNSPEC_MFHI))] "" - { return ISA_HAS_MACCHI ? "macchi\t%0,%.,%." : "mfhi\t%0"; } + { return ISA_HAS_MACCHI ? "macchi\t%0,%.,%." : + ISA_HAS_MULT ? "mfhi\t%0" : "mfhi\t%0,$ac0"; } [(set_attr "type" "mfhi") (set_attr "mode" "")]) @@ -5656,7 +5657,12 @@ (match_operand:GPR 2 "register_operand" "l")] UNSPEC_MTHI))] "" - "mthi\t%z1" + { + if (ISA_HAS_MULT) + return "mthi\t%z1"; + else + return "mthi\t%z1, $ac0"; + } [(set_attr "type" "mthi") (set_attr "mode" "SI")]) diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index 2e647d703b4..08bcf8143ee 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -120,9 +120,13 @@ Target Var(TARGET_DSP) Use MIPS-DSP instructions. mdspr2 -Target Var(TARGET_DSPR2) Condition(MIPS_SUPPORT_DSP) +Target Var(TARGET_DSPR2) Condition({defined (MIPS_SUPPORT_DSP) && !defined (NANOMIPS_SUPPORT)}) Use MIPS-DSP REV 2 instructions. +mdspr3 +Target Var(TARGET_DSPR3) Condition({defined (MIPS_SUPPORT_DSP) && defined (NANOMIPS_SUPPORT)}) +Use MIPS-DSP Rev 3 instructions. + mdebug Target Var(TARGET_DEBUG_MODE) Undocumented Condition(MIPS_SUPPORT_LEGACY) diff --git a/gcc/testsuite/gcc.target/nanomips/dpaq_sa_l_w.c b/gcc/testsuite/gcc.target/nanomips/dpaq_sa_l_w.c new file mode 100644 index 00000000000..4fa49bdf2d4 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/dpaq_sa_l_w.c @@ -0,0 +1,51 @@ +/* { dg-do compile { target { fixed_point } } } */ +/* This test requires widening_mul */ +/* { dg-options "-mgp32 -mdspr3 -fexpensive-optimizations" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler-times "\tdpaq_sa.l.w\t\\\$ac" 3 } } */ + +_Sat long long _Fract +f1 (_Sat long _Fract x, _Sat long _Fract y, _Sat long long _Fract z) +{ + return (_Sat long long _Fract) x * y + z; +} + +_Sat long long _Fract +f2 (_Sat long _Fract x, _Sat long _Fract y, _Sat long long _Fract z) +{ + return z + (_Sat long long _Fract) y * x; +} + +_Sat long long _Fract +f3 (_Sat long _Fract x, _Sat long _Fract y, _Sat long long _Fract z) +{ + _Sat long long _Fract t = (_Sat long long _Fract) x * y; + int temp = 5; + if (temp == 5) + z = t + z; /* Need to put z at the end. GCC does not swap operands to + match the ssmadd pattern, because types are saturating. */ + return z; +} + +long long _Fract +f4 (long _Fract x, long _Fract y, long long _Fract z) +{ + return (long long _Fract) x * y + z; +} + +long long _Fract +f5 (long _Fract x, long _Fract y, long long _Fract z) +{ + return z + (long long _Fract) y * x; +} + +long long _Fract +f6 (long _Fract x, long _Fract y, long long _Fract z) +{ + long long _Fract t = (long long _Fract) x * y; + int temp = 5; + if (temp == 5) + z = t + z; /* Need to put z at the end. GCC does not swap operands to + match the ssmadd pattern, because types are saturating. */ + return z; +} diff --git a/gcc/testsuite/gcc.target/nanomips/dpsq_sa_l_w.c b/gcc/testsuite/gcc.target/nanomips/dpsq_sa_l_w.c new file mode 100644 index 00000000000..b6632f07816 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/dpsq_sa_l_w.c @@ -0,0 +1,37 @@ +/* { dg-do compile { target { fixed_point } } } */ +/* This test requires widening_mul */ +/* { dg-options "-mgp32 -mdspr3 -fexpensive-optimizations" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler-times "\tdpsq_sa.l.w\t\\\$ac" 2 } } */ + +_Sat long long _Fract +f1 (_Sat long _Fract x, _Sat long _Fract y, _Sat long long _Fract z) +{ + return z - (_Sat long long _Fract) x * y; +} + +_Sat long long _Fract +f2 (_Sat long _Fract x, _Sat long _Fract y, _Sat long long _Fract z) +{ + _Sat long long _Fract t = (_Sat long long _Fract) x * y; + int temp = 5; + if (temp == 5) + z -= t; + return z; +} + +long long _Fract +f3 (long _Fract x, long _Fract y, long long _Fract z) +{ + return z - (long long _Fract) x * y; +} + +long long _Fract +f4 (long _Fract x, long _Fract y, long long _Fract z) +{ + long long _Fract t = (long long _Fract) x * y; + int temp = 5; + if (temp == 5) + z -= t; + return z; +} diff --git a/gcc/testsuite/gcc.target/nanomips/dsp-ctrl.c b/gcc/testsuite/gcc.target/nanomips/dsp-ctrl.c new file mode 100644 index 00000000000..05df69bd9b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/dsp-ctrl.c @@ -0,0 +1,69 @@ +/* { dg-do run } */ +/* { dg-options "-mdspr3 -mgp32" } */ + +extern void abort (void); +extern void exit (int); + +void __attribute__ ((noinline)) +test1 (int i) +{ + __builtin_mips_wrdsp (i, 63); +} + +void __attribute__ ((noinline)) +test2 () +{ + long long a = 0; + volatile int tmp = __builtin_mips_extpdp (a, 3); +} + +void __attribute__ ((noinline)) +test3 (int i) +{ + long long a = 0; + volatile int tmp = __builtin_mips_extpdp (a, i); +} + +void __attribute__ ((noinline)) +test4 () +{ + long long a = 0; + int i = 0; + volatile long long tmp = __builtin_mips_mthlip (a, i); +} + +int +main () +{ + int cntl; + + /* Test 1: wrdsp */ + __builtin_mips_wrdsp (0,63); + test1 (63); + cntl = __builtin_mips_rddsp (63); + if (cntl != 63) + abort (); + + /* Test 2: extpdp */ + __builtin_mips_wrdsp (63,63); + test2 (); + cntl = __builtin_mips_rddsp (63); + if (cntl != 59) + abort (); + + /* Test 3: extpdpv */ + __builtin_mips_wrdsp (63,63); + test3 (10); + cntl = __builtin_mips_rddsp (63); + if (cntl != 52) + abort (); + + /* Test 4: mthlip */ + __builtin_mips_wrdsp (8,63); + test4 (); + cntl = __builtin_mips_rddsp (63); + if (cntl != 40) + abort (); + + exit (0); +} diff --git a/gcc/testsuite/gcc.target/nanomips/dsp-lhxs.c b/gcc/testsuite/gcc.target/nanomips/dsp-lhxs.c new file mode 100644 index 00000000000..e673d2b2491 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/dsp-lhxs.c @@ -0,0 +1,11 @@ +/* Test MIPS32 DSP LHX instruction */ +/* { dg-do compile } */ +/* { dg-options "-mgp32 -mdspr3" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +/* { dg-final { scan-assembler "\tlhxs\t" } } */ + +signed short test (signed short *a, int index) +{ + return a[index]; +} diff --git a/gcc/testsuite/gcc.target/nanomips/dsp-no-lhx.c b/gcc/testsuite/gcc.target/nanomips/dsp-no-lhx.c new file mode 100644 index 00000000000..6a82bf9a85e --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/dsp-no-lhx.c @@ -0,0 +1,11 @@ +/* Test MIPS32 DSP LHX instruction */ +/* { dg-do compile } */ +/* { dg-options "-mgp32 -mdspr3" } */ + +/* { dg-final { scan-assembler-not "\tlhx\t" } } */ +/* { dg-final { scan-assembler-not "\tlhxs\t" } } */ + +unsigned short test (unsigned short *a, int index) +{ + return a[index]; +} diff --git a/gcc/testsuite/gcc.target/nanomips/fixed-scalar-type.c b/gcc/testsuite/gcc.target/nanomips/fixed-scalar-type.c new file mode 100644 index 00000000000..8c1e8be9380 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/fixed-scalar-type.c @@ -0,0 +1,218 @@ +/* Test scalar fixed-point instructions */ +/* { dg-do compile { target { fixed_point } } } */ +/* { dg-options "-mdspr2" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler-times "\taddu\t" 10 } } */ +/* { dg-final { scan-assembler-times "\tsubu\t" 10 } } */ +/* { dg-final { scan-assembler "\taddu_s.qb\t" } } */ +/* { dg-final { scan-assembler-times "\taddu_s.ph\t" 2 } } */ +/* { dg-final { scan-assembler-times "\taddq_s.ph\t" 2 } } */ +/* { dg-final { scan-assembler-times "\taddq_s.w\t" 2 } } */ +/* { dg-final { scan-assembler "\tsubu_s.qb\t" } } */ +/* { dg-final { scan-assembler-times "\tsubu_s.ph\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tsubq_s.ph\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tsubq_s.w\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tmulq_rs.ph\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmulq_rs.w\t" 1 } } */ + +short _Fract non_sat_test1 (short _Fract a, short _Fract b) +{ + return a + b; +} + +_Fract non_sat_test2 (_Fract a, _Fract b) +{ + return a + b; +} + +long _Fract non_sat_test3 (long _Fract a, long _Fract b) +{ + return a + b; +} + +unsigned short _Fract non_sat_test4 (unsigned short _Fract a, + unsigned short _Fract b) +{ + return a + b; +} + +unsigned _Fract non_sat_test5 (unsigned _Fract a, unsigned _Fract b) +{ + return a + b; +} + +unsigned long _Fract non_sat_test6 (unsigned long _Fract a, + unsigned long _Fract b) +{ + return a + b; +} + +short _Accum non_sat_test7 (short _Accum a, short _Accum b) +{ + return a + b; +} + +_Accum non_sat_test8 (_Accum a, _Accum b) +{ + return a + b; +} + +unsigned short _Accum non_sat_test9 (unsigned short _Accum a, + unsigned short _Accum b) +{ + return a + b; +} + +unsigned _Accum non_sat_test10 (unsigned _Accum a, unsigned _Accum b) +{ + return a + b; +} + +short _Fract non_sat_test11 (short _Fract a, short _Fract b) +{ + return a - b; +} + +_Fract non_sat_test12 (_Fract a, _Fract b) +{ + return a - b; +} + +long _Fract non_sat_test13 (long _Fract a, long _Fract b) +{ + return a - b; +} + +unsigned short _Fract non_sat_test14 (unsigned short _Fract a, + unsigned short _Fract b) +{ + return a - b; +} + +unsigned _Fract non_sat_test15 (unsigned _Fract a, unsigned _Fract b) +{ + return a - b; +} + +unsigned long _Fract non_sat_test16 (unsigned long _Fract a, + unsigned long _Fract b) +{ + return a - b; +} + +short _Accum non_sat_test17 (short _Accum a, short _Accum b) +{ + return a - b; +} + +_Accum non_sat_test18 (_Accum a, _Accum b) +{ + return a - b; +} + +unsigned short _Accum non_sat_test19 (unsigned short _Accum a, + unsigned short _Accum b) +{ + return a - b; +} + +unsigned _Accum non_sat_test20 (unsigned _Accum a, unsigned _Accum b) +{ + return a - b; +} + +_Sat unsigned short _Fract test1 (_Sat unsigned short _Fract a, + _Sat unsigned short _Fract b) +{ + return a + b; +} + +_Sat unsigned _Fract test2 (_Sat unsigned _Fract a, + _Sat unsigned _Fract b) +{ + return a + b; +} + +_Sat unsigned short _Accum test3 (_Sat unsigned short _Accum a, + _Sat unsigned short _Accum b) +{ + return a + b; +} + +_Sat _Fract test4 (_Sat _Fract a, _Sat _Fract b) +{ + return a + b; +} + +_Sat long _Fract test5 (_Sat long _Fract a, _Sat long _Fract b) +{ + return a + b; +} + +_Sat short _Accum test6 (_Sat short _Accum a, _Sat short _Accum b) +{ + return a + b; +} + +_Sat _Accum test7 (_Sat _Accum a, _Sat _Accum b) +{ + return a + b; +} + +_Sat unsigned short _Fract test8 (_Sat unsigned short _Fract a, + _Sat unsigned short _Fract b) +{ + return a - b; +} + +_Sat unsigned _Fract test9 (_Sat unsigned _Fract a, + _Sat unsigned _Fract b) +{ + return a - b; +} + +_Sat unsigned short _Accum test10 (_Sat unsigned short _Accum a, + _Sat unsigned short _Accum b) +{ + return a - b; +} + +_Sat _Fract test11 (_Sat _Fract a, _Sat _Fract b) +{ + return a - b; +} + +_Sat long _Fract test12 (_Sat long _Fract a, _Sat long _Fract b) +{ + return a - b; +} + +_Sat short _Accum test13 (_Sat short _Accum a, _Sat short _Accum b) +{ + return a - b; +} + +_Sat _Accum test14 (_Sat _Accum a, _Sat _Accum b) +{ + return a - b; +} + +_Sat _Fract test15 (_Sat _Fract a, _Sat _Fract b) +{ + return a * b; +} + +_Sat long _Fract test16 (_Sat long _Fract a, _Sat long _Fract b) +{ + return a * b; +} + +_Fract test17 (_Fract a, _Fract b) +{ + return a * b; +} + +long _Fract test18 (long _Fract a, long _Fract b) +{ + return a * b; +} diff --git a/gcc/testsuite/gcc.target/nanomips/fixed-vector-type.c b/gcc/testsuite/gcc.target/nanomips/fixed-vector-type.c new file mode 100644 index 00000000000..d493372682e --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/fixed-vector-type.c @@ -0,0 +1,133 @@ +/* Test vector fixed-point instructions */ +/* { dg-do compile { target { fixed_point } } } */ +/* { dg-options "-mdspr2" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler-times "\taddq_s.ph\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tsubq_s.ph\t" 2 } } */ +/* { dg-final { scan-assembler-times "\taddu_s.qb\t" 1 } } */ +/* { dg-final { scan-assembler-times "\taddu_s.ph\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tsubu_s.qb\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tsubu_s.ph\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tmulq_rs.ph\t" 1 } } */ + +typedef _Sat unsigned short _Fract sat_v4uqq __attribute__ ((vector_size(4))); +typedef _Sat unsigned _Fract sat_v2uhq __attribute__ ((vector_size(4))); +typedef _Sat unsigned short _Accum sat_v2uha __attribute__ ((vector_size(4))); +typedef _Sat _Fract sat_v2hq __attribute__ ((vector_size(4))); +typedef _Sat short _Accum sat_v2ha __attribute__ ((vector_size(4))); + +typedef unsigned short _Fract v4uqq __attribute__ ((vector_size(4))); +typedef unsigned _Fract v2uhq __attribute__ ((vector_size(4))); +typedef unsigned short _Accum v2uha __attribute__ ((vector_size(4))); +typedef _Fract v2hq __attribute__ ((vector_size(4))); +typedef short _Accum v2ha __attribute__ ((vector_size(4))); + +sat_v2hq test1 (sat_v2hq a, sat_v2hq b) +{ + return a + b; +} + +sat_v2ha test2 (sat_v2ha a, sat_v2ha b) +{ + return a + b; +} + +sat_v2hq test3 (sat_v2hq a, sat_v2hq b) +{ + return a - b; +} + +sat_v2ha test4 (sat_v2ha a, sat_v2ha b) +{ + return a - b; +} + +sat_v4uqq test5 (sat_v4uqq a, sat_v4uqq b) +{ + return a + b; +} + +sat_v2uhq test6 (sat_v2uhq a, sat_v2uhq b) +{ + return a + b; +} + +sat_v2uha test7 (sat_v2uha a, sat_v2uha b) +{ + return a + b; +} + +sat_v4uqq test8 (sat_v4uqq a, sat_v4uqq b) +{ + return a - b; +} + +sat_v2uhq test9 (sat_v2uhq a, sat_v2uhq b) +{ + return a - b; +} + +sat_v2uha test10 (sat_v2uha a, sat_v2uha b) +{ + return a - b; +} + +sat_v2hq test11 (sat_v2hq a, sat_v2hq b) +{ + return a * b; +} + +v2hq test12 (v2hq a, v2hq b) +{ + return a + b; +} + +v2hq test13 (v2hq a, v2hq b) +{ + return a - b; +} + +v2hq test14 (v2hq a, v2hq b) +{ + return a * b; +} + +v2ha test15 (v2ha a, v2ha b) +{ + return a + b; +} + +v2ha test16 (v2ha a, v2ha b) +{ + return a - b; +} + +v4uqq test17 (v4uqq a, v4uqq b) +{ + return a + b; +} + +v4uqq test18 (v4uqq a, v4uqq b) +{ + return a - b; +} + +v2uhq test19 (v2uhq a, v2uhq b) +{ + return a + b; +} + +v2uhq test20 (v2uhq a, v2uhq b) +{ + return a - b; +} + +v2uha test21 (v2uha a, v2uha b) +{ + return a + b; +} + +v2uha test22 (v2uha a, v2uha b) +{ + return a - b; +} diff --git a/gcc/testsuite/gcc.target/nanomips/madd-4.c b/gcc/testsuite/gcc.target/nanomips/madd-4.c new file mode 100644 index 00000000000..6a31b79f16a --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/madd-4.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* This test requires widening_mul */ +/* { dg-options "-mdspr3 -mgp32 -fexpensive-optimizations" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler-times "\tmadd\t\\\$ac" 3 } } */ + +long long +f1 (int x, int y, long long z) +{ + return (long long) x * y + z; +} + +long long +f2 (int x, int y, long long z) +{ + return z + (long long) y * x; +} + +long long +f3 (int x, int y, long long z) +{ + long long t = (long long) x * y; + int temp = 5; + if (temp == 5) + z += t; + return z; +} diff --git a/gcc/testsuite/gcc.target/nanomips/maddu-3.c b/gcc/testsuite/gcc.target/nanomips/maddu-3.c new file mode 100644 index 00000000000..7ec312ce743 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/maddu-3.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* This test requires widening_mul */ +/* { dg-options "(HAS_MADD) -mgp32 -fexpensive-optimizations -mdspr3" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler-times "\tmaddu\t" 3 } } */ + +typedef unsigned int ui; +typedef unsigned long long ull; + +ull +f1 (ui x, ui y, ull z) +{ + return (ull) x * y + z; +} + +ull +f2 (ui x, ui y, ull z) +{ + return z + (ull) y * x; +} + +ull +f3 (ui x, ui y, ull z) +{ + ull t = (ull) x * y; + int temp = 5; + if (temp == 5) + z += t; + return z; +} diff --git a/gcc/testsuite/gcc.target/nanomips/maddu-4.c b/gcc/testsuite/gcc.target/nanomips/maddu-4.c new file mode 100644 index 00000000000..89a91fb6a12 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/maddu-4.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* This test requires widening_mul */ +/* { dg-options "-mdspr3 -mgp32 -fexpensive-optimizations" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler-times "\tmaddu\t\\\$ac" 3 } } */ + +typedef unsigned int ui; +typedef unsigned long long ull; + +ull +f1 (ui x, ui y, ull z) +{ + return (ull) x * y + z; +} + +ull +f2 (ui x, ui y, ull z) +{ + return z + (ull) y * x; +} + +ull +f3 (ui x, ui y, ull z) +{ + ull t = (ull) x * y; + int temp = 5; + if (temp == 5) + z += t; + return z; +} diff --git a/gcc/testsuite/gcc.target/nanomips/mips-prepend-1.c b/gcc/testsuite/gcc.target/nanomips/mips-prepend-1.c new file mode 100644 index 00000000000..cab88637a76 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/mips-prepend-1.c @@ -0,0 +1,8 @@ +/* { dg-options "-mdspr3" } */ +/* { dg-final { scan-assembler "prepend\[^\n\]*,10" } } */ + +int +foo (int x, int y) +{ + return __builtin_mips_prepend (x, y, 42); +} diff --git a/gcc/testsuite/gcc.target/nanomips/mips32-dsp-run.c b/gcc/testsuite/gcc.target/nanomips/mips32-dsp-run.c new file mode 100644 index 00000000000..dd189bf99cf --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/mips32-dsp-run.c @@ -0,0 +1,1063 @@ +/* Test MIPS32 DSP instructions */ +/* { dg-do run } */ +/* { dg-options "-march=32r6 -mdspr3 (REQUIRES_STDLIB)" } */ + +#include +#include + +typedef signed char v4i8 __attribute__ ((vector_size(4))); +typedef short v2q15 __attribute__ ((vector_size(4))); + +typedef int q31; +typedef int i32; +typedef unsigned int ui32; +typedef long long a64; + +void test_MIPS_DSP (void); + +char array[100]; +int little_endian; + +int main () +{ + int i; + + union { long long ll; int i[2]; } endianness_test; + endianness_test.ll = 1; + little_endian = endianness_test.i[0]; + + for (i = 0; i < 100; i++) + array[i] = i; + + test_MIPS_DSP (); + + exit (0); +} + +v2q15 add_v2q15 (v2q15 a, v2q15 b) +{ + return __builtin_mips_addq_ph (a, b); +} + +v4i8 add_v4i8 (v4i8 a, v4i8 b) +{ + return __builtin_mips_addu_qb (a, b); +} + +v2q15 sub_v2q15 (v2q15 a, v2q15 b) +{ + return __builtin_mips_subq_ph (a, b); +} + +v4i8 sub_v4i8 (v4i8 a, v4i8 b) +{ + return __builtin_mips_subu_qb (a, b); +} + +void test_MIPS_DSP () +{ + v4i8 v4i8_a,v4i8_b,v4i8_c,v4i8_r,v4i8_s; + v2q15 v2q15_a,v2q15_b,v2q15_c,v2q15_r,v2q15_s; + q31 q31_a,q31_b,q31_c,q31_r,q31_s; + /* To protect the multiplication-related tests from being optimized + at compile time. */ + volatile i32 i32_a,i32_b,i32_c,i32_r,i32_s; + volatile ui32 ui32_a,ui32_b,ui32_c; + a64 a64_a,a64_b,a64_c,a64_r,a64_s; + + void *ptr_a; + int r,s; + long long lr,ls; + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + v2q15_s = (v2q15) {0x81bd, 0x6789}; + v2q15_r = add_v2q15 (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + v2q15_s = (v2q15) {0x7fff, 0x6789}; + v2q15_r = __builtin_mips_addq_s_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x70000000; + q31_b = 0x71234567; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_addq_s_w (q31_a, q31_b); + if (q31_r != q31_s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0xff, 0x89, 0x11, 0x11}; + v4i8_s = (v4i8) {0xf1, 0xbd, 0x67, 0x89}; + v4i8_r = add_v4i8 (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0xff, 0x89, 0x11, 0x11}; + v4i8_s = (v4i8) {0xff, 0xbd, 0x67, 0x89}; + v4i8_r = __builtin_mips_addu_s_qb (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + v2q15_s = (v2q15) {0xa2ab, 0x4567}; + v2q15_r = sub_v2q15 (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x8000, 0x5678}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + v2q15_s = (v2q15) {0x8000, 0x4567}; + v2q15_r = __builtin_mips_subq_s_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x70000000; + q31_b = 0x71234567; + q31_s = 0xfedcba99; + q31_r = __builtin_mips_subq_s_w (q31_a, q31_b); + if (q31_r != q31_s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0xff, 0x89, 0x11, 0x11}; + v4i8_s = (v4i8) {0xf3, 0xab, 0x45, 0x67}; + v4i8_r = sub_v4i8 (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0xff, 0x89, 0x11, 0x11}; + v4i8_s = (v4i8) {0x0, 0x0, 0x45, 0x67}; + v4i8_r = __builtin_mips_subu_s_qb (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + i32_a = 0xf5678900; + i32_b = 0x7abcdef0; + i32_s = 0x702467f0; + i32_r = __builtin_mips_addsc (i32_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_a = 0x75678900; + i32_b = 0x7abcdef0; + i32_s = 0xf02467f1; + i32_r = __builtin_mips_addwc (i32_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_a = 0; + i32_b = 0x00000901; + i32_s = 9; + i32_r = __builtin_mips_modsub (i32_a, i32_b); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + i32_s = 0x1f4; + i32_r = __builtin_mips_raddu_w_qb (v4i8_a); + if (i32_r != i32_s) + abort (); + + v2q15_a = (v2q15) {0x8000, 0x8134}; + v2q15_s = (v2q15) {0x7fff, 0x7ecc}; + v2q15_r = __builtin_mips_absq_s_ph (v2q15_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = (q31) 0x80000000; + q31_s = (q31) 0x7fffffff; + q31_r = __builtin_mips_absq_s_w (q31_a); + if (q31_r != q31_s) + abort (); + + v2q15_a = (v2q15) {0x9999, 0x5612}; + v2q15_b = (v2q15) {0x5612, 0x3333}; + if (little_endian) + v4i8_s = (v4i8) {0x56, 0x33, 0x99, 0x56}; + else + v4i8_s = (v4i8) {0x99, 0x56, 0x56, 0x33}; + v4i8_r = __builtin_mips_precrq_qb_ph (v2q15_a, v2q15_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + q31_a = 0x12348678; + q31_b = 0x44445555; + if (little_endian) + v2q15_s = (v2q15) {0x4444, 0x1234}; + else + v2q15_s = (v2q15) {0x1234, 0x4444}; + v2q15_r = __builtin_mips_precrq_ph_w (q31_a, q31_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x12348678; + q31_b = 0x44445555; + if (little_endian) + v2q15_s = (v2q15) {0x4444, 0x1235}; + else + v2q15_s = (v2q15) {0x1235, 0x4444}; + v2q15_r = __builtin_mips_precrq_rs_ph_w (q31_a, q31_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x9999, 0x5612}; + v2q15_b = (v2q15) {0x5612, 0x3333}; + if (little_endian) + v4i8_s = (v4i8) {0xac, 0x66, 0x00, 0xac}; + else + v4i8_s = (v4i8) {0x00, 0xac, 0xac, 0x66}; + v4i8_r = __builtin_mips_precrqu_s_qb_ph (v2q15_a, v2q15_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x3589, 0x4444}; + if (little_endian) + q31_s = 0x44440000; + else + q31_s = 0x35890000; + q31_r = __builtin_mips_preceq_w_phl (v2q15_a); + if (q31_r != q31_s) + abort (); + + v2q15_a = (v2q15) {0x3589, 0x4444}; + if (little_endian) + q31_s = 0x35890000; + else + q31_s = 0x44440000; + q31_r = __builtin_mips_preceq_w_phr (v2q15_a); + if (q31_r != q31_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x2b00, 0x1980}; + else + v2q15_s = (v2q15) {0x0900, 0x2b00}; + v2q15_r = __builtin_mips_precequ_ph_qbl (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x0900, 0x2b00}; + else + v2q15_s = (v2q15) {0x2b00, 0x1980}; + v2q15_r = __builtin_mips_precequ_ph_qbr (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x2b00, 0x1980}; + else + v2q15_s = (v2q15) {0x0900, 0x2b00}; + v2q15_r = __builtin_mips_precequ_ph_qbla (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x0900, 0x2b00}; + else + v2q15_s = (v2q15) {0x2b00, 0x1980}; + v2q15_r = __builtin_mips_precequ_ph_qbra (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x56, 0x33}; + else + v2q15_s = (v2q15) {0x12, 0x56}; + v2q15_r = __builtin_mips_preceu_ph_qbl (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x12, 0x56}; + else + v2q15_s = (v2q15) {0x56, 0x33}; + v2q15_r = __builtin_mips_preceu_ph_qbr (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x99, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x99, 0x33}; + else + v2q15_s = (v2q15) {0x12, 0x56}; + v2q15_r = __builtin_mips_preceu_ph_qbla (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x99, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x12, 0x56}; + else + v2q15_s = (v2q15) {0x99, 0x33}; + v2q15_r = __builtin_mips_preceu_ph_qbra (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_s = (v4i8) {0xc8, 0xd0, 0x58, 0xe0}; + v4i8_r = __builtin_mips_shll_qb (v4i8_a, 2); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + i32_b = 1; + v4i8_s = (v4i8) {0xe4, 0x68, 0xac, 0xf0}; + v4i8_r = __builtin_mips_shll_qb (v4i8_a, i32_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_s = (v2q15) {0x48d0, 0x59e0}; + v2q15_r = __builtin_mips_shll_ph (v2q15_a, 2); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + i32_b = 1; + v2q15_s = (v2q15) {0x2468, 0xacf0}; + v2q15_r = __builtin_mips_shll_ph (v2q15_a, i32_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_s = (v2q15) {0x48d0, 0x7fff}; + v2q15_r = __builtin_mips_shll_s_ph (v2q15_a, 2); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + i32_b = 1; + v2q15_s = (v2q15) {0x2468, 0x7fff}; + v2q15_r = __builtin_mips_shll_s_ph (v2q15_a, i32_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x70000000; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_shll_s_w (q31_a, 2); + if (q31_r != q31_s) + abort (); + + q31_a = 0x70000000; + i32_b = 1; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_shll_s_w (q31_a, i32_b); + if (q31_r != q31_s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_s = (v4i8) {0x3c, 0xd, 0x15, 0x1e}; + v4i8_r = __builtin_mips_shrl_qb (v4i8_a, 2); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + i32_b = 1; + v4i8_s = (v4i8) {0x79, 0x1a, 0x2b, 0x3c}; + v4i8_r = __builtin_mips_shrl_qb (v4i8_a, i32_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_s = (v2q15) {0x48d, 0x159e}; + v2q15_r = __builtin_mips_shra_ph (v2q15_a, 2); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + i32_b = 1; + v2q15_s = (v2q15) {0x91a, 0x2b3c}; + v2q15_r = __builtin_mips_shra_ph (v2q15_a, i32_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_s = (v2q15) {0x48d, 0x159e}; + v2q15_r = __builtin_mips_shra_r_ph (v2q15_a, 2); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + i32_b = 3; + v2q15_s = (v2q15) {0x247, 0xacf}; + v2q15_r = __builtin_mips_shra_r_ph (v2q15_a, i32_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x70000000; + q31_s = 0x1c000000; + q31_r = __builtin_mips_shra_r_w (q31_a, 2); + if (q31_r != q31_s) + abort (); + + q31_a = 0x70000004; + i32_b = 3; + q31_s = 0x0e000001; + q31_r = __builtin_mips_shra_r_w (q31_a, i32_b); + if (q31_r != q31_s) + abort (); + + v4i8_a = (v4i8) {0x1, 0x2, 0x3, 0x4}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + if (little_endian) + v2q15_s = (v2q15) {0xffff, 0x4444}; + else + v2q15_s = (v2q15) {0x6f89, 0x2222}; + v2q15_r = __builtin_mips_muleu_s_ph_qbl (v4i8_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x1, 0x2, 0x3, 0x4}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + if (little_endian) + v2q15_s = (v2q15) {0x6f89, 0x2222}; + else + v2q15_s = (v2q15) {0xffff, 0x4444}; + v2q15_r = __builtin_mips_muleu_s_ph_qbr (v4i8_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + v2q15_s = (v2q15) {0x0fdd, 0x0b87}; + v2q15_r = __builtin_mips_mulq_rs_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x8000, 0x8000}; + v2q15_b = (v2q15) {0x8000, 0x8000}; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_muleq_s_w_phl (v2q15_a, v2q15_b); + if (q31_r != q31_s) + abort (); + + v2q15_a = (v2q15) {0x8000, 0x8000}; + v2q15_b = (v2q15) {0x8000, 0x8000}; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_muleq_s_w_phr (v2q15_a, v2q15_b); + if (q31_r != q31_s) + abort (); + +#ifndef __mips64 + a64_a = 0x22221111; + v4i8_b = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_c = (v4i8) {0xaa, 0x89, 0x11, 0x34}; + if (little_endian) + a64_s = 0x22222f27; + else + a64_s = 0x222238d9; + a64_r = __builtin_mips_dpau_h_qbl (a64_a, v4i8_b, v4i8_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x22221111; + v4i8_b = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_c = (v4i8) {0xaa, 0x89, 0x11, 0x34}; + if (little_endian) + a64_s = 0x222238d9; + else + a64_s = 0x22222f27; + a64_r = __builtin_mips_dpau_h_qbr (a64_a, v4i8_b, v4i8_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x22221111; + v4i8_b = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_c = (v4i8) {0xaa, 0x89, 0x11, 0x34}; + if (little_endian) + a64_s = 0x2221f2fb; + else + a64_s = 0x2221e949; + a64_r = __builtin_mips_dpsu_h_qbl (a64_a, v4i8_b, v4i8_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x22221111; + v4i8_b = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_c = (v4i8) {0xaa, 0x89, 0x11, 0x34}; + if (little_endian) + a64_s = 0x2221e949; + else + a64_s = 0x2221f2fb; + a64_r = __builtin_mips_dpsu_h_qbr (a64_a, v4i8_b, v4i8_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x5678}; + v2q15_c = (v2q15) {0x8000, 0x1111}; + a64_s = 0x8b877d00; + a64_r = __builtin_mips_dpaq_s_w_ph (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x5678}; + v2q15_c = (v2q15) {0x8000, 0x1111}; + a64_s = 0xffffffff7478a522LL; + a64_r = __builtin_mips_dpsq_s_w_ph (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x5678}; + v2q15_c = (v2q15) {0x8000, 0x1111}; + if (little_endian) + a64_s = 0xffffffff8b877d02LL; + else + a64_s = 0x7478a520; + a64_r = __builtin_mips_mulsaq_s_w_ph (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + q31_b = 0x80000000; + q31_c = 0x80000000; + a64_s = 0x7fffffffffffffffLL; + a64_r = __builtin_mips_dpaq_sa_l_w (a64_a, q31_b, q31_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + q31_b = 0x80000000; + q31_c = 0x80000000; + a64_s = 0x8000000000001112LL; + a64_r = __builtin_mips_dpsq_sa_l_w (a64_a, q31_b, q31_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x1}; + v2q15_c = (v2q15) {0x8000, 0x2}; + if (little_endian) + a64_s = 0x1115; + else + a64_s = 0x80001110; + a64_r = __builtin_mips_maq_s_w_phl (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x1}; + v2q15_c = (v2q15) {0x8000, 0x2}; + if (little_endian) + a64_s = 0x80001110; + else + a64_s = 0x1115; + a64_r = __builtin_mips_maq_s_w_phr (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x1}; + v2q15_c = (v2q15) {0x8000, 0x2}; + if (little_endian) + a64_s = 0x1115; + else + a64_s = 0x7fffffff; + a64_r = __builtin_mips_maq_sa_w_phl (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x1}; + v2q15_c = (v2q15) {0x8000, 0x2}; + if (little_endian) + a64_s = 0x7fffffff; + else + a64_s = 0x1115; + a64_r = __builtin_mips_maq_sa_w_phr (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); +#endif + + i32_a = 0x12345678; + i32_s = 0x00001e6a; + i32_r = __builtin_mips_bitrev (i32_a); + if (i32_r != i32_s) + abort (); + + i32_a = 0x00000208; // pos is 8, size is 4 + __builtin_mips_wrdsp (i32_a, 31); + i32_a = 0x12345678; + i32_b = 0x87654321; + i32_s = 0x12345178; + i32_r = __builtin_mips_insv (i32_a, i32_b); + if (i32_r != i32_s) + abort (); + + v4i8_s = (v4i8) {1, 1, 1, 1}; + v4i8_r = __builtin_mips_repl_qb (1); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + i32_a = 99; + v4i8_s = (v4i8) {99, 99, 99, 99}; + v4i8_r = __builtin_mips_repl_qb (i32_a); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_s = (v2q15) {30, 30}; + v2q15_r = __builtin_mips_repl_ph (30); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + i32_a = 0x5612; + v2q15_s = (v2q15) {0x5612, 0x5612}; + v2q15_r = __builtin_mips_repl_ph (i32_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x03000000; + else + i32_s = 0x0c000000; + __builtin_mips_cmpu_eq_qb (v4i8_a, v4i8_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x04000000; + else + i32_s = 0x02000000; + __builtin_mips_cmpu_lt_qb (v4i8_a, v4i8_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x07000000; + else + i32_s = 0x0e000000; + __builtin_mips_cmpu_le_qb (v4i8_a, v4i8_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x3; + else + i32_s = 0xc; + i32_r=__builtin_mips_cmpgu_eq_qb (v4i8_a, v4i8_b); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x4; + else + i32_s = 0x2; + i32_r = __builtin_mips_cmpgu_lt_qb (v4i8_a, v4i8_b); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x7; + else + i32_s = 0xe; + i32_r = __builtin_mips_cmpgu_le_qb (v4i8_a, v4i8_b); + if (i32_r != i32_s) + abort (); + + __builtin_mips_wrdsp (0,31); // Clear all condition code bits. + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x1234, 0x7856}; + if (little_endian) + i32_s = 0x01000000; + else + i32_s = 0x02000000; + __builtin_mips_cmp_eq_ph (v2q15_a, v2q15_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x1234, 0x7856}; + if (little_endian) + i32_s = 0x02000000; + else + i32_s = 0x01000000; + __builtin_mips_cmp_lt_ph (v2q15_a, v2q15_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x1234, 0x7856}; + i32_s = 0x03000000; + __builtin_mips_cmp_le_ph (v2q15_a, v2q15_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + i32_a = 0x0a000000; // cc: 0000 1010 + __builtin_mips_wrdsp (i32_a, 31); + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x21, 0x43, 0x65, 0x87}; + if (little_endian) + v4i8_s = (v4i8) {0x21, 0x34, 0x65, 0x78}; + else + v4i8_s = (v4i8) {0x12, 0x43, 0x56, 0x87}; + v4i8_r = __builtin_mips_pick_qb (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + i32_a = 0x02000000; // cc: 0000 0010 + __builtin_mips_wrdsp (i32_a, 31); + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x2143, 0x6587}; + if (little_endian) + v2q15_s = (v2q15) {0x2143, 0x5678}; + else + v2q15_s = (v2q15) {0x1234, 0x6587}; + v2q15_r = __builtin_mips_pick_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x1234, 0x7856}; + if (little_endian) + v2q15_s = (v2q15) {0x7856, 0x1234}; + else + v2q15_s = (v2q15) {0x5678, 0x1234}; + v2q15_r = __builtin_mips_packrl_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + +#ifndef __mips64 + a64_a = 0x1234567887654321LL; + i32_s = 0x88765432; + i32_r = __builtin_mips_extr_w (a64_a, 4); + if (i32_r != i32_s) + abort (); + + a64_a = 0x1234567887658321LL; + i32_s = 0x56788766; + i32_r = __builtin_mips_extr_r_w (a64_a, 16); + if (i32_r != i32_s) + abort (); + + a64_a = 0x12345677fffffff8LL; + i32_s = 0x7fffffff; + i32_r = __builtin_mips_extr_rs_w (a64_a, 4); + if (i32_r != i32_s) + abort (); + + a64_a = 0x1234567887658321LL; + i32_s = 0x7fff; + i32_r = __builtin_mips_extr_s_h (a64_a, 16); + if (i32_r != i32_s) + abort (); + + a64_a = 0x0000007887658321LL; + i32_b = 24; + i32_s = 0x7887; + i32_r = __builtin_mips_extr_s_h (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + a64_a = 0x1234567887654321LL; + i32_b = 4; + i32_s = 0x88765432; + i32_r = __builtin_mips_extr_w (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + a64_a = 0x1234567887658321LL; + i32_b = 16; + i32_s = 0x56788766; + i32_r = __builtin_mips_extr_r_w (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + a64_a = 0x12345677fffffff8LL; + i32_b = 4; + i32_s = 0x7fffffff; + i32_r = __builtin_mips_extr_rs_w (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_a = 0x0000021f; // pos is 31 + __builtin_mips_wrdsp (i32_a, 31); + a64_a = 0x1234567887654321LL; + i32_s = 8; + i32_r = __builtin_mips_extp (a64_a, 3); // extract 4 bits + if (i32_r != i32_s) + abort (); + + i32_a = 0x0000021f; // pos is 31 + __builtin_mips_wrdsp (i32_a, 31); + a64_a = 0x1234567887654321LL; + i32_b = 7; // size is 8. NOTE!! we should use 7 + i32_s = 0x87; + i32_r = __builtin_mips_extp (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_a = 0x0000021f; // pos is 31 + __builtin_mips_wrdsp (i32_a, 31); + a64_a = 0x1234567887654321LL; + i32_s = 8; + i32_r = __builtin_mips_extpdp (a64_a, 3); // extract 4 bits + if (i32_r != i32_s) + abort (); + + i32_s = 0x0000021b; // pos is 27 + i32_r = __builtin_mips_rddsp (31); + if (i32_r != i32_s) + abort (); + + i32_a = 0x0000021f; // pos is 31 + __builtin_mips_wrdsp (i32_a, 31); + a64_a = 0x1234567887654321LL; + i32_b = 11; // size is 12. NOTE!!! We should use 11 + i32_s = 0x876; + i32_r = __builtin_mips_extpdp (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_s = 0x00000213; // pos is 19 + i32_r = __builtin_mips_rddsp (31); + if (i32_r != i32_s) + abort (); + + a64_a = 0x1234567887654321LL; + a64_s = 0x0012345678876543LL; + a64_r = __builtin_mips_shilo (a64_a, 8); + if (a64_r != a64_s) + abort (); + + a64_a = 0x1234567887654321LL; + i32_b = -16; + a64_s = 0x5678876543210000LL; + a64_r = __builtin_mips_shilo (a64_a, i32_b); + if (a64_r != a64_s) + abort (); + + i32_a = 0x0; + __builtin_mips_wrdsp (i32_a, 31); + a64_a = 0x1234567887654321LL; + i32_b = 0x11112222; + a64_s = 0x8765432111112222LL; + a64_r = __builtin_mips_mthlip (a64_a, i32_b); + if (a64_r != a64_s) + abort (); + i32_s = 32; + i32_r = __builtin_mips_rddsp (31); + if (i32_r != i32_s) + abort (); +#endif + + i32_a = 0x1357a468; + __builtin_mips_wrdsp (i32_a, 63); + i32_s = 0x03572428; + i32_r = __builtin_mips_rddsp (63); + if (i32_r != i32_s) + abort (); + + ptr_a = &array; + i32_b = 37; + i32_s = 37; + i32_r = __builtin_mips_lbux (ptr_a, i32_b); + if (i32_r != i32_s) + abort (); + + ptr_a = &array; + i32_b = 38; + if (little_endian) + i32_s = 0x2726; + else + i32_s = 0x2627; + i32_r = __builtin_mips_lhx (ptr_a, i32_b); + if (i32_r != i32_s) + abort (); + + ptr_a = &array; + i32_b = 40; + if (little_endian) + i32_s = 0x2b2a2928; + else + i32_s = 0x28292a2b; + i32_r = __builtin_mips_lwx (ptr_a, i32_b); + if (i32_r != i32_s) + abort (); + +/* i32_a = 0x00000220; // pos is 32, size is 4 + __builtin_mips_wrdsp (i32_a, 63); + i32_s = 1; + i32_r = __builtin_mips_bposge32 (); + if (i32_r != i32_s) + abort (); +*/ +#ifndef __mips64 + a64_a = 0x12345678; + i32_b = 0x80000000; + i32_c = 0x11112222; + a64_s = 0xF7776EEF12345678LL; + a64_r = __builtin_mips_madd (a64_a, i32_b, i32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + ui32_b = 0x80000000; + ui32_c = 0x11112222; + a64_s = 0x0888911112345678LL; + a64_r = __builtin_mips_maddu (a64_a, ui32_b, ui32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + i32_b = 0x80000000; + i32_c = 0x11112222; + a64_s = 0x0888911112345678LL; + a64_r = __builtin_mips_msub (a64_a, i32_b, i32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + ui32_b = 0x80000000; + ui32_c = 0x11112222; + a64_s = 0xF7776EEF12345678LL; + a64_r = __builtin_mips_msubu (a64_a, ui32_b, ui32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + i32_a = 0x80000000; + i32_b = 0x11112222; + a64_s = 0xF7776EEF00000000LL; + a64_r = __builtin_mips_mult (i32_a, i32_b); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + ui32_a = 0x80000000; + ui32_b = 0x11112222; + a64_s = 0x888911100000000LL; + a64_r = __builtin_mips_multu (ui32_a, ui32_b); + if (a64_r != a64_s) + abort (); +#endif +} + diff --git a/gcc/testsuite/gcc.target/nanomips/mips32-dspr2.c b/gcc/testsuite/gcc.target/nanomips/mips32-dspr2.c new file mode 100644 index 00000000000..260936bf9ef --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/mips32-dspr2.c @@ -0,0 +1,541 @@ +/* Test MIPS32 DSP REV 2 instructions */ +/* { dg-do run } */ +/* { dg-options "-mdspr3" } */ + +typedef signed char v4q7 __attribute__ ((vector_size(4))); +typedef signed char v4i8 __attribute__ ((vector_size(4))); +typedef short v2q15 __attribute__ ((vector_size(4))); +typedef short v2i16 __attribute__ ((vector_size(4))); +typedef int q31; +typedef int i32; +typedef unsigned int ui32; +typedef long long a64; + +void abort (void); + +void test_MIPS_DSPR2 (void); + +int little_endian; + +int main () +{ + union { long long ll; int i[2]; } endianness_test; + endianness_test.ll = 1; + little_endian = endianness_test.i[0]; + + test_MIPS_DSPR2 (); + + return 0; +} + +void test_MIPS_DSPR2 () +{ + v4q7 v4q7_a,v4q7_b,v4q7_c,v4q7_r,v4q7_s; + v4i8 v4i8_a,v4i8_b,v4i8_c,v4i8_r,v4i8_s; + v2q15 v2q15_a,v2q15_b,v2q15_c,v2q15_r,v2q15_s; + v2i16 v2i16_a,v2i16_b,v2i16_c,v2i16_r,v2i16_s; + q31 q31_a,q31_b,q31_c,q31_r,q31_s; + i32 i32_a,i32_b,i32_c,i32_r,i32_s; + ui32 ui32_a,ui32_b,ui32_c,ui32_r,ui32_s; + a64 a64_a,a64_b,a64_c,a64_r,a64_s; + + int r,s; + + v4q7_a = (v4i8) {0x81, 0xff, 0x80, 0x23}; + v4q7_s = (v4i8) {0x7f, 0x01, 0x7f, 0x23}; + v4q7_r = __builtin_mips_absq_s_qb (v4q7_a); + r = (int) v4q7_r; + s = (int) v4q7_s; + if (r != s) + abort (); + + v2i16_a = (v2i16) {0xffff, 0x2468}; + v2i16_b = (v2i16) {0x1234, 0x1111}; + v2i16_s = (v2i16) {0x1233, 0x3579}; + v2i16_r = __builtin_mips_addu_ph (v2i16_a, v2i16_b); + r = (int) v2i16_r; + s = (int) v2i16_s; + if (r != s) + abort (); + + v2i16_a = (v2i16) {0xffff, 0x2468}; + v2i16_b = (v2i16) {0x1234, 0x1111}; + v2i16_s = (v2i16) {0xffff, 0x3579}; + v2i16_r = __builtin_mips_addu_s_ph (v2i16_a, v2i16_b); + r = (int) v2i16_r; + s = (int) v2i16_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x11, 0x22, 0x33, 0xff}; + v4i8_b = (v4i8) {0x11, 0x33, 0x99, 0xff}; + v4i8_s = (v4i8) {0x11, 0x2a, 0x66, 0xff}; + v4i8_r = __builtin_mips_adduh_qb (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x11, 0x22, 0x33, 0xff}; + v4i8_b = (v4i8) {0x11, 0x33, 0x99, 0xff}; + v4i8_s = (v4i8) {0x11, 0x2b, 0x66, 0xff}; + v4i8_r = __builtin_mips_adduh_r_qb (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + i32_a = 0x12345678; + i32_b = 0x87654321; + i32_s = 0x56784321; + i32_r = __builtin_mips_append (i32_a, i32_b, 16); + if (i32_r != i32_s) + abort (); + + i32_a = 0x12345678; + i32_b = 0x87654321; + i32_s = 0x78876543; + i32_r = __builtin_mips_balign (i32_a, i32_b, 3); + if (i32_r != i32_s) + abort (); + + __builtin_mips_wrdsp (0, 63); + v4i8_a = (v4i8) {0x11, 0x22, 0x33, 0x44}; + v4i8_b = (v4i8) {0x11, 0x33, 0x33, 0x44}; + if (little_endian) + i32_s = 0xd; + else + i32_s = 0xb; + i32_r = __builtin_mips_cmpgdu_eq_qb (v4i8_a, v4i8_b); + if (i32_r != i32_s) + abort (); + i32_r = __builtin_mips_rddsp (16); + if (little_endian) + i32_s = 0x0d000000; + else + i32_s = 0x0b000000; + if (i32_r != i32_s) + abort (); + + __builtin_mips_wrdsp (0, 63); + v4i8_a = (v4i8) {0x11, 0x22, 0x33, 0x44}; + v4i8_b = (v4i8) {0x11, 0x33, 0x33, 0x44}; + if (little_endian) + i32_s = 0x2; + else + i32_s = 0x4; + i32_r = __builtin_mips_cmpgdu_lt_qb (v4i8_a, v4i8_b); + if (i32_r != i32_s) + abort (); + i32_r = __builtin_mips_rddsp (16); + if (little_endian) + i32_s = 0x02000000; + else + i32_s = 0x04000000; + if (i32_r != i32_s) + abort (); + + __builtin_mips_wrdsp (0, 63); + v4i8_a = (v4i8) {0x11, 0x22, 0x33, 0x54}; + v4i8_b = (v4i8) {0x11, 0x33, 0x33, 0x44}; + if (little_endian) + i32_s = 0x7; + else + i32_s = 0xe; + i32_r = __builtin_mips_cmpgdu_le_qb (v4i8_a, v4i8_b); + if (i32_r != i32_s) + abort (); + i32_r = __builtin_mips_rddsp (16); + if (little_endian) + i32_s = 0x07000000; + else + i32_s = 0x0e000000; + if (i32_r != i32_s) + abort (); + +#ifndef __mips64 + a64_a = 0x12345678; + v2i16_b = (v2i16) {0xffff, 0x1555}; + v2i16_c = (v2i16) {0x1234, 0x3322}; + a64_s = 0x1677088e; + a64_r = __builtin_mips_dpa_w_ph (a64_a, v2i16_b, v2i16_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + v2i16_b = (v2i16) {0xffff, 0x1555}; + v2i16_c = (v2i16) {0x1234, 0x3322}; + a64_s = 0x0df1a462; + a64_r = __builtin_mips_dps_w_ph (a64_a, v2i16_b, v2i16_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + i32_b = 0x80000000; + i32_c = 0x11112222; + a64_s = 0xF7776EEF12345678LL; + a64_r = __builtin_mips_madd (a64_a, i32_b, i32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + ui32_b = 0x80000000; + ui32_c = 0x11112222; + a64_s = 0x0888911112345678LL; + a64_r = __builtin_mips_maddu (a64_a, ui32_b, ui32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + i32_b = 0x80000000; + i32_c = 0x11112222; + a64_s = 0x0888911112345678LL; + a64_r = __builtin_mips_msub (a64_a, i32_b, i32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + ui32_b = 0x80000000; + ui32_c = 0x11112222; + a64_s = 0xF7776EEF12345678LL; + a64_r = __builtin_mips_msubu (a64_a, ui32_b, ui32_c); + if (a64_r != a64_s) + abort (); +#endif + + v2i16_a = (v2i16) {0xffff, 0x2468}; + v2i16_b = (v2i16) {0x1234, 0x1111}; + v2i16_s = (v2i16) {0xedcc, 0x52e8}; + v2i16_r = __builtin_mips_mul_ph (v2i16_a, v2i16_b); + r = (int) v2i16_r; + s = (int) v2i16_s; + if (r != s) + abort (); + + v2i16_a = (v2i16) {0x8000, 0x7fff}; + v2i16_b = (v2i16) {0x1234, 0x1111}; + v2i16_s = (v2i16) {0x8000, 0x7fff}; + v2i16_r = __builtin_mips_mul_s_ph (v2i16_a, v2i16_b); + r = (int) v2i16_r; + s = (int) v2i16_s; + if (r != s) + abort (); + + q31_a = 0x80000000; + q31_b = 0x80000000; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_mulq_rs_w (q31_a, q31_b); + if (q31_r != q31_s) + abort (); + + v2q15_a = (v2q15) {0xffff, 0x8000}; + v2q15_b = (v2q15) {0x1111, 0x8000}; + v2q15_s = (v2q15) {0xffff, 0x7fff}; + v2q15_r = __builtin_mips_mulq_s_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x00000002; + q31_b = 0x80000000; + q31_s = 0xfffffffe; + q31_r = __builtin_mips_mulq_s_w (q31_a, q31_b); + if (q31_r != q31_s) + abort (); + +#ifndef __mips64 + a64_a = 0x19848419; + v2i16_b = (v2i16) {0xffff, 0x8000}; + v2i16_c = (v2i16) {0x1111, 0x8000}; + if (little_endian) + a64_s = 0x5984952a; + else + a64_s = 0xffffffffd9847308LL; + a64_r = __builtin_mips_mulsa_w_ph (a64_a, v2i16_b, v2i16_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + i32_a = 0x80000000; + i32_b = 0x11112222; + a64_s = 0xF7776EEF00000000LL; + a64_r = __builtin_mips_mult (i32_a, i32_b); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + ui32_a = 0x80000000; + ui32_b = 0x11112222; + a64_s = 0x888911100000000LL; + a64_r = __builtin_mips_multu (ui32_a, ui32_b); + if (a64_r != a64_s) + abort (); +#endif + + v2i16_a = (v2i16) {0x1234, 0x5678}; + v2i16_b = (v2i16) {0x2233, 0x5566}; + if (little_endian) + v4i8_s = (v4i8) {0x33, 0x66, 0x34, 0x78}; + else + v4i8_s = (v4i8) {0x34, 0x78, 0x33, 0x66}; + v4i8_r = __builtin_mips_precr_qb_ph (v2i16_a, v2i16_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + i32_a = 0x12345678; + i32_b = 0x33334444; + if (little_endian) + v2i16_s = (v2i16) {0x3444, 0x4567}; + else + v2i16_s = (v2i16) {0x4567, 0x3444}; + v2i16_r = __builtin_mips_precr_sra_ph_w (i32_a, i32_b, 4); + r = (int) v2i16_r; + s = (int) v2i16_s; + if (r != s) + abort (); + + i32_a = 0x12345678; + i32_b = 0x33334444; + if (little_endian) + v2i16_s = (v2i16) {0x3444, 0x4568}; + else + v2i16_s = (v2i16) {0x4568, 0x3444}; + v2i16_r = __builtin_mips_precr_sra_r_ph_w (i32_a, i32_b, 4); + r = (int) v2i16_r; + s = (int) v2i16_s; + if (r != s) + abort (); + + i32_a = 0x12345678; + i32_b = 0x87654321; + i32_s = 0x43211234; + i32_r = __builtin_mips_prepend (i32_a, i32_b, 16); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x45, 0x77, 0x99}; + v4i8_s = (v4i8) {0x9, 0x22, 0x3b, 0xcc}; + v4i8_r = __builtin_mips_shra_qb (v4i8_a, 1); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x45, 0x77, 0x99}; + v4i8_s = (v4i8) {0x9, 0x23, 0x3c, 0xcd}; + v4i8_r = __builtin_mips_shra_r_qb (v4i8_a, 1); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + i32_b = 1; + v4i8_a = (v4i8) {0x12, 0x45, 0x77, 0x99}; + v4i8_s = (v4i8) {0x9, 0x22, 0x3b, 0xcc}; + v4i8_r = __builtin_mips_shra_qb (v4i8_a, i32_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + i32_b = 1; + v4i8_a = (v4i8) {0x12, 0x45, 0x77, 0x99}; + v4i8_s = (v4i8) {0x9, 0x23, 0x3c, 0xcd}; + v4i8_r = __builtin_mips_shra_r_qb (v4i8_a, i32_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2i16_a = (v2i16) {0x1357, 0x2468}; + v2i16_s = (v2i16) {0x0135, 0x0246}; + v2i16_r = __builtin_mips_shrl_ph (v2i16_a, 4); + r = (int) v2i16_r; + s = (int) v2i16_s; + if (r != s) + abort (); + + i32_b = 8; + v2i16_a = (v2i16) {0x1357, 0x2468}; + v2i16_s = (v2i16) {0x0013, 0x0024}; + v2i16_r = __builtin_mips_shrl_ph (v2i16_a, i32_b); + r = (int) v2i16_r; + s = (int) v2i16_s; + if (r != s) + abort (); + + v2i16_a = (v2i16) {0x1357, 0x4455}; + v2i16_b = (v2i16) {0x3333, 0x4444}; + v2i16_s = (v2i16) {0xe024, 0x0011}; + v2i16_r = __builtin_mips_subu_ph (v2i16_a, v2i16_b); + r = (int) v2i16_r; + s = (int) v2i16_s; + if (r != s) + abort (); + + v2i16_a = (v2i16) {0x1357, 0x4455}; + v2i16_b = (v2i16) {0x3333, 0x4444}; + v2i16_s = (v2i16) {0x0000, 0x0011}; + v2i16_r = __builtin_mips_subu_s_ph (v2i16_a, v2i16_b); + r = (int) v2i16_r; + s = (int) v2i16_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x33 ,0x44, 0x55, 0x66}; + v4i8_b = (v4i8) {0x99 ,0x15, 0x85, 0xff}; + v4i8_s = (v4i8) {0xcd ,0x17, 0xe8, 0xb3}; + v4i8_r = __builtin_mips_subuh_qb (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x33 ,0x44, 0x55, 0x66}; + v4i8_b = (v4i8) {0x99 ,0x15, 0x85, 0xff}; + v4i8_s = (v4i8) {0xcd ,0x18, 0xe8, 0xb4}; + v4i8_r = __builtin_mips_subuh_r_qb (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x3334, 0x4444}; + v2q15_b = (v2q15) {0x1111, 0x2222}; + v2q15_s = (v2q15) {0x2222, 0x3333}; + v2q15_r = __builtin_mips_addqh_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x3334, 0x4444}; + v2q15_b = (v2q15) {0x1111, 0x2222}; + v2q15_s = (v2q15) {0x2223, 0x3333}; + v2q15_r = __builtin_mips_addqh_r_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x11111112; + q31_b = 0x99999999; + q31_s = 0xd5555555; + q31_r = __builtin_mips_addqh_w (q31_a, q31_b); + if (q31_r != q31_s) + abort (); + + q31_a = 0x11111112; + q31_b = 0x99999999; + q31_s = 0xd5555556; + q31_r = __builtin_mips_addqh_r_w (q31_a, q31_b); + if (q31_r != q31_s) + abort (); + + v2q15_a = (v2q15) {0x3334, 0x4444}; + v2q15_b = (v2q15) {0x1111, 0x2222}; + v2q15_s = (v2q15) {0x1111, 0x1111}; + v2q15_r = __builtin_mips_subqh_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x3334, 0x4444}; + v2q15_b = (v2q15) {0x1111, 0x2222}; + v2q15_s = (v2q15) {0x1112, 0x1111}; + v2q15_r = __builtin_mips_subqh_r_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x11111112; + q31_b = 0x99999999; + q31_s = 0x3bbbbbbc; + q31_r = __builtin_mips_subqh_w (q31_a, q31_b); + if (q31_r != q31_s) + abort (); + + q31_a = 0x11111112; + q31_b = 0x99999999; + q31_s = 0x3bbbbbbd; + q31_r = __builtin_mips_subqh_r_w (q31_a, q31_b); + if (q31_r != q31_s) + abort (); + +#ifndef __mips64 + a64_a = 0x1111222212345678LL; + v2i16_b = (v2i16) {0x1, 0x2}; + v2i16_c = (v2i16) {0x3, 0x4}; + a64_s = 0x1111222212345682LL; + a64_r = __builtin_mips_dpax_w_ph (a64_a, v2i16_b, v2i16_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x9999111112345678LL; + v2i16_b = (v2i16) {0x1, 0x2}; + v2i16_c = (v2i16) {0x3, 0x4}; + a64_s = 0x999911111234566eLL; + a64_r = __builtin_mips_dpsx_w_ph (a64_a, v2i16_b, v2i16_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x70000000; + v2q15_b = (v2q15) {0x4000, 0x2000}; + v2q15_c = (v2q15) {0x2000, 0x4000}; + a64_s = 0x98000000; + a64_r = __builtin_mips_dpaqx_s_w_ph (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x70000000; + v2q15_b = (v2q15) {0x4000, 0x2000}; + v2q15_c = (v2q15) {0x2000, 0x4000}; + a64_s = 0x7fffffff; + a64_r = __builtin_mips_dpaqx_sa_w_ph (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x70000000; + v2q15_b = (v2q15) {0x4000, 0x2000}; + v2q15_c = (v2q15) {0x2000, 0x4000}; + a64_s = 0x48000000; + a64_r = __builtin_mips_dpsqx_s_w_ph (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0xFFFFFFFF80000000LL; + v2q15_b = (v2q15) {0x4000, 0x2000}; + v2q15_c = (v2q15) {0x2000, 0x4000}; + a64_s = 0xFFFFFFFF80000000LL; + a64_r = __builtin_mips_dpsqx_sa_w_ph (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); +#endif +} diff --git a/gcc/testsuite/gcc.target/nanomips/msub-4.c b/gcc/testsuite/gcc.target/nanomips/msub-4.c new file mode 100644 index 00000000000..e5845e6cab5 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/msub-4.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* This test requires widening_mul */ +/* { dg-options "-mdspr3 -mgp32 -fexpensive-optimizations" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler-times "\tmsub\t\\\$ac" 2 } } */ + +long long +f1 (int x, int y, long long z) +{ + return z - (long long) y * x; +} + +long long +f2 (int x, int y, long long z) +{ + long long t = (long long) x * y; + int temp = 5; + if (temp == 5) + z -= t; + return z; +} diff --git a/gcc/testsuite/gcc.target/nanomips/msubu-4.c b/gcc/testsuite/gcc.target/nanomips/msubu-4.c new file mode 100644 index 00000000000..a8e13dc5c0c --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/msubu-4.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* This test requires widening_mul */ +/* { dg-options "-mdspr3 -mgp32 -fexpensive-optimizations" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-final { scan-assembler-times "\tmsubu\t\\\$ac" 2 } } */ + +typedef unsigned int ui; +typedef unsigned long long ull; + +ull +f1 (ui x, ui y, ull z) +{ + return z - (ull) y * x; +} + +ull +f2 (ui x, ui y, ull z) +{ + ull t = (ull) x * y; + int temp = 5; + if (temp == 5) + z -= t; + return z; +} diff --git a/gcc/testsuite/gcc.target/nanomips/nanomips-dsp-accinit-2.c b/gcc/testsuite/gcc.target/nanomips/nanomips-dsp-accinit-2.c new file mode 100644 index 00000000000..6f31f4ee813 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/nanomips-dsp-accinit-2.c @@ -0,0 +1,23 @@ +/* { dg-options "-mdspr3 -mgp32" } */ +/* References to RESULT within the loop need to have a higher frequency than + references to RESULT outside the loop, otherwise there is no reason + to prefer multiply/accumulator registers over GPRs. */ +/* { dg-skip-if "requires register frequencies" { *-*-* } { "-O0" "-Os" } { "" } } */ + +/* Check that the zero-initialization of the accumulator feeding into + the madd is done by means of an mthi & mtlo pair instead of a + "mult $0,$0" instruction. */ + +long long f (int n, int *v, int m) +{ + long long result = 0; + int i; + + for (i = 0; i < n; i++) + result = __builtin_mips_madd (result, v[i], m); + return result; +} + +/* { dg-final { scan-assembler "mult\t\[^\n\]*\\\$zero" } } */ +/* { dg-final { scan-assembler-not "\tmthi\t" } } */ +/* { dg-final { scan-assembler-not "\tmtlo\t" } } */ diff --git a/gcc/testsuite/gcc.target/nanomips/nanomips-dsp.c b/gcc/testsuite/gcc.target/nanomips/nanomips-dsp.c new file mode 100644 index 00000000000..3d2ffd6de23 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/nanomips-dsp.c @@ -0,0 +1,1160 @@ +/* Test MIPS32 DSP instructions */ +/* { dg-do compile } */ +/* { dg-options "-mgp32 -mdspr3 (REQUIRES_STDLIB)" } */ +/* { dg-final { scan-assembler "\taddq.ph\t" } } */ +/* { dg-final { scan-assembler "\taddq_s.ph\t" } } */ +/* { dg-final { scan-assembler "\taddq_s.w\t" } } */ +/* { dg-final { scan-assembler "\taddu.qb\t" } } */ +/* { dg-final { scan-assembler "\taddu_s.qb\t" } } */ +/* { dg-final { scan-assembler "\tsubq.ph\t" } } */ +/* { dg-final { scan-assembler "\tsubq_s.ph\t" } } */ +/* { dg-final { scan-assembler "\tsubq_s.w\t" } } */ +/* { dg-final { scan-assembler "\tsubu.qb\t" } } */ +/* { dg-final { scan-assembler "\tsubu_s.qb\t" } } */ +/* { dg-final { scan-assembler "\taddsc\t" } } */ +/* { dg-final { scan-assembler "\taddwc\t" } } */ +/* { dg-final { scan-assembler "\tmodsub\t" } } */ +/* { dg-final { scan-assembler "\traddu.w.qb\t" } } */ +/* { dg-final { scan-assembler "\tabsq_s.ph\t" } } */ +/* { dg-final { scan-assembler "\tabsq_s.w\t" } } */ +/* { dg-final { scan-assembler "\tprecrq.qb.ph\t" } } */ +/* { dg-final { scan-assembler "\tprecrq.ph.w\t" } } */ +/* { dg-final { scan-assembler "\tprecrq_rs.ph.w\t" } } */ +/* { dg-final { scan-assembler "\tprecrqu_s.qb.ph\t" } } */ +/* { dg-final { scan-assembler "\tpreceq.w.phl\t" } } */ +/* { dg-final { scan-assembler "\tpreceq.w.phr\t" } } */ +/* { dg-final { scan-assembler "\tprecequ.ph.qbl\t" } } */ +/* { dg-final { scan-assembler "\tprecequ.ph.qbr\t" } } */ +/* { dg-final { scan-assembler "\tprecequ.ph.qbla\t" } } */ +/* { dg-final { scan-assembler "\tprecequ.ph.qbra\t" } } */ +/* { dg-final { scan-assembler "\tpreceu.ph.qbl\t" } } */ +/* { dg-final { scan-assembler "\tpreceu.ph.qbr\t" } } */ +/* { dg-final { scan-assembler "\tpreceu.ph.qbla\t" } } */ +/* { dg-final { scan-assembler "\tpreceu.ph.qbra\t" } } */ +/* { dg-final { scan-assembler "\tshllv?.qb\t" } } */ +/* { dg-final { scan-assembler "\tshllv?.ph\t" } } */ +/* { dg-final { scan-assembler "\tshllv?_s.ph\t" } } */ +/* { dg-final { scan-assembler "\tshllv?_s.w\t" } } */ +/* { dg-final { scan-assembler "\tshrlv?.qb\t" } } */ +/* { dg-final { scan-assembler "\tshrav?.ph\t" } } */ +/* { dg-final { scan-assembler "\tshrav?_r.ph\t" } } */ +/* { dg-final { scan-assembler "\tshrav?_r.w\t" } } */ +/* { dg-final { scan-assembler "\tmuleu_s.ph.qbl\t" } } */ +/* { dg-final { scan-assembler "\tmuleu_s.ph.qbr\t" } } */ +/* { dg-final { scan-assembler "\tmulq_rs.ph\t" } } */ +/* { dg-final { scan-assembler "\tmuleq_s.w.phl\t" } } */ +/* { dg-final { scan-assembler "\tmuleq_s.w.phr\t" } } */ +/* { dg-final { scan-assembler "\tdpau.h.qbl\t" } } */ +/* { dg-final { scan-assembler "\tdpau.h.qbr\t" } } */ +/* { dg-final { scan-assembler "\tdpsu.h.qbl\t" } } */ +/* { dg-final { scan-assembler "\tdpsu.h.qbr\t" } } */ +/* { dg-final { scan-assembler "\tdpaq_s.w.ph\t" } } */ +/* { dg-final { scan-assembler "\tdpsq_s.w.ph\t" } } */ +/* { dg-final { scan-assembler "\tmulsaq_s.w.ph\t" } } */ +/* { dg-final { scan-assembler "\tdpaq_sa.l.w\t" } } */ +/* { dg-final { scan-assembler "\tdpsq_sa.l.w\t" } } */ +/* { dg-final { scan-assembler "\tmaq_s.w.phl\t" } } */ +/* { dg-final { scan-assembler "\tmaq_s.w.phr\t" } } */ +/* { dg-final { scan-assembler "\tmaq_sa.w.phl\t" } } */ +/* { dg-final { scan-assembler "\tmaq_sa.w.phr\t" } } */ +/* { dg-final { scan-assembler "\tbitrev\t" } } */ +/* { dg-final { scan-assembler "\tinsv\t" } } */ +/* { dg-final { scan-assembler "\treplv?.qb\t" } } */ +/* { dg-final { scan-assembler "\trepl.ph\t" } } */ +/* { dg-final { scan-assembler "\treplv.ph\t" } } */ +/* { dg-final { scan-assembler "\tcmpu.eq.qb\t" } } */ +/* { dg-final { scan-assembler "\tcmpu.lt.qb\t" } } */ +/* { dg-final { scan-assembler "\tcmpu.le.qb\t" } } */ +/* { dg-final { scan-assembler "\tcmpgu.eq.qb\t" } } */ +/* { dg-final { scan-assembler "\tcmpgu.lt.qb\t" } } */ +/* { dg-final { scan-assembler "\tcmpgu.le.qb\t" } } */ +/* { dg-final { scan-assembler "\tcmp.eq.ph\t" } } */ +/* { dg-final { scan-assembler "\tcmp.lt.ph\t" } } */ +/* { dg-final { scan-assembler "\tcmp.le.ph\t" } } */ +/* { dg-final { scan-assembler "\tpick.qb\t" } } */ +/* { dg-final { scan-assembler "\tpick.ph\t" } } */ +/* { dg-final { scan-assembler "\tpackrl.ph\t" } } */ +/* { dg-final { scan-assembler "\textrv?.w\t" } } */ +/* { dg-final { scan-assembler "\textrv?_s.h\t" } } */ +/* { dg-final { scan-assembler "\textrv?_r.w\t" } } */ +/* { dg-final { scan-assembler "\textrv?_rs.w\t" } } */ +/* { dg-final { scan-assembler "\textpv?\t" } } */ +/* { dg-final { scan-assembler "\textpdpv?\t" } } */ +/* { dg-final { scan-assembler "\tshilov?\t" } } */ +/* { dg-final { scan-assembler "\tmthlip\t" } } */ +/* { dg-final { scan-assembler "\tmfhi\t" } } */ +/* { dg-final { scan-assembler "\tmflo\t" } } */ +/* { dg-final { scan-assembler "\tmthi\t" } } */ +/* { dg-final { scan-assembler "\tmtlo\t" } } */ +/* { dg-final { scan-assembler "\twrdsp\t" } } */ +/* { dg-final { scan-assembler "\trddsp\t" } } */ +/* { dg-final { scan-assembler "\tlbux?\t" } } */ +/* { dg-final { scan-assembler "\tlhx?\t" } } */ +/* { dg-final { scan-assembler "\tlwx?\t" } } */ +/* { dg-final { scan-assembler "\tbposge32c\t" } } */ +/* { dg-final { scan-assembler "\tmadd\t" } } */ +/* { dg-final { scan-assembler "\tmaddu\t" } } */ +/* { dg-final { scan-assembler "\tmsub\t" } } */ +/* { dg-final { scan-assembler "\tmsubu\t" } } */ +/* { dg-final { scan-assembler "\tmult\t" } } */ +/* { dg-final { scan-assembler "\tmultu\t" } } */ + +#include +#include + +typedef signed char v4i8 __attribute__ ((vector_size(4))); +typedef short v2q15 __attribute__ ((vector_size(4))); + +typedef int q31; +typedef int i32; +typedef unsigned int ui32; +typedef long long a64; + +void test_MIPS_DSP (void); + +char array[100]; +int little_endian; + +int main () +{ + int i; + + union { long long ll; int i[2]; } endianness_test; + endianness_test.ll = 1; + little_endian = endianness_test.i[0]; + + for (i = 0; i < 100; i++) + array[i] = i; + + test_MIPS_DSP (); + + exit (0); +} + +v2q15 add_v2q15 (v2q15 a, v2q15 b) +{ + return __builtin_mips_addq_ph (a, b); +} + +v4i8 add_v4i8 (v4i8 a, v4i8 b) +{ + return __builtin_mips_addu_qb (a, b); +} + +v2q15 sub_v2q15 (v2q15 a, v2q15 b) +{ + return __builtin_mips_subq_ph (a, b); +} + +v4i8 sub_v4i8 (v4i8 a, v4i8 b) +{ + return __builtin_mips_subu_qb (a, b); +} + +void test_MIPS_DSP () +{ + v4i8 v4i8_a,v4i8_b,v4i8_c,v4i8_r,v4i8_s; + v2q15 v2q15_a,v2q15_b,v2q15_c,v2q15_r,v2q15_s; + q31 q31_a,q31_b,q31_c,q31_r,q31_s; + /* To protect the multiplication-related tests from being optimized + at compile time. */ + volatile i32 i32_a,i32_b,i32_c,i32_r,i32_s; + volatile ui32 ui32_a,ui32_b,ui32_c; + a64 a64_a,a64_b,a64_c,a64_r,a64_s; + + void *ptr_a; + int r,s; + long long lr,ls; + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + v2q15_s = (v2q15) {0x81bd, 0x6789}; + v2q15_r = add_v2q15 (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + v2q15_s = (v2q15) {0x7fff, 0x6789}; + v2q15_r = __builtin_mips_addq_s_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x70000000; + q31_b = 0x71234567; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_addq_s_w (q31_a, q31_b); + if (q31_r != q31_s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0xff, 0x89, 0x11, 0x11}; + v4i8_s = (v4i8) {0xf1, 0xbd, 0x67, 0x89}; + v4i8_r = add_v4i8 (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0xff, 0x89, 0x11, 0x11}; + v4i8_s = (v4i8) {0xff, 0xbd, 0x67, 0x89}; + v4i8_r = __builtin_mips_addu_s_qb (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + v2q15_s = (v2q15) {0xa2ab, 0x4567}; + v2q15_r = sub_v2q15 (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x8000, 0x5678}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + v2q15_s = (v2q15) {0x8000, 0x4567}; + v2q15_r = __builtin_mips_subq_s_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x70000000; + q31_b = 0x71234567; + q31_s = 0xfedcba99; + q31_r = __builtin_mips_subq_s_w (q31_a, q31_b); + if (q31_r != q31_s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0xff, 0x89, 0x11, 0x11}; + v4i8_s = (v4i8) {0xf3, 0xab, 0x45, 0x67}; + v4i8_r = sub_v4i8 (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0xff, 0x89, 0x11, 0x11}; + v4i8_s = (v4i8) {0x0, 0x0, 0x45, 0x67}; + v4i8_r = __builtin_mips_subu_s_qb (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + i32_a = 0xf5678900; + i32_b = 0x7abcdef0; + i32_s = 0x702467f0; + i32_r = __builtin_mips_addsc (i32_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_a = 0x75678900; + i32_b = 0x7abcdef0; + i32_s = 0xf02467f1; + i32_r = __builtin_mips_addwc (i32_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_a = 0; + i32_b = 0x00000901; + i32_s = 9; + i32_r = __builtin_mips_modsub (i32_a, i32_b); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + i32_s = 0x1f4; + i32_r = __builtin_mips_raddu_w_qb (v4i8_a); + if (i32_r != i32_s) + abort (); + + v2q15_a = (v2q15) {0x8000, 0x8134}; + v2q15_s = (v2q15) {0x7fff, 0x7ecc}; + v2q15_r = __builtin_mips_absq_s_ph (v2q15_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = (q31) 0x80000000; + q31_s = (q31) 0x7fffffff; + q31_r = __builtin_mips_absq_s_w (q31_a); + if (q31_r != q31_s) + abort (); + + v2q15_a = (v2q15) {0x9999, 0x5612}; + v2q15_b = (v2q15) {0x5612, 0x3333}; + if (little_endian) + v4i8_s = (v4i8) {0x56, 0x33, 0x99, 0x56}; + else + v4i8_s = (v4i8) {0x99, 0x56, 0x56, 0x33}; + v4i8_r = __builtin_mips_precrq_qb_ph (v2q15_a, v2q15_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + q31_a = 0x12348678; + q31_b = 0x44445555; + if (little_endian) + v2q15_s = (v2q15) {0x4444, 0x1234}; + else + v2q15_s = (v2q15) {0x1234, 0x4444}; + v2q15_r = __builtin_mips_precrq_ph_w (q31_a, q31_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x12348678; + q31_b = 0x44445555; + if (little_endian) + v2q15_s = (v2q15) {0x4444, 0x1235}; + else + v2q15_s = (v2q15) {0x1235, 0x4444}; + v2q15_r = __builtin_mips_precrq_rs_ph_w (q31_a, q31_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x9999, 0x5612}; + v2q15_b = (v2q15) {0x5612, 0x3333}; + if (little_endian) + v4i8_s = (v4i8) {0xac, 0x66, 0x00, 0xac}; + else + v4i8_s = (v4i8) {0x00, 0xac, 0xac, 0x66}; + v4i8_r = __builtin_mips_precrqu_s_qb_ph (v2q15_a, v2q15_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x3589, 0x4444}; + if (little_endian) + q31_s = 0x44440000; + else + q31_s = 0x35890000; + q31_r = __builtin_mips_preceq_w_phl (v2q15_a); + if (q31_r != q31_s) + abort (); + + v2q15_a = (v2q15) {0x3589, 0x4444}; + if (little_endian) + q31_s = 0x35890000; + else + q31_s = 0x44440000; + q31_r = __builtin_mips_preceq_w_phr (v2q15_a); + if (q31_r != q31_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x2b00, 0x1980}; + else + v2q15_s = (v2q15) {0x0900, 0x2b00}; + v2q15_r = __builtin_mips_precequ_ph_qbl (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x0900, 0x2b00}; + else + v2q15_s = (v2q15) {0x2b00, 0x1980}; + v2q15_r = __builtin_mips_precequ_ph_qbr (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x2b00, 0x1980}; + else + v2q15_s = (v2q15) {0x0900, 0x2b00}; + v2q15_r = __builtin_mips_precequ_ph_qbla (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x0900, 0x2b00}; + else + v2q15_s = (v2q15) {0x2b00, 0x1980}; + v2q15_r = __builtin_mips_precequ_ph_qbra (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x56, 0x33}; + else + v2q15_s = (v2q15) {0x12, 0x56}; + v2q15_r = __builtin_mips_preceu_ph_qbl (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x56, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x12, 0x56}; + else + v2q15_s = (v2q15) {0x56, 0x33}; + v2q15_r = __builtin_mips_preceu_ph_qbr (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x99, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x99, 0x33}; + else + v2q15_s = (v2q15) {0x12, 0x56}; + v2q15_r = __builtin_mips_preceu_ph_qbla (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x99, 0x56, 0x33}; + if (little_endian) + v2q15_s = (v2q15) {0x12, 0x56}; + else + v2q15_s = (v2q15) {0x99, 0x33}; + v2q15_r = __builtin_mips_preceu_ph_qbra (v4i8_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_s = (v4i8) {0xc8, 0xd0, 0x58, 0xe0}; + v4i8_r = __builtin_mips_shll_qb (v4i8_a, 2); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + i32_b = 1; + v4i8_s = (v4i8) {0xe4, 0x68, 0xac, 0xf0}; + v4i8_r = __builtin_mips_shll_qb (v4i8_a, i32_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_s = (v2q15) {0x48d0, 0x59e0}; + v2q15_r = __builtin_mips_shll_ph (v2q15_a, 2); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + i32_b = 1; + v2q15_s = (v2q15) {0x2468, 0xacf0}; + v2q15_r = __builtin_mips_shll_ph (v2q15_a, i32_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_s = (v2q15) {0x48d0, 0x7fff}; + v2q15_r = __builtin_mips_shll_s_ph (v2q15_a, 2); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + i32_b = 1; + v2q15_s = (v2q15) {0x2468, 0x7fff}; + v2q15_r = __builtin_mips_shll_s_ph (v2q15_a, i32_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x70000000; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_shll_s_w (q31_a, 2); + if (q31_r != q31_s) + abort (); + + q31_a = 0x70000000; + i32_b = 1; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_shll_s_w (q31_a, i32_b); + if (q31_r != q31_s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + v4i8_s = (v4i8) {0x3c, 0xd, 0x15, 0x1e}; + v4i8_r = __builtin_mips_shrl_qb (v4i8_a, 2); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0xf2, 0x34, 0x56, 0x78}; + i32_b = 1; + v4i8_s = (v4i8) {0x79, 0x1a, 0x2b, 0x3c}; + v4i8_r = __builtin_mips_shrl_qb (v4i8_a, i32_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_s = (v2q15) {0x48d, 0x159e}; + v2q15_r = __builtin_mips_shra_ph (v2q15_a, 2); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + i32_b = 1; + v2q15_s = (v2q15) {0x91a, 0x2b3c}; + v2q15_r = __builtin_mips_shra_ph (v2q15_a, i32_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_s = (v2q15) {0x48d, 0x159e}; + v2q15_r = __builtin_mips_shra_r_ph (v2q15_a, 2); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + i32_b = 3; + v2q15_s = (v2q15) {0x247, 0xacf}; + v2q15_r = __builtin_mips_shra_r_ph (v2q15_a, i32_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + q31_a = 0x70000000; + q31_s = 0x1c000000; + q31_r = __builtin_mips_shra_r_w (q31_a, 2); + if (q31_r != q31_s) + abort (); + + q31_a = 0x70000004; + i32_b = 3; + q31_s = 0x0e000001; + q31_r = __builtin_mips_shra_r_w (q31_a, i32_b); + if (q31_r != q31_s) + abort (); + + v4i8_a = (v4i8) {0x1, 0x2, 0x3, 0x4}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + if (little_endian) + v2q15_s = (v2q15) {0xffff, 0x4444}; + else + v2q15_s = (v2q15) {0x6f89, 0x2222}; + v2q15_r = __builtin_mips_muleu_s_ph_qbl (v4i8_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x1, 0x2, 0x3, 0x4}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + if (little_endian) + v2q15_s = (v2q15) {0x6f89, 0x2222}; + else + v2q15_s = (v2q15) {0xffff, 0x4444}; + v2q15_r = __builtin_mips_muleu_s_ph_qbr (v4i8_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x6f89, 0x1111}; + v2q15_s = (v2q15) {0x0fdd, 0x0b87}; + v2q15_r = __builtin_mips_mulq_rs_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x8000, 0x8000}; + v2q15_b = (v2q15) {0x8000, 0x8000}; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_muleq_s_w_phl (v2q15_a, v2q15_b); + if (q31_r != q31_s) + abort (); + + v2q15_a = (v2q15) {0x8000, 0x8000}; + v2q15_b = (v2q15) {0x8000, 0x8000}; + q31_s = 0x7fffffff; + q31_r = __builtin_mips_muleq_s_w_phr (v2q15_a, v2q15_b); + if (q31_r != q31_s) + abort (); + +#ifndef __mips64 + a64_a = 0x22221111; + v4i8_b = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_c = (v4i8) {0xaa, 0x89, 0x11, 0x34}; + if (little_endian) + a64_s = 0x22222f27; + else + a64_s = 0x222238d9; + a64_r = __builtin_mips_dpau_h_qbl (a64_a, v4i8_b, v4i8_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x22221111; + v4i8_b = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_c = (v4i8) {0xaa, 0x89, 0x11, 0x34}; + if (little_endian) + a64_s = 0x222238d9; + else + a64_s = 0x22222f27; + a64_r = __builtin_mips_dpau_h_qbr (a64_a, v4i8_b, v4i8_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x22221111; + v4i8_b = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_c = (v4i8) {0xaa, 0x89, 0x11, 0x34}; + if (little_endian) + a64_s = 0x2221f2fb; + else + a64_s = 0x2221e949; + a64_r = __builtin_mips_dpsu_h_qbl (a64_a, v4i8_b, v4i8_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x22221111; + v4i8_b = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_c = (v4i8) {0xaa, 0x89, 0x11, 0x34}; + if (little_endian) + a64_s = 0x2221e949; + else + a64_s = 0x2221f2fb; + a64_r = __builtin_mips_dpsu_h_qbr (a64_a, v4i8_b, v4i8_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x5678}; + v2q15_c = (v2q15) {0x8000, 0x1111}; + a64_s = 0x8b877d00; + a64_r = __builtin_mips_dpaq_s_w_ph (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x5678}; + v2q15_c = (v2q15) {0x8000, 0x1111}; + a64_s = 0xffffffff7478a522LL; + a64_r = __builtin_mips_dpsq_s_w_ph (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x5678}; + v2q15_c = (v2q15) {0x8000, 0x1111}; + if (little_endian) + a64_s = 0xffffffff8b877d02LL; + else + a64_s = 0x7478a520; + a64_r = __builtin_mips_mulsaq_s_w_ph (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + q31_b = 0x80000000; + q31_c = 0x80000000; + a64_s = 0x7fffffffffffffffLL; + a64_r = __builtin_mips_dpaq_sa_l_w (a64_a, q31_b, q31_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + q31_b = 0x80000000; + q31_c = 0x80000000; + a64_s = 0x8000000000001112LL; + a64_r = __builtin_mips_dpsq_sa_l_w (a64_a, q31_b, q31_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x1}; + v2q15_c = (v2q15) {0x8000, 0x2}; + if (little_endian) + a64_s = 0x1115; + else + a64_s = 0x80001110; + a64_r = __builtin_mips_maq_s_w_phl (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x1}; + v2q15_c = (v2q15) {0x8000, 0x2}; + if (little_endian) + a64_s = 0x80001110; + else + a64_s = 0x1115; + a64_r = __builtin_mips_maq_s_w_phr (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x1}; + v2q15_c = (v2q15) {0x8000, 0x2}; + if (little_endian) + a64_s = 0x1115; + else + a64_s = 0x7fffffff; + a64_r = __builtin_mips_maq_sa_w_phl (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); + + a64_a = 0x00001111; + v2q15_b = (v2q15) {0x8000, 0x1}; + v2q15_c = (v2q15) {0x8000, 0x2}; + if (little_endian) + a64_s = 0x7fffffff; + else + a64_s = 0x1115; + a64_r = __builtin_mips_maq_sa_w_phr (a64_a, v2q15_b, v2q15_c); + if (a64_r != a64_s) + abort (); +#endif + + i32_a = 0x12345678; + i32_s = 0x00001e6a; + i32_r = __builtin_mips_bitrev (i32_a); + if (i32_r != i32_s) + abort (); + + i32_a = 0x00000208; // pos is 8, size is 4 + __builtin_mips_wrdsp (i32_a, 31); + i32_a = 0x12345678; + i32_b = 0x87654321; + i32_s = 0x12345178; + i32_r = __builtin_mips_insv (i32_a, i32_b); + if (i32_r != i32_s) + abort (); + + v4i8_s = (v4i8) {1, 1, 1, 1}; + v4i8_r = __builtin_mips_repl_qb (1); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + i32_a = 99; + v4i8_s = (v4i8) {99, 99, 99, 99}; + v4i8_r = __builtin_mips_repl_qb (i32_a); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + v2q15_s = (v2q15) {30, 30}; + v2q15_r = __builtin_mips_repl_ph (30); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + i32_a = 0x5612; + v2q15_s = (v2q15) {0x5612, 0x5612}; + v2q15_r = __builtin_mips_repl_ph (i32_a); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x03000000; + else + i32_s = 0x0c000000; + __builtin_mips_cmpu_eq_qb (v4i8_a, v4i8_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x04000000; + else + i32_s = 0x02000000; + __builtin_mips_cmpu_lt_qb (v4i8_a, v4i8_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x07000000; + else + i32_s = 0x0e000000; + __builtin_mips_cmpu_le_qb (v4i8_a, v4i8_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x3; + else + i32_s = 0xc; + i32_r=__builtin_mips_cmpgu_eq_qb (v4i8_a, v4i8_b); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x4; + else + i32_s = 0x2; + i32_r = __builtin_mips_cmpgu_lt_qb (v4i8_a, v4i8_b); + if (i32_r != i32_s) + abort (); + + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x12, 0x34, 0x78, 0x56}; + if (little_endian) + i32_s = 0x7; + else + i32_s = 0xe; + i32_r = __builtin_mips_cmpgu_le_qb (v4i8_a, v4i8_b); + if (i32_r != i32_s) + abort (); + + __builtin_mips_wrdsp (0,31); // Clear all condition code bits. + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x1234, 0x7856}; + if (little_endian) + i32_s = 0x01000000; + else + i32_s = 0x02000000; + __builtin_mips_cmp_eq_ph (v2q15_a, v2q15_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x1234, 0x7856}; + if (little_endian) + i32_s = 0x02000000; + else + i32_s = 0x01000000; + __builtin_mips_cmp_lt_ph (v2q15_a, v2q15_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x1234, 0x7856}; + i32_s = 0x03000000; + __builtin_mips_cmp_le_ph (v2q15_a, v2q15_b); + i32_r = __builtin_mips_rddsp (16); + if (i32_r != i32_s) + abort (); + + i32_a = 0x0a000000; // cc: 0000 1010 + __builtin_mips_wrdsp (i32_a, 31); + v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78}; + v4i8_b = (v4i8) {0x21, 0x43, 0x65, 0x87}; + if (little_endian) + v4i8_s = (v4i8) {0x21, 0x34, 0x65, 0x78}; + else + v4i8_s = (v4i8) {0x12, 0x43, 0x56, 0x87}; + v4i8_r = __builtin_mips_pick_qb (v4i8_a, v4i8_b); + r = (int) v4i8_r; + s = (int) v4i8_s; + if (r != s) + abort (); + + i32_a = 0x02000000; // cc: 0000 0010 + __builtin_mips_wrdsp (i32_a, 31); + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x2143, 0x6587}; + if (little_endian) + v2q15_s = (v2q15) {0x2143, 0x5678}; + else + v2q15_s = (v2q15) {0x1234, 0x6587}; + v2q15_r = __builtin_mips_pick_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + + v2q15_a = (v2q15) {0x1234, 0x5678}; + v2q15_b = (v2q15) {0x1234, 0x7856}; + if (little_endian) + v2q15_s = (v2q15) {0x7856, 0x1234}; + else + v2q15_s = (v2q15) {0x5678, 0x1234}; + v2q15_r = __builtin_mips_packrl_ph (v2q15_a, v2q15_b); + r = (int) v2q15_r; + s = (int) v2q15_s; + if (r != s) + abort (); + +#ifndef __mips64 + a64_a = 0x1234567887654321LL; + i32_s = 0x88765432; + i32_r = __builtin_mips_extr_w (a64_a, 4); + if (i32_r != i32_s) + abort (); + + a64_a = 0x1234567887658321LL; + i32_s = 0x56788766; + i32_r = __builtin_mips_extr_r_w (a64_a, 16); + if (i32_r != i32_s) + abort (); + + a64_a = 0x12345677fffffff8LL; + i32_s = 0x7fffffff; + i32_r = __builtin_mips_extr_rs_w (a64_a, 4); + if (i32_r != i32_s) + abort (); + + a64_a = 0x1234567887658321LL; + i32_s = 0x7fff; + i32_r = __builtin_mips_extr_s_h (a64_a, 16); + if (i32_r != i32_s) + abort (); + + a64_a = 0x0000007887658321LL; + i32_b = 24; + i32_s = 0x7887; + i32_r = __builtin_mips_extr_s_h (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + a64_a = 0x1234567887654321LL; + i32_b = 4; + i32_s = 0x88765432; + i32_r = __builtin_mips_extr_w (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + a64_a = 0x1234567887658321LL; + i32_b = 16; + i32_s = 0x56788766; + i32_r = __builtin_mips_extr_r_w (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + a64_a = 0x12345677fffffff8LL; + i32_b = 4; + i32_s = 0x7fffffff; + i32_r = __builtin_mips_extr_rs_w (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_a = 0x0000021f; // pos is 31 + __builtin_mips_wrdsp (i32_a, 31); + a64_a = 0x1234567887654321LL; + i32_s = 8; + i32_r = __builtin_mips_extp (a64_a, 3); // extract 4 bits + if (i32_r != i32_s) + abort (); + + i32_a = 0x0000021f; // pos is 31 + __builtin_mips_wrdsp (i32_a, 31); + a64_a = 0x1234567887654321LL; + i32_b = 7; // size is 8. NOTE!! we should use 7 + i32_s = 0x87; + i32_r = __builtin_mips_extp (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_a = 0x0000021f; // pos is 31 + __builtin_mips_wrdsp (i32_a, 31); + a64_a = 0x1234567887654321LL; + i32_s = 8; + i32_r = __builtin_mips_extpdp (a64_a, 3); // extract 4 bits + if (i32_r != i32_s) + abort (); + + i32_s = 0x0000021b; // pos is 27 + i32_r = __builtin_mips_rddsp (31); + if (i32_r != i32_s) + abort (); + + i32_a = 0x0000021f; // pos is 31 + __builtin_mips_wrdsp (i32_a, 31); + a64_a = 0x1234567887654321LL; + i32_b = 11; // size is 12. NOTE!!! We should use 11 + i32_s = 0x876; + i32_r = __builtin_mips_extpdp (a64_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_s = 0x00000213; // pos is 19 + i32_r = __builtin_mips_rddsp (31); + if (i32_r != i32_s) + abort (); + + a64_a = 0x1234567887654321LL; + a64_s = 0x0012345678876543LL; + a64_r = __builtin_mips_shilo (a64_a, 8); + if (a64_r != a64_s) + abort (); + + a64_a = 0x1234567887654321LL; + i32_b = -16; + a64_s = 0x5678876543210000LL; + a64_r = __builtin_mips_shilo (a64_a, i32_b); + if (a64_r != a64_s) + abort (); + + i32_a = 0x0; + __builtin_mips_wrdsp (i32_a, 31); + a64_a = 0x1234567887654321LL; + i32_b = 0x11112222; + a64_s = 0x8765432111112222LL; + a64_r = __builtin_mips_mthlip (a64_a, i32_b); + if (a64_r != a64_s) + abort (); + i32_s = 32; + i32_r = __builtin_mips_rddsp (31); + if (i32_r != i32_s) + abort (); +#endif + + i32_a = 0x1357a468; + __builtin_mips_wrdsp (i32_a, 63); + i32_s = 0x03572428; + i32_r = __builtin_mips_rddsp (63); + if (i32_r != i32_s) + abort (); + + ptr_a = &array; + i32_b = 37; + i32_s = 37; + i32_r = __builtin_mips_lbux (ptr_a, i32_b); + if (i32_r != i32_s) + abort (); + + ptr_a = &array; + i32_b = 38; + if (little_endian) + i32_s = 0x2726; + else + i32_s = 0x2627; + i32_r = __builtin_mips_lhx (ptr_a, i32_b); + if (i32_r != i32_s) + abort (); + + ptr_a = &array; + i32_b = 40; + if (little_endian) + i32_s = 0x2b2a2928; + else + i32_s = 0x28292a2b; + i32_r = __builtin_mips_lwx (ptr_a, i32_b); + if (i32_r != i32_s) + abort (); + + i32_a = 0x00000220; // pos is 32, size is 4 + __builtin_mips_wrdsp (i32_a, 63); + i32_s = 1; + i32_r = __builtin_mips_bposge32 (); + if (i32_r != i32_s) + abort (); + +#ifndef __mips64 + a64_a = 0x12345678; + i32_b = 0x80000000; + i32_c = 0x11112222; + a64_s = 0xF7776EEF12345678LL; + a64_r = __builtin_mips_madd (a64_a, i32_b, i32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + ui32_b = 0x80000000; + ui32_c = 0x11112222; + a64_s = 0x0888911112345678LL; + a64_r = __builtin_mips_maddu (a64_a, ui32_b, ui32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + i32_b = 0x80000000; + i32_c = 0x11112222; + a64_s = 0x0888911112345678LL; + a64_r = __builtin_mips_msub (a64_a, i32_b, i32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + a64_a = 0x12345678; + ui32_b = 0x80000000; + ui32_c = 0x11112222; + a64_s = 0xF7776EEF12345678LL; + a64_r = __builtin_mips_msubu (a64_a, ui32_b, ui32_c); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + i32_a = 0x80000000; + i32_b = 0x11112222; + a64_s = 0xF7776EEF00000000LL; + a64_r = __builtin_mips_mult (i32_a, i32_b); + if (a64_r != a64_s) + abort (); +#endif + +#ifndef __mips64 + ui32_a = 0x80000000; + ui32_b = 0x11112222; + a64_s = 0x888911100000000LL; + a64_r = __builtin_mips_multu (ui32_a, ui32_b); + if (a64_r != a64_s) + abort (); +#endif +} + diff --git a/gcc/testsuite/gcc.target/nanomips/nanomips-dspr3-type-1.c b/gcc/testsuite/gcc.target/nanomips/nanomips-dspr3-type-1.c new file mode 100644 index 00000000000..6e31c491d64 --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/nanomips-dspr3-type-1.c @@ -0,0 +1,30 @@ +/* Test MIPS32 DSP instructions */ +/* { dg-do compile } */ +/* { dg-options "-mdspr3" } */ +/* { dg-final { scan-assembler "\taddq.ph\t" } } */ +/* { dg-final { scan-assembler "\taddu.qb\t" } } */ +/* { dg-final { scan-assembler "\tsubq.ph\t" } } */ +/* { dg-final { scan-assembler "\tsubu.qb\t" } } */ + +typedef char v4qi __attribute__ ((vector_size(4))); +typedef short v2hi __attribute__ ((vector_size(4))); + +v2hi add_v2hi (v2hi a, v2hi b) +{ + return a + b; +} + +v4qi add_v4qi (v4qi a, v4qi b) +{ + return a + b; +} + +v2hi sub_v2hi (v2hi a, v2hi b) +{ + return a - b; +} + +v4qi sub_v4qi (v4qi a, v4qi b) +{ + return a - b; +} diff --git a/gcc/testsuite/gcc.target/nanomips/nanomips-dspr3-type-2.c b/gcc/testsuite/gcc.target/nanomips/nanomips-dspr3-type-2.c new file mode 100644 index 00000000000..d312bedfa0b --- /dev/null +++ b/gcc/testsuite/gcc.target/nanomips/nanomips-dspr3-type-2.c @@ -0,0 +1,12 @@ +/* Test MIPS32 DSP REV 2 instructions */ +/* { dg-do compile } */ +/* { dg-options "-mdspr3" } */ +/* { dg-final { scan-assembler "\tmul.ph\t" } } */ + +typedef short v2hi __attribute__ ((vector_size(4))); + +v2hi mul_v2hi (v2hi a, v2hi b) +{ + return a * b; +} + From patchwork Sun Sep 26 13:26:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dragan Mladjenovic X-Patchwork-Id: 45450 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7089D3858015 for ; Sun, 26 Sep 2021 13:36:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7089D3858015 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1632663398; bh=MntRICD3j8FxZevQJ5iGWXwtUDCchqg0uI+jUTI7nNk=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=opNaPJwqgrbIPE8Md3XW/zymccJQuYIyF8UtuobsUBwIs7UT19Vu0qErgCdKbPWgJ GbMyNRgNvdf/WMvL4Sr+3Fzk0CRzUA8muw5euYJopWdY6U7ei1NkIqSPdeaxasc0fq Rt/ooA87PUzqlUnrl4UCXpi2R3PTkcn+IbmjoerQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mailgw01.mediatek.com (mailgw01.mediatek.com [216.200.240.184]) by sourceware.org (Postfix) with ESMTPS id BF1D43858403; Sun, 26 Sep 2021 13:35:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BF1D43858403 X-UUID: 867845fc25df46e6bb7d7e3d91d799f0-20210926 X-UUID: 867845fc25df46e6bb7d7e3d91d799f0-20210926 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1333465835; Sun, 26 Sep 2021 06:35:05 -0700 Received: from MTKMBS62N1.mediatek.inc (172.29.193.41) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sun, 26 Sep 2021 06:26:07 -0700 Received: from MTKMBS62N1.mediatek.inc ([fe80::697c:586d:7cff:34e7]) by MTKMBS62N1.mediatek.inc ([fe80::697c:586d:7cff:34e7%12]) with mapi id 15.00.1497.015; Sun, 26 Sep 2021 06:26:07 -0700 To: "gcc-patches@gcc.gnu.org" Subject: [RFC 7/7] Add documentation for nanoMIPS Thread-Topic: [RFC 7/7] Add documentation for nanoMIPS Thread-Index: AQHXstoPFtvMQnWcbEm+E80QvvaRrA== Date: Sun, 26 Sep 2021 13:26:07 +0000 Message-ID: <30b77027c0684e14b31727bdd14f7fc1@MTKMBS62N1.mediatek.inc> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [172.29.193.239] MIME-Version: 1.0 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, HTML_MESSAGE, SPF_HELO_NONE, SPF_PASS, TXREP, UNPARSEABLE_RELAY 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-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Dragan Mladjenovic via Gcc-patches From: Dragan Mladjenovic Reply-To: Dragan Mladjenovic Cc: Jeff Law , Matthew Fortune , Jakub Jelinek , YunQiang Su , "Petar.Jovanovic@syrmia.com" , Faraz Shahbazker , Vince Del Vecchio Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" gcc/ChangeLog: * doc/extend.texi: Add nanoMIPS Function Attributes, nanoMIPS Built-in Functions and nanoMIPS DSP Built-in Functions. * doc/invoke.texi: Add nanoMIPS Options. * doc/md.texi: Add nanoMIPS constraints. --- gcc/doc/extend.texi | 124 +++++++++++++++ gcc/doc/invoke.texi | 367 ++++++++++++++++++++++++++++++++++++++++++++ gcc/doc/md.texi | 71 +++++++++ 3 files changed, 562 insertions(+) 3 files changed, 562 insertions(+) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 6d8b9856eea..5bfea4cd7b6 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2484,6 +2484,7 @@ GCC plugins may provide their own attributes. * Microsoft Windows Function Attributes:: * MIPS Function Attributes:: * MSP430 Function Attributes:: +* nanoMIPS Function Attributes:: * NDS32 Function Attributes:: * Nios II Function Attributes:: * Nvidia PTX Function Attributes:: @@ -5673,6 +5674,99 @@ options can help the packing, however, since they produce smaller, easier to pack regions. @end table +@node nanoMIPS Function Attributes +@subsection nanoMIPS Function Attributes + +These function attributes are supported by the nanoMIPS back end: + +@table @code +@item cmodel ("@var{model}") +@cindex @code{cmodel} function attribute, nanoMIPS +Use this attribute to indicate what code should be generated for a particular +code and data model for this function. The behavior and permissible arguments +are the same as for the command line option @option{-mcmodel=}. +@end table + +@table @code +@item interrupt +@cindex @code{interrupt} function attribute, nanoMIPS +Use this attribute to indicate that the specified function is an interrupt +handler. The compiler generates function entry and exit sequences suitable +for use in an interrupt handler when this attribute is present. +An optional argument is supported for the interrupt attribute which allows +the interrupt mode to be described. By default GCC assumes the external +interrupt controller (EIC) mode is in use, this can be explicitly set using +@code{eic}. When interrupts are non-masked then the requested Interrupt +Priority Level (IPL) is copied to the current IPL which has the effect of only +enabling higher priority interrupts. To use vectored interrupt mode use +the argument @code{vector=[sw0|sw1|hw0|hw1|hw2|hw3|hw4|hw5]}, this will change +the behavior of the non-masked interrupt support and GCC will arrange to mask +all interrupts from sw0 up to and including the specified interrupt vector. + +You can use the following attributes to modify the behavior +of an interrupt handler: +@table @code +@item use_shadow_register_set +@cindex @code{use_shadow_register_set} function attribute, nanoMIPS +Assume that the handler uses a shadow register set, instead of +the main general-purpose registers. An optional argument @code{intstack} is +supported to indicate that the shadow register set contains a valid stack +pointer. + +@item keep_interrupts_masked +@cindex @code{keep_interrupts_masked} function attribute, nanoMIPS +Keep interrupts masked for the whole function. Without this attribute, +GCC tries to reenable interrupts for as much of the function as it can. + +@item use_debug_exception_return +@cindex @code{use_debug_exception_return} function attribute, nanoMIPS +Return using the @code{deret} instruction. Interrupt handlers that don't +have this attribute return using @code{eret} instead. +@end table + +You can use any combination of these attributes, as shown below: +@smallexample +void __attribute__ ((interrupt)) v0 (); +void __attribute__ ((interrupt, use_shadow_register_set)) v1 (); +void __attribute__ ((interrupt, keep_interrupts_masked)) v2 (); +void __attribute__ ((interrupt, use_debug_exception_return)) v3 (); +void __attribute__ ((interrupt, use_shadow_register_set, + keep_interrupts_masked)) v4 (); +void __attribute__ ((interrupt, use_shadow_register_set, + use_debug_exception_return)) v5 (); +void __attribute__ ((interrupt, keep_interrupts_masked, + use_debug_exception_return)) v6 (); +void __attribute__ ((interrupt, use_shadow_register_set, + keep_interrupts_masked, + use_debug_exception_return)) v7 (); +void __attribute__ ((interrupt("eic"))) v8 (); +void __attribute__ ((interrupt("vector=hw3"))) v9 (); +@end smallexample + +@item long_call +@itemx near +@itemx far +@cindex indirect calls, nanoMIPS +@cindex @code{long_call} function attribute, nanoMIPS +@cindex @code{near} function attribute, nanoMIPS +@cindex @code{far} function attribute, nanoMIPS +These attributes specify how a particular function is called on nanoMIPS@. +The attributes override the @option{-mlong-calls} (@pxref{nanoMIPS Options}) +command-line switch. The @code{long_call} and @code{far} attributes are +synonyms, and cause the compiler to always call +the function by first loading its address into a register, and then using +the contents of that register. The @code{near} attribute has the opposite +effect; it specifies that non-PIC calls should be made using the more +efficient @code{jal} instruction. + +@item use_hazard_barrier_return +@cindex @code{use_hazard_barrier_return} function attribute, nanoMIPS +This function attribute instructs the compiler to generate a hazard barrier +return that clears all execution and instruction hazards while returning, +instead of generating a normal return instruction. + +@end table + @node NDS32 Function Attributes @subsection NDS32 Function Attributes @@ -14495,6 +14589,8 @@ instructions, but allow the compiler to schedule those calls. * MIPS SIMD Architecture (MSA) Support:: * Other MIPS Built-in Functions:: * MSP430 Built-in Functions:: +* nanoMIPS Built-in Functions:: +* nanoMIPS DSP Built-in Functions:: * NDS32 Built-in Functions:: * picoChip Built-in Functions:: * Basic PowerPC Built-in Functions:: @@ -17510,6 +17606,34 @@ optimized to a constant later. The number of cycles delayed by this builtin is exact. @end table +@node nanoMIPS Built-in Functions +@subsection nanoMIPS Built-in Functions + +The following built-in functions map directly to a particular nanoMIPS +instruction. Please refer to the architecture specification +for details on what each instruction does. + +@smallexample +imm0_3: integer literal 0 to 3. +typedef int i32; +typedef unsigned int ui32; +@end smallexample + +@smallexample +i32 __builtin_mips_align (i32, i32, imm0_3) +ui32 __builtin_mips_bitrevb (ui32) +ui32 __builtin_mips_bitrevh (ui32) +ui32 __builtin_mips_bitrevw (ui32) +ui32 __builtin_mips_byterevh (ui32) +ui32 __builtin_mips_byterevw (ui32) +@end smallexample + +@node nanoMIPS DSP Built-in Functions +@subsection nanoMIPS DSP Built-in Functions +nanoMIPS supports DSP Rev 3 onwards. For description of the built-ins, +Please refer to MIPS DSP and MIPS DSP Rev 2 sections in +@pxref{MIPS DSP Built-in Functions}. + @node NDS32 Built-in Functions @subsection NDS32 Built-in Functions diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index ba98eab68a5..c4ff1bff816 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1108,6 +1108,35 @@ Objective-C and Objective-C++ Dialects}. -msilicon-errata= -msilicon-errata-warn= @gol -mhwmult= -minrt -mtiny-printf -mmax-inline-shift=} +@emph{nanoMIPS Options} +@gccoptlist{-EL -EB -march=@var{arch} -mtune=@var{arch} @gol +-m32 -m64 @gol +-mcmodel=auto -mcmodel=medium -mcmodel=large @gol +-mbalc-stubs -mno-balc-stubs @gol +-mpcrel -mno-pcrel @gol +-mpid -mno-pid @gol +-mrelax -mno-relax @gol +-mgp32 -mgp64 -mhard-float -msoft-float @gol +-msingle-float -mdouble-float @gol +-mdspr3 -mno-dspr3 @gol +-mmcu -mmno-mcu @gol +-meva -mno-eva @gol +-mvirt -mno-virt @gol +-mxpa -mno-xpa @gol +-mmsa -mno-msa @gol +-msym32 -mno-sym32 @gol +-G@var{num} -mlocal-sdata -mno-local-sdata @gol +-mextern-sdata -mno-extern-sdata -mgpopt -mno-gopt @gol +-membedded-data -mno-embedded-data @gol +-muninit-const-in-rodata -mno-uninit-const-in-rodata @gol +-mcheck-zero-division -mno-check-zero-division @gol +-mdivide-traps @gol +-mmemcpy -mno-memcpy @gol +-mlong-calls -mno-long-calls @gol +-mimadd -mno-imadd @gol +-mflush-func=@var{func} -mno-flush-func @gol +-mbranch-cost=@var{num}} + @emph{NDS32 Options} @gccoptlist{-mbig-endian -mlittle-endian @gol -mreduced-regs -mfull-regs @gol @@ -18350,6 +18379,7 @@ platform. * MN10300 Options:: * Moxie Options:: * MSP430 Options:: +* nanoMIPS Options:: * NDS32 Options:: * Nios II Options:: * Nvidia PTX Options:: @@ -26212,6 +26242,343 @@ Warn if @samp{devices.csv} is not found or there are problem parsing it @end table +@node nanoMIPS Options +@subsection nanoMIPS Options +@cindex nanoMIPS options + +@table @gcctabopt + +@item -EB +@opindex EB +Generate big-endian code. This is the default for @samp{nanomips*eb-*-*} +configurations. + +@item -EL +@opindex EL +Generate little-endian code. + +@item -march=@var{arch} +@opindex march +Generate code that runs on @var{arch}, which can be the name of a +generic nanoMIPS, or the name of a particular processor. +The ISA names are: +@samp{32r6}, @samp{64r6}. +The processor names are: +@samp{i7200}. + +GCC defines two macros based on the value of this option. The first +is @code{_MIPS_ARCH}, which gives the name of target architecture, as +a string. The second has the form @code{_MIPS_ARCH_@var{foo}}, +where @var{foo} is the capitalized value of @code{_MIPS_ARCH}@. +For example, @option{-march=32r6} sets @code{_MIPS_ARCH} +to @code{"32r6"} and defines the macro @code{_MIPS_ARCH_32R6}. + +@item -mtune=@var{arch} +@opindex mtune +Optimize for @var{arch}. Among other things, this option controls +the way instructions are scheduled, and the perceived cost of arithmetic +operations. The list of @var{arch} values is the same as for +@option{-march}. + +When this option is not used, GCC optimizes for the processor +specified by @option{-march}. By using @option{-march} and +@option{-mtune} together, it is possible to generate code that +runs on a family of processors, but optimize the code for one +particular member of that family. + +@option{-mtune} defines the macros @code{_MIPS_TUNE} and +@code{_MIPS_TUNE_@var{foo}}, which work in the same way as the +@option{-march} ones described above. + +@item -m32 +@itemx -m64 +@opindex m32 +@opindex m64 +Generate code for the given ABI, either 32-bit or 64-bit variant. + +@item -mcmodel=auto +@opindex mcmodel=auto +Generate the most compressed code possible by relying on the linker to expand +or relax code appropriately, depending on a given symbol's visibility at +link-time. + +@item -mcmodel=medium +@opindex mcmodel=medium +Generate code which is appropriate for average-sized applications without +relying on linker relaxations or expansions. The GP area can not exceed 2MiB +and direct calls have a maximum range of 32 MiB. + +@item -mcmodel=large +@opindex mcmodel=large +Generates code which is appropriate for large applications without relying on +linker relaxations or expansions. There are no inherent size limits when +using this model. + +@item -mbalc-stubs +@itemx -mno-balc-stubs +@opindex mbalc-stubs +@opindex mno-balc-stubs +Enable (disable) the assembler's out-of-range call optimization through +trampoline stubs. + +The default option is @option{-mbalc-stubs} for @option{-Os} optimization +level and @option{-mno-balc-stubs} for any other optimization level. + +@item -mpcrel +@itemx -mno-pcrel +@opindex mpcrel +@opindex mno-pcrel +@option{-mpcrel} forces PC-relative addressing for non-pre-emptible symbols. +This also effectively disables absolute addressing. +@option{-mno-pcrel} avoids PC-relative addressing for non-pre-emptible +symbols where alternative sequences are not larger or slower. + +The default option is @option{-mpcrel}. + +@item -mpid +@itemx -mno-pid +@opindex mpid +@opindex mno-pid +Enforce (do not enforce) position-independent data by requiring GP-relative +addressing for all non-pre-emptible data symbols. + +The default is @option{mno-pid}. + +@item -mrelax +@itemx -mno-relax +@opindex mrelax +@opindex mno-relax +Enable (disable) linker relaxations and expansions for the compilation unit. +The compiler emits (does not emit) a @code{.linkrelax} directive to +the assembly file that causes an ELF header flag to be set in the object. + +The default option is to emit the @code{.linkrelax} directive. + +@item -mgp32 +@opindex mgp32 +Assume that general-purpose registers are 32 bits wide. + +@item -mgp64 +@opindex mgp64 +Assume that general-purpose registers are 64 bits wide. + +@item -mhard-float +@opindex mhard-float +Use floating-point coprocessor instructions. + +@item -msoft-float +@opindex msoft-float +Do not use floating-point coprocessor instructions. Implement +floating-point calculations using library calls instead. + +@item -msingle-float +@opindex msingle-float +Assume that the floating-point coprocessor only supports single-precision +operations. + +@item -mdouble-float +@opindex mdouble-float +Assume that the floating-point coprocessor supports double-precision +operations. This is the default. + +@item -mdspr3 +@itemx -mno-dspr3 +@opindex mdspr3 +@opindex mno-dspr3 +Use (do not use) revision 3 of the MIPS DSP ASE@. +@xref{MIPS DSP Built-in Functions}. This option defines the +preprocessor macros @code{__mips_dsp} and @code{__mips_dspr3}. +It also defines @code{__mips_dsp_rev} to 3. + +@item -mmt +@itemx -mno-mt +@opindex mmt +@opindex mno-mt +Use (do not use) MT Multithreading instructions. + +@item -mmcu +@itemx -mno-mcu +@opindex mmcu +@opindex mno-mcu +Use (do not use) the MIPS MCU ASE instructions. + +@item -meva +@itemx -mno-eva +@opindex meva +@opindex mno-eva +Use (do not use) the MIPS Enhanced Virtual Addressing instructions. + +@item -mvirt +@itemx -mno-virt +@opindex mvirt +@opindex mno-virt +Use (do not use) the MIPS Virtualization Application Specific instructions. + +@item -mxpa +@itemx -mno-xpa +@opindex mxpa +@opindex mno-xpa +Use (do not use) the MIPS eXtended Physical Address (XPA) instructions. + +@item -msym32 +@itemx -mno-sym32 +@opindex msym32 +@opindex mno-sym32 +Assume (do not assume) that all symbols have 32-bit values, regardless +of the selected ABI@. This option is useful in combination with +@option{-m64} because it allows GCC to generate shorter and faster references +to symbolic addresses. + +@item -G @var{num} +@opindex G +Put definitions of externally-visible data in a small data section +if that data is no bigger than @var{num} bytes. GCC can then generate +more efficient accesses to the data; see @option{-mgpopt} for details. + +The default @option{-G} option depends on the configuration. + +@item -mlocal-sdata +@itemx -mno-local-sdata +@opindex mlocal-sdata +@opindex mno-local-sdata +Extend (do not extend) the @option{-G} behavior to local data too, +such as to static variables in C@. @option{-mlocal-sdata} is the +default for all configurations. + +If the linker complains that an application is using too much small data, +you might want to try rebuilding the less performance-critical parts with +@option{-mno-local-sdata}. You might also want to build large +libraries with @option{-mno-local-sdata}, so that the libraries leave +more room for the main program. + +@item -mextern-sdata +@itemx -mno-extern-sdata +@opindex mextern-sdata +@opindex mno-extern-sdata +Assume (do not assume) that externally-defined data is in +a small data section if the size of that data is within the @option{-G} limit. +@option{-mextern-sdata} is the default for all configurations. + +If you compile a module @var{Mod} with @option{-mextern-sdata} @option{-G +@var{num}} @option{-mgpopt}, and @var{Mod} references a variable @var{Var} +that is no bigger than @var{num} bytes, you must make sure that @var{Var} +is placed in a small data section. If @var{Var} is defined by another +module, you must either compile that module with a high-enough +@option{-G} setting or attach a @code{section} attribute to @var{Var}'s +definition. If @var{Var} is common, you must link the application +with a high-enough @option{-G} setting. + +The easiest way of satisfying these restrictions is to compile +and link every module with the same @option{-G} option. However, +you may wish to build a library that supports several different +small data limits. You can do this by compiling the library with +the highest supported @option{-G} setting and additionally using +@option{-mno-extern-sdata} to stop the library from making assumptions +about externally-defined data. + +@item -mgpopt +@itemx -mno-gpopt +@opindex mgpopt +@opindex mno-gpopt +Use (do not use) GP-relative accesses for symbols that are known to be +in a small data section; see @option{-G}, @option{-mlocal-sdata} and +@option{-mextern-sdata}. @option{-mgpopt} is the default for all +configurations. + +@option{-mno-gpopt} is useful for cases where the @code{$gp} register +might not hold the value of @code{_gp}. For example, if the code is +part of a library that might be used in a boot monitor, programs that +call boot monitor routines pass an unknown value in @code{$gp}. +(In such situations, the boot monitor itself is usually compiled +with @option{-G0}.) + +@option{-mno-gpopt} implies @option{-mno-local-sdata} and +@option{-mno-extern-sdata}. + +@item -membedded-data +@itemx -mno-embedded-data +@opindex membedded-data +@opindex mno-embedded-data +Allocate variables to the read-only data section first if possible, then +next in the small data section if possible, otherwise in data. This gives +slightly slower code than the default, but reduces the amount of RAM required +when executing, and thus may be preferred for some embedded systems. + +@item -muninit-const-in-rodata +@itemx -mno-uninit-const-in-rodata +@opindex muninit-const-in-rodata +@opindex mno-uninit-const-in-rodata +Put uninitialized @code{const} variables in the read-only data section. +This option is only meaningful in conjunction with @option{-membedded-data}. + +@item -mcheck-zero-division +@itemx -mno-check-zero-division +@opindex mcheck-zero-division +@opindex mno-check-zero-division +Trap (do not trap) on integer division by zero. + +The default is @option{-mno-check-zero-division} at @option{-Os} level and +@option{-mcheck-zero-division} for any other optimization level. + +@item -mdivide-traps +@opindex mdivide-traps +nanoMIPS systems check for division by zero by generating either a +conditional trap or a break instruction. Using traps results in +smaller code, but it is not supported in the nanoMIPS Subset. Also, some +versions of the Linux kernel have a bug that prevents trap from +generating the proper signal (@code{SIGFPE}). Use @option{-mdivide-traps} to +allow conditional traps on architectures that support them and +@option{-mno-divide-traps} to force the use of breaks. + +Divide-by-zero checks can be completely disabled using +@option{-mno-check-zero-division}. + +@item -mmemcpy +@itemx -mno-memcpy +@opindex mmemcpy +@opindex mno-memcpy +Force (do not force) the use of @code{memcpy} for non-trivial block +moves. The default is @option{-mno-memcpy}, which allows GCC to inline +most constant-sized copies. + +@item -mlong-calls +@itemx -mno-long-calls +@opindex mlong-calls +@opindex mno-long-calls +Disable (do not disable) use of the @code{balc} instruction. Calling +functions using @code{balc} is more efficient but requires the caller +and callee to within the same 64 megabyte window. + +The default is @option{-mno-long-calls}. + +@item -mimadd +@itemx -mno-imadd +@opindex mimadd +@opindex mno-imadd +Enable (disable) use of the @code{madd} and @code{msub} integer +instructions. The default is @option{-mimadd} on architectures +that support @code{madd} and @code{msub} as part of the DSP. + +@item -mflush-func=@var{func} +@itemx -mno-flush-func +@opindex mflush-func +Specifies the function to call to flush the I and D caches, or to not +call any such function. If called, the function must take the same +arguments as the common @code{_flush_func}, that is, the address of the +memory range for which the cache is being flushed, the size of the +memory range, and the number 3 (to flush both caches). The default +depends on the target GCC was configured for, but commonly is either +@code{_flush_func} or @code{__cpu_flush}. + +@item mbranch-cost=@var{num} +@opindex mbranch-cost +Set the cost of branches to roughly @var{num} ``simple'' instructions. +This cost is only a heuristic and is not guaranteed to produce +consistent results across releases. A zero cost redundantly selects +the default, which is based on the @option{-mtune} setting. + +@end table + @node NDS32 Options @subsection NDS32 Options @cindex NDS32 Options diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 2b41cb7fb7b..883ef8bdc03 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -2969,6 +2969,77 @@ Memory reference, stack only. @end table +@item nanoMIPS---@file{config/mips/constraints.md} +@table @code +@item c +A register suitable for use in an indirect jump. + +@item d +Equivalent to @code{r}; retained for backwards compatibility. + +@item f +A floating-point register (if available). + +@item m +When used as a constraint in an ASM statement this is automatically +re-interpreted as the ZR constraint. This transformation only happens for +simple single alternative contraints with or without modifiers @code{=}, +@code{+} and @code{&}. + +@item v +Register @code{$3}. + +@item y +Equivalent to @code{r}; retained for backwards compatibility. + +@item I +A constant in the range @minus{}0xFFF to 0xFFFF inclusive that is suitable +for @code{addiu[32]} or @code{addiu[neg]} instructions. + +@item J +Integer zero. + +@item K +An unsigned 12-bit constant (for logic instructions). + +@item L +A signed 32-bit constant in which the lower 12 bits are zero. +Such constants can be loaded using @code{lui}. + +@item M +A constant that cannot be loaded using @code{lui}, @code{addiu} +or @code{ori} and instead requires @code{li48}. + +@item N +A constant in the range @minus{}65535 to @minus{}1 (inclusive). + +@item O +A signed 15-bit constant. + +@item P +A constant in the range 1 to 65535 (inclusive). + +@item G +Floating-point zero. + +@item R +An address that can be used in a non-macro load or store. This constraint +is deprecated as the nanoMIPS addressing modes vary between different +forms of load and store instructions. Use @code{ZR} to guarantee that +an address is suitable for all possible instructions. + +@item ZR +A memory operand whose address is formed from a base register alone; i.e. +no offset or index. + +@item ZC +A memory operand whose address is formed from a base register and a signed +9-bit offset. + +@item ZD +An address formed from a base register and a signed 9-bit offset. +@end table + @item NDS32---@file{config/nds32/constraints.md} @table @code @item w