coreboot-libre-fam15h-rdimm/util/crossgcc/patches/gcc-8.3.0_nds32_ite.patch

21020 lines
692 KiB
Diff
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff -urN gcc-8.2.0.orig/gcc/common/config/nds32/nds32-common.c gcc-8.2.0/gcc/common/config/nds32/nds32-common.c
--- gcc-8.2.0.orig/gcc/common/config/nds32/nds32-common.c 2018-04-06 07:51:33.000000000 +0200
+++ gcc-8.2.0/gcc/common/config/nds32/nds32-common.c 2019-01-25 15:38:32.817242625 +0100
@@ -53,6 +53,16 @@
return true;
+ case OPT_misr_secure_:
+ /* Check the valid security level: 0 1 2 3. */
+ if (value < 0 || value > 3)
+ {
+ error_at (loc, "for the option -misr-secure=X, the valid X "
+ "must be: 0, 1, 2, or 3");
+ return false;
+ }
+ return true;
+
case OPT_mcache_block_size_:
/* Check valid value: 4 8 16 32 64 128 256 512. */
if (exact_log2 (value) < 2 || exact_log2 (value) > 9)
@@ -74,12 +84,19 @@
/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
static const struct default_options nds32_option_optimization_table[] =
{
+#if TARGET_LINUX_ABI == 0
+ /* Disable -fdelete-null-pointer-checks by default in ELF toolchain. */
+ { OPT_LEVELS_ALL, OPT_fdelete_null_pointer_checks,
+ NULL, 0 },
+#endif
/* Enable -fsched-pressure by default at -O1 and above. */
{ OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
/* Enable -fomit-frame-pointer by default at all optimization levels. */
{ OPT_LEVELS_ALL, OPT_fomit_frame_pointer, NULL, 1 },
/* Enable -mrelax-hint by default at all optimization levels. */
{ OPT_LEVELS_ALL, OPT_mrelax_hint, NULL, 1 },
+ /* Enalbe -malways-align by default at -O1 and above, but not -Os or -Og. */
+ { OPT_LEVELS_1_PLUS_SPEED_ONLY, OPT_malways_align, NULL, 1 },
/* Enable -mv3push by default at -Os, but it is useless under V2 ISA. */
{ OPT_LEVELS_SIZE, OPT_mv3push, NULL, 1 },
@@ -87,6 +104,19 @@
};
/* ------------------------------------------------------------------------ */
+
+/* Implement TARGET_EXCEPT_UNWIND_INFO. */
+static enum unwind_info_type
+nds32_except_unwind_info (struct gcc_options *opts ATTRIBUTE_UNUSED)
+{
+ if (TARGET_LINUX_ABI)
+ return UI_DWARF2;
+
+ return UI_SJLJ;
+}
+
+/* ------------------------------------------------------------------------ */
+
/* Run-time Target Specification. */
@@ -103,6 +133,7 @@
TARGET_EXT_PERF : Generate performance extention instrcution.
TARGET_EXT_PERF2 : Generate performance extention version 2 instrcution.
TARGET_EXT_STRING : Generate string extention instrcution.
+ TARGET_HW_ABS : Generate hardware abs instruction.
TARGET_CMOV : Generate conditional move instruction. */
#undef TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS \
@@ -113,6 +144,7 @@
| MASK_EXT_PERF \
| MASK_EXT_PERF2 \
| MASK_EXT_STRING \
+ | MASK_HW_ABS \
| MASK_CMOV)
#undef TARGET_HANDLE_OPTION
@@ -125,7 +157,7 @@
/* Defining the Output Assembler Language. */
#undef TARGET_EXCEPT_UNWIND_INFO
-#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
+#define TARGET_EXCEPT_UNWIND_INFO nds32_except_unwind_info
/* ------------------------------------------------------------------------ */
diff -urN gcc-8.2.0.orig/gcc/config/nds32/constants.md gcc-8.2.0/gcc/config/nds32/constants.md
--- gcc-8.2.0.orig/gcc/config/nds32/constants.md 2018-04-22 09:46:39.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/constants.md 2019-01-25 15:38:32.821242637 +0100
@@ -23,6 +23,7 @@
(define_constants
[(R8_REGNUM 8)
(TA_REGNUM 15)
+ (TP_REGNUM 25)
(FP_REGNUM 28)
(GP_REGNUM 29)
(LP_REGNUM 30)
@@ -49,6 +50,16 @@
UNSPEC_FFB
UNSPEC_FFMISM
UNSPEC_FLMISM
+ UNSPEC_KDMBB
+ UNSPEC_KDMBT
+ UNSPEC_KDMTB
+ UNSPEC_KDMTT
+ UNSPEC_KHMBB
+ UNSPEC_KHMBT
+ UNSPEC_KHMTB
+ UNSPEC_KHMTT
+ UNSPEC_KSLRAW
+ UNSPEC_KSLRAWU
UNSPEC_SVA
UNSPEC_SVS
UNSPEC_WSBH
@@ -62,6 +73,29 @@
UNSPEC_UASTORE_HW
UNSPEC_UASTORE_W
UNSPEC_UASTORE_DW
+ UNSPEC_GOTINIT
+ UNSPEC_GOT
+ UNSPEC_GOTOFF
+ UNSPEC_PLT
+ UNSPEC_TLSGD
+ UNSPEC_TLSLD
+ UNSPEC_TLSIE
+ UNSPEC_TLSLE
+ UNSPEC_ROUND
+ UNSPEC_VEC_COMPARE
+ UNSPEC_KHM
+ UNSPEC_KHMX
+ UNSPEC_CLIP_OV
+ UNSPEC_CLIPS_OV
+ UNSPEC_BITREV
+ UNSPEC_KABS
+ UNSPEC_LOOP_END
+ UNSPEC_TLS_DESC
+ UNSPEC_TLS_IE
+ UNSPEC_ADD32
+ UNSPEC_ICT
+ UNSPEC_KADDH
+ UNSPEC_KSUBH
])
;; The unspec_volatile operation index.
@@ -135,10 +169,14 @@
UNSPEC_VOLATILE_SET_TRIG_EDGE
UNSPEC_VOLATILE_GET_TRIG_TYPE
UNSPEC_VOLATILE_RELAX_GROUP
+ UNSPEC_VOLATILE_OMIT_FP_BEGIN
+ UNSPEC_VOLATILE_OMIT_FP_END
UNSPEC_VOLATILE_POP25_RETURN
UNSPEC_VOLATILE_UNALIGNED_FEATURE
UNSPEC_VOLATILE_ENABLE_UNALIGNED
UNSPEC_VOLATILE_DISABLE_UNALIGNED
+ UNSPEC_VOLATILE_RDOV
+ UNSPEC_VOLATILE_CLROV
])
;; ------------------------------------------------------------------------
diff -urN gcc-8.2.0.orig/gcc/config/nds32/constraints.md gcc-8.2.0/gcc/config/nds32/constraints.md
--- gcc-8.2.0.orig/gcc/config/nds32/constraints.md 2018-04-06 07:51:33.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/constraints.md 2019-01-25 15:38:32.821242637 +0100
@@ -127,6 +127,11 @@
(and (match_code "const_int")
(match_test "IN_RANGE (ival, -31, 0)")))
+(define_constraint "Iu06"
+ "Unsigned immediate 6-bit value"
+ (and (match_code "const_int")
+ (match_test "ival < (1 << 6) && ival >= 0")))
+
;; Ip05 is special and dedicated for v3 movpi45 instruction.
;; movpi45 has imm5u field but the range is 16 ~ 47.
(define_constraint "Ip05"
@@ -136,10 +141,10 @@
&& ival >= (0 + 16)
&& (TARGET_ISA_V3 || TARGET_ISA_V3M)")))
-(define_constraint "Iu06"
+(define_constraint "IU06"
"Unsigned immediate 6-bit value constraint for addri36.sp instruction"
(and (match_code "const_int")
- (match_test "ival < (1 << 6)
+ (match_test "ival < (1 << 8)
&& ival >= 0
&& (ival % 4 == 0)
&& (TARGET_ISA_V3 || TARGET_ISA_V3M)")))
@@ -302,6 +307,25 @@
(match_test "(TARGET_ISA_V3 || TARGET_ISA_V3M)
&& (IN_RANGE (exact_log2 (ival + 1), 1, 8))")))
+(define_constraint "CVp5"
+ "Unsigned immediate 5-bit value for movpi45 instruction with range 16-47"
+ (and (match_code "const_vector")
+ (match_test "nds32_valid_CVp5_p (op)")))
+
+(define_constraint "CVs5"
+ "Signed immediate 5-bit value"
+ (and (match_code "const_vector")
+ (match_test "nds32_valid_CVs5_p (op)")))
+
+(define_constraint "CVs2"
+ "Signed immediate 20-bit value"
+ (and (match_code "const_vector")
+ (match_test "nds32_valid_CVs2_p (op)")))
+
+(define_constraint "CVhi"
+ "The immediate value that can be simply set high 20-bit"
+ (and (match_code "const_vector")
+ (match_test "nds32_valid_CVhi_p (op)")))
(define_memory_constraint "U33"
"Memory constraint for 333 format"
@@ -349,4 +373,9 @@
(match_test "(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
&& nds32_float_mem_operand_p (op)")))
+(define_constraint "S"
+ "@internal
+ A constant call address."
+ (match_operand 0 "nds32_symbolic_operand"))
+
;; ------------------------------------------------------------------------
diff -urN gcc-8.2.0.orig/gcc/config/nds32/elf.h gcc-8.2.0/gcc/config/nds32/elf.h
--- gcc-8.2.0.orig/gcc/config/nds32/elf.h 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/elf.h 2019-01-25 15:38:32.821242637 +0100
@@ -0,0 +1,81 @@
+/* Definitions of target machine of Andes NDS32 cpu for GNU compiler
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ 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
+ <http://www.gnu.org/licenses/>. */
+
+
+/* ------------------------------------------------------------------------ */
+
+#define TARGET_LINUX_ABI 0
+
+/* In the configure stage we may use options --enable-default-relax,
+ --enable-Os-default-ifc and --enable-Os-default-ex9. They effect
+ the default spec of passing --relax, --mifc, and --mex9 to linker.
+ We use NDS32_RELAX_SPEC, NDS32_IFC_SPEC, and NDS32_EX9_SPEC
+ so that we can customize them conveniently. */
+#define LINK_SPEC \
+ " %{G*}" \
+ " %{mbig-endian:-EB} %{mlittle-endian:-EL}" \
+ " %{shared:-shared}" \
+ NDS32_RELAX_SPEC
+
+#define LIB_SPEC \
+ " -lc -lgloss"
+
+#define LIBGCC_SPEC \
+ " -lgcc"
+
+/* The option -mno-ctor-dtor can disable constructor/destructor feature
+ by applying different crt stuff. In the convention, crt0.o is the
+ startup file without constructor/destructor;
+ crt1.o, crti.o, crtbegin.o, crtend.o, and crtn.o are the
+ startup files with constructor/destructor.
+ Note that crt0.o, crt1.o, crti.o, and crtn.o are provided
+ by newlib/mculib/glibc/ublic, while crtbegin.o and crtend.o are
+ currently provided by GCC for nds32 target.
+
+ For nds32 target so far:
+ If -mno-ctor-dtor, we are going to link
+ "crt0.o [user objects]".
+ If -mctor-dtor, we are going to link
+ "crt1.o crtbegin1.o [user objects] crtend1.o".
+
+ Note that the TARGET_DEFAULT_CTOR_DTOR would effect the
+ default behavior. Check gcc/config.gcc for more information. */
+#ifdef TARGET_DEFAULT_CTOR_DTOR
+ #define STARTFILE_SPEC \
+ " %{!mno-ctor-dtor:crt1.o%s;:crt0.o%s}" \
+ " %{!mno-ctor-dtor:crtbegin1.o%s}" \
+ " %{mcrt-arg:crtarg.o%s}"
+ #define ENDFILE_SPEC \
+ " %{!mno-ctor-dtor:crtend1.o%s}"
+#else
+ #define STARTFILE_SPEC \
+ " %{mctor-dtor|coverage:crt1.o%s;:crt0.o%s}" \
+ " %{mctor-dtor|coverage:crtbegin1.o%s}" \
+ " %{mcrt-arg:crtarg.o%s}"
+ #define ENDFILE_SPEC \
+ " %{mctor-dtor|coverage:crtend1.o%s}"
+#endif
+
+#define STARTFILE_CXX_SPEC \
+ " %{!mno-ctor-dtor:crt1.o%s;:crt0.o%s}" \
+ " %{!mno-ctor-dtor:crtbegin1.o%s}" \
+ " %{mcrt-arg:crtarg.o%s}"
+#define ENDFILE_CXX_SPEC \
+ " %{!mno-ctor-dtor:crtend1.o%s}"
diff -urN gcc-8.2.0.orig/gcc/config/nds32/iterators.md gcc-8.2.0/gcc/config/nds32/iterators.md
--- gcc-8.2.0.orig/gcc/config/nds32/iterators.md 2018-04-06 07:51:33.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/iterators.md 2019-01-25 15:38:32.821242637 +0100
@@ -68,6 +68,28 @@
;; shifts
(define_code_iterator shift_rotate [ashift ashiftrt lshiftrt rotatert])
+(define_code_iterator shifts [ashift ashiftrt lshiftrt])
+
+(define_code_iterator shiftrt [ashiftrt lshiftrt])
+
+(define_code_iterator sat_plus [ss_plus us_plus])
+
+(define_code_iterator all_plus [plus ss_plus us_plus])
+
+(define_code_iterator sat_minus [ss_minus us_minus])
+
+(define_code_iterator all_minus [minus ss_minus us_minus])
+
+(define_code_iterator plus_minus [plus minus])
+
+(define_code_iterator extend [sign_extend zero_extend])
+
+(define_code_iterator sumax [smax umax])
+
+(define_code_iterator sumin [smin umin])
+
+(define_code_iterator sumin_max [smax umax smin umin])
+
;;----------------------------------------------------------------------------
;; Code attributes.
;;----------------------------------------------------------------------------
@@ -76,5 +98,23 @@
(define_code_attr shift
[(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr") (rotatert "rotr")])
+(define_code_attr su
+ [(ashiftrt "") (lshiftrt "u") (sign_extend "s") (zero_extend "u")])
+
+(define_code_attr zs
+ [(sign_extend "s") (zero_extend "z")])
+
+(define_code_attr uk
+ [(plus "") (ss_plus "k") (us_plus "uk")
+ (minus "") (ss_minus "k") (us_minus "uk")])
+
+(define_code_attr opcode
+ [(plus "add") (minus "sub") (smax "smax") (umax "umax") (smin "smin") (umin "umin")])
+
+(define_code_attr add_rsub
+ [(plus "a") (minus "rs")])
+
+(define_code_attr add_sub
+ [(plus "a") (minus "s")])
;;----------------------------------------------------------------------------
diff -urN gcc-8.2.0.orig/gcc/config/nds32/linux.h gcc-8.2.0/gcc/config/nds32/linux.h
--- gcc-8.2.0.orig/gcc/config/nds32/linux.h 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/linux.h 2019-01-25 15:38:32.821242637 +0100
@@ -0,0 +1,86 @@
+/* Definitions of target machine of Andes NDS32 cpu for GNU compiler
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ 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
+ <http://www.gnu.org/licenses/>. */
+
+
+/* ------------------------------------------------------------------------ */
+
+#define TARGET_LINUX_ABI 1
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ GNU_USER_TARGET_OS_CPP_BUILTINS(); \
+ } \
+ while (0)
+
+#ifdef TARGET_BIG_ENDIAN_DEFAULT
+#define LD_SO_ENDIAN_SPEC "%{mlittle-endian:le}%{!mlittle-endian:be}"
+#else
+#define LD_SO_ENDIAN_SPEC "%{mbig-endian:be}%{!mbig-endian:le}"
+#endif
+
+/* Record arch version in TARGET_ARCH_DEFAULT. 0 means soft ABI,
+ 1 means hard ABI and using full floating-point instruction,
+ 2 means hard ABI and only using single-precision floating-point
+ instruction */
+#if TARGET_ARCH_DEFAULT
+#define LD_SO_ABI_SPEC "%{!mabi=2:f}"
+#else
+#define LD_SO_ABI_SPEC "%{mabi=2fp+:f}"
+#endif
+
+#define GLIBC_DYNAMIC_LINKER \
+ "/lib/ld-linux-nds32" LD_SO_ENDIAN_SPEC LD_SO_ABI_SPEC ".so.1"
+
+/* In the configure stage we may use options --enable-default-relax,
+ --enable-Os-default-ifc and --enable-Os-default-ex9. They effect
+ the default spec of passing --relax, --mifc, and --mex9 to linker.
+ We use NDS32_RELAX_SPEC, NDS32_IFC_SPEC, and NDS32_EX9_SPEC
+ so that we can customize them conveniently. */
+#define LINK_SPEC \
+ " %{G*}" \
+ " %{mbig-endian:-EB} %{mlittle-endian:-EL}" \
+ " %{shared:-shared} \
+ %{!shared: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ -dynamic-linker " GNU_USER_DYNAMIC_LINKER "} \
+ %{static:-static}}" \
+ NDS32_RELAX_SPEC
+
+#define LINK_PIE_SPEC "%{pie:%{!fno-pie:%{!fno-PIE:%{!static:-pie}}}} "
+
+#define CPP_SPEC "%{pthread:-D_REENTRANT}"
+
+/* The SYNC operations are implemented as library functions, not
+ INSN patterns. As a result, the HAVE defines for the patterns are
+ not defined. We need to define them to generate the corresponding
+ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_* and __GCC_ATOMIC_*_LOCK_FREE
+ defines.
+ Ref: https://sourceware.org/ml/libc-alpha/2014-09/msg00322.html */
+#define HAVE_sync_compare_and_swapqi 1
+#define HAVE_sync_compare_and_swaphi 1
+#define HAVE_sync_compare_and_swapsi 1
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32.c gcc-8.2.0/gcc/config/nds32/nds32.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32.c 2018-05-07 03:38:02.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32.c 2019-01-25 15:38:32.833242671 +0100
@@ -305,6 +305,7 @@
{ "nested", 0, 0, false, false, false, false, NULL, NULL },
{ "not_nested", 0, 0, false, false, false, false, NULL, NULL },
{ "nested_ready", 0, 0, false, false, false, false, NULL, NULL },
+ { "critical", 0, 0, false, false, false, false, NULL, NULL },
/* The attributes describing isr register save scheme. */
{ "save_all", 0, 0, false, false, false, false, NULL, NULL },
@@ -314,9 +315,19 @@
{ "nmi", 1, 1, false, false, false, false, NULL, NULL },
{ "warm", 1, 1, false, false, false, false, NULL, NULL },
+ /* The attributes describing isr security level. */
+ { "secure", 1, 1, false, false, false, false, NULL, NULL },
+
/* The attribute telling no prologue/epilogue. */
{ "naked", 0, 0, false, false, false, false, NULL, NULL },
+ /* The attribute is used to tell this function to be ROM patch. */
+ { "indirect_call",0, 0, false, false, false, false, NULL, NULL },
+
+ /* FOR BACKWARD COMPATIBILITY,
+ this attribute also tells no prologue/epilogue. */
+ { "no_prologue", 0, 0, false, false, false, false, NULL, NULL },
+
/* The last attribute spec is set to be NULL. */
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
@@ -345,6 +356,10 @@
/* Initially this function is not under strictly aligned situation. */
machine->strict_aligned_p = 0;
+ /* Initially this function has no naked and no_prologue attributes. */
+ machine->attr_naked_p = 0;
+ machine->attr_no_prologue_p = 0;
+
return machine;
}
@@ -362,6 +377,15 @@
needs prologue/epilogue. */
cfun->machine->naked_p = 0;
+ /* We need to mark whether this function has naked and no_prologue
+ attribute so that we can distinguish the difference if users applies
+ -mret-in-naked-func option. */
+ cfun->machine->attr_naked_p
+ = lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
+ ? 1 : 0;
+ cfun->machine->attr_no_prologue_p
+ = lookup_attribute ("no_prologue", DECL_ATTRIBUTES (current_function_decl))
+ ? 1 : 0;
/* If __builtin_eh_return is used, we better have frame pointer needed
so that we can easily locate the stack slot of return address. */
@@ -432,7 +456,8 @@
/* If $gp value is required to be saved on stack, it needs 4 bytes space.
Check whether we are using PIC code genration. */
- cfun->machine->gp_size = (flag_pic) ? 4 : 0;
+ cfun->machine->gp_size =
+ (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)) ? 4 : 0;
/* If $lp value is required to be saved on stack, it needs 4 bytes space.
Check whether $lp is ever live. */
@@ -497,7 +522,7 @@
}
/* Check if this function can omit prologue/epilogue code fragment.
- If there is 'naked' attribute in this function,
+ If there is 'no_prologue'/'naked'/'secure' attribute in this function,
we can set 'naked_p' flag to indicate that
we do not have to generate prologue/epilogue.
Or, if all the following conditions succeed,
@@ -510,14 +535,17 @@
is no outgoing size.
condition 3: There is no local_size, which means
we do not need to adjust $sp. */
- if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
+ if (lookup_attribute ("no_prologue", DECL_ATTRIBUTES (current_function_decl))
+ || lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
+ || lookup_attribute ("secure", DECL_ATTRIBUTES (current_function_decl))
|| (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM
&& cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM
&& cfun->machine->callee_saved_first_fpr_regno == SP_REGNUM
&& cfun->machine->callee_saved_last_fpr_regno == SP_REGNUM
&& !df_regs_ever_live_p (FP_REGNUM)
&& !df_regs_ever_live_p (LP_REGNUM)
- && cfun->machine->local_size == 0))
+ && cfun->machine->local_size == 0
+ && !flag_pic))
{
/* Set this function 'naked_p' and other functions can check this flag.
Note that in nds32 port, the 'naked_p = 1' JUST means there is no
@@ -1259,6 +1287,32 @@
REG_NOTES (parallel_insn) = dwarf;
}
+static void
+nds32_emit_load_gp (void)
+{
+ rtx got_symbol, pat;
+
+ /* Initial GLOBAL OFFSET TABLE don't do the scheduling. */
+ emit_insn (gen_blockage ());
+
+ got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ /* sethi $gp, _GLOBAL_OFFSET_TABLE_ -8 */
+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, got_symbol), UNSPEC_GOTINIT);
+ pat = gen_rtx_CONST (SImode, gen_rtx_PLUS (Pmode, pat, GEN_INT (-8)));
+ emit_insn (gen_sethi (pic_offset_table_rtx,pat));
+
+ /* ori $gp, $gp, _GLOBAL_OFFSET_TABLE_ -4 */
+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, got_symbol), UNSPEC_GOTINIT);
+ pat = gen_rtx_CONST (SImode, gen_rtx_PLUS (Pmode, pat, GEN_INT (-4)));
+ emit_insn (gen_lo_sum (pic_offset_table_rtx, pic_offset_table_rtx, pat));
+
+ /* add5.pc $gp */
+ emit_insn (gen_add_pc (pic_offset_table_rtx, pic_offset_table_rtx));
+
+ /* Initial GLOBAL OFFSET TABLE don't do the scheduling. */
+ emit_insn (gen_blockage ());
+}
+
/* Function that may creates more instructions
for large value on adjusting stack pointer.
@@ -1342,17 +1396,25 @@
}
/* Return true if FUNC is a naked function. */
-static bool
+bool
nds32_naked_function_p (tree func)
{
- tree t;
+ /* FOR BACKWARD COMPATIBILITY,
+ we need to support 'no_prologue' attribute as well. */
+ tree t_naked;
+ tree t_no_prologue;
if (TREE_CODE (func) != FUNCTION_DECL)
abort ();
- t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
+ /* We have to use lookup_attribute() to check attributes.
+ Because attr_naked_p and attr_no_prologue_p are set in
+ nds32_compute_stack_frame() and the function has not been
+ invoked yet. */
+ t_naked = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
+ t_no_prologue = lookup_attribute ("no_prologue", DECL_ATTRIBUTES (func));
- return (t != NULL_TREE);
+ return ((t_naked != NULL_TREE) || (t_no_prologue != NULL_TREE));
}
/* Function that determine whether a load postincrement is a good thing to use
@@ -1570,6 +1632,11 @@
nds32_register_passes (void)
{
nds32_register_pass (
+ make_pass_nds32_fp_as_gp,
+ PASS_POS_INSERT_BEFORE,
+ "ira");
+
+ nds32_register_pass (
make_pass_nds32_relax_opt,
PASS_POS_INSERT_AFTER,
"mach");
@@ -1636,6 +1703,9 @@
{
int regno;
+ if (TARGET_LINUX_ABI)
+ fixed_regs[TP_REGNUM] = 1;
+
if (TARGET_HARD_FLOAT)
{
for (regno = NDS32_FIRST_FPR_REGNUM;
@@ -1987,6 +2057,16 @@
: PARM_BOUNDARY);
}
+bool
+nds32_vector_mode_supported_p (machine_mode mode)
+{
+ if (mode == V4QImode
+ || mode == V2HImode)
+ return NDS32_EXT_DSP_P ();
+
+ return false;
+}
+
/* -- How Scalar Function Values Are Returned. */
static rtx
@@ -2124,56 +2204,12 @@
nds32_asm_function_end_prologue (FILE *file)
{
fprintf (file, "\t! END PROLOGUE\n");
-
- /* If frame pointer is NOT needed and -mfp-as-gp is issued,
- we can generate special directive: ".omit_fp_begin"
- to guide linker doing fp-as-gp optimization.
- However, for a naked function, which means
- it should not have prologue/epilogue,
- using fp-as-gp still requires saving $fp by push/pop behavior and
- there is no benefit to use fp-as-gp on such small function.
- So we need to make sure this function is NOT naked as well. */
- if (!frame_pointer_needed
- && !cfun->machine->naked_p
- && cfun->machine->fp_as_gp_p)
- {
- fprintf (file, "\t! ----------------------------------------\n");
- fprintf (file, "\t! Guide linker to do "
- "link time optimization: fp-as-gp\n");
- fprintf (file, "\t! We add one more instruction to "
- "initialize $fp near to $gp location.\n");
- fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
- fprintf (file, "\t! this extra instruction should be "
- "eliminated at link stage.\n");
- fprintf (file, "\t.omit_fp_begin\n");
- fprintf (file, "\tla\t$fp,_FP_BASE_\n");
- fprintf (file, "\t! ----------------------------------------\n");
- }
}
/* Before rtl epilogue has been expanded, this function is used. */
static void
nds32_asm_function_begin_epilogue (FILE *file)
{
- /* If frame pointer is NOT needed and -mfp-as-gp is issued,
- we can generate special directive: ".omit_fp_end"
- to claim fp-as-gp optimization range.
- However, for a naked function,
- which means it should not have prologue/epilogue,
- using fp-as-gp still requires saving $fp by push/pop behavior and
- there is no benefit to use fp-as-gp on such small function.
- So we need to make sure this function is NOT naked as well. */
- if (!frame_pointer_needed
- && !cfun->machine->naked_p
- && cfun->machine->fp_as_gp_p)
- {
- fprintf (file, "\t! ----------------------------------------\n");
- fprintf (file, "\t! Claim the range of fp-as-gp "
- "link time optimization\n");
- fprintf (file, "\t.omit_fp_end\n");
- fprintf (file, "\t! ----------------------------------------\n");
- }
-
fprintf (file, "\t! BEGIN EPILOGUE\n");
}
@@ -2200,6 +2236,26 @@
? 1
: 0);
+ if (flag_pic)
+ {
+ fprintf (file, "\tsmw.adm\t$r31, [$r31], $r31, 4\n");
+ fprintf (file, "\tsethi\t%s, hi20(_GLOBAL_OFFSET_TABLE_-8)\n",
+ reg_names [PIC_OFFSET_TABLE_REGNUM]);
+ fprintf (file, "\tori\t%s, %s, lo12(_GLOBAL_OFFSET_TABLE_-4)\n",
+ reg_names [PIC_OFFSET_TABLE_REGNUM],
+ reg_names [PIC_OFFSET_TABLE_REGNUM]);
+
+ if (TARGET_ISA_V3)
+ fprintf (file, "\tadd5.pc\t$gp\n");
+ else
+ {
+ fprintf (file, "\tmfusr\t$ta, $pc\n");
+ fprintf (file, "\tadd\t%s, $ta, %s\n",
+ reg_names [PIC_OFFSET_TABLE_REGNUM],
+ reg_names [PIC_OFFSET_TABLE_REGNUM]);
+ }
+ }
+
if (delta != 0)
{
if (satisfies_constraint_Is15 (GEN_INT (delta)))
@@ -2224,9 +2280,23 @@
}
}
- fprintf (file, "\tb\t");
- assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
- fprintf (file, "\n");
+ if (flag_pic)
+ {
+ fprintf (file, "\tla\t$ta, ");
+ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
+ fprintf (file, "@PLT\n");
+ fprintf (file, "\t! epilogue\n");
+ fprintf (file, "\tlwi.bi\t%s, [%s], 4\n",
+ reg_names[PIC_OFFSET_TABLE_REGNUM],
+ reg_names[STACK_POINTER_REGNUM]);
+ fprintf (file, "\tbr\t$ta\n");
+ }
+ else
+ {
+ fprintf (file, "\tb\t");
+ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
+ fprintf (file, "\n");
+ }
final_end_function ();
}
@@ -2242,15 +2312,20 @@
/* 1. Do not apply sibling call if -mv3push is enabled,
because pop25 instruction also represents return behavior.
- 2. If this function is a variadic function, do not apply sibling call
+ 2. If this function is a isr function, do not apply sibling call
+ because it may perform the behavior that user does not expect.
+ 3. If this function is a variadic function, do not apply sibling call
because the stack layout may be a mess.
- 3. We don't want to apply sibling call optimization for indirect
+ 4. We don't want to apply sibling call optimization for indirect
sibcall because the pop behavior in epilogue may pollute the
content of caller-saved regsiter when the register is used for
- indirect sibcall. */
+ indirect sibcall.
+ 5. In pic mode, it may use some registers for PLT call. */
return (!TARGET_V3PUSH
+ && !nds32_isr_function_p (current_function_decl)
&& (cfun->machine->va_args_size == 0)
- && decl);
+ && decl
+ && !flag_pic);
}
/* Determine whether we need to enable warning for function return check. */
@@ -2566,6 +2641,13 @@
case SYMBOL_REF:
/* (mem (symbol_ref A)) => [symbol_ref] */
+
+ if (flag_pic || SYMBOL_REF_TLS_MODEL (x))
+ return false;
+
+ if (TARGET_ICT_MODEL_LARGE && nds32_indirect_call_referenced_p (x))
+ return false;
+
/* If -mcmodel=large, the 'symbol_ref' is not a valid address
during or after LRA/reload phase. */
if (TARGET_CMODEL_LARGE
@@ -2577,7 +2659,8 @@
the 'symbol_ref' is not a valid address during or after
LRA/reload phase. */
if (TARGET_CMODEL_MEDIUM
- && NDS32_SYMBOL_REF_RODATA_P (x)
+ && (NDS32_SYMBOL_REF_RODATA_P (x)
+ || CONSTANT_POOL_ADDRESS_P (x))
&& (reload_completed
|| reload_in_progress
|| lra_in_progress))
@@ -2599,6 +2682,10 @@
{
/* Now we see the [ + const_addr ] pattern, but we need
some further checking. */
+
+ if (flag_pic || SYMBOL_REF_TLS_MODEL (op0))
+ return false;
+
/* If -mcmodel=large, the 'const_addr' is not a valid address
during or after LRA/reload phase. */
if (TARGET_CMODEL_LARGE
@@ -2675,17 +2762,202 @@
case LO_SUM:
/* (mem (lo_sum (reg) (symbol_ref))) */
- /* (mem (lo_sum (reg) (const))) */
- gcc_assert (REG_P (XEXP (x, 0)));
- if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
- || GET_CODE (XEXP (x, 1)) == CONST)
- return nds32_legitimate_address_p (mode, XEXP (x, 1), strict);
- else
+ /* (mem (lo_sum (reg) (const (plus (symbol_ref) (reg)))) */
+ /* TLS case: (mem (lo_sum (reg) (const (unspec symbol_ref X)))) */
+ /* The LO_SUM is a valid address if and only if we would like to
+ generate 32-bit full address memory access with any of following
+ circumstance:
+ 1. -mcmodel=large.
+ 2. -mcmodel=medium and the symbol_ref references to rodata. */
+ {
+ rtx sym = NULL_RTX;
+
+ if (flag_pic)
+ return false;
+
+ if (!REG_P (XEXP (x, 0)))
+ return false;
+
+ if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
+ sym = XEXP (x, 1);
+ else if (GET_CODE (XEXP (x, 1)) == CONST)
+ {
+ rtx plus = XEXP(XEXP (x, 1), 0);
+ if (GET_CODE (plus) == PLUS)
+ sym = XEXP (plus, 0);
+ else if (GET_CODE (plus) == UNSPEC)
+ sym = XVECEXP (plus, 0, 0);
+ }
+ else
+ return false;
+
+ gcc_assert (GET_CODE (sym) == SYMBOL_REF);
+
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (sym))
+ return true;
+
+ if (TARGET_CMODEL_LARGE)
+ return true;
+ else if (TARGET_CMODEL_MEDIUM
+ && NDS32_SYMBOL_REF_RODATA_P (sym))
+ return true;
+ else
+ return false;
+ }
+
+ default:
+ return false;
+ }
+}
+
+static rtx
+nds32_legitimize_address (rtx x,
+ rtx oldx ATTRIBUTE_UNUSED,
+ machine_mode mode ATTRIBUTE_UNUSED)
+{
+ if (nds32_tls_referenced_p (x))
+ x = nds32_legitimize_tls_address (x);
+ else if (flag_pic && SYMBOLIC_CONST_P (x))
+ x = nds32_legitimize_pic_address (x);
+ else if (TARGET_ICT_MODEL_LARGE && nds32_indirect_call_referenced_p (x))
+ x = nds32_legitimize_ict_address (x);
+
+ return x;
+}
+
+static bool
+nds32_legitimate_constant_p (machine_mode mode, rtx x)
+{
+ switch (GET_CODE (x))
+ {
+ case CONST_DOUBLE:
+ if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
+ && (mode == DFmode || mode == SFmode))
return false;
+ break;
+ case CONST:
+ x = XEXP (x, 0);
+
+ if (GET_CODE (x) == PLUS)
+ {
+ if (!CONST_INT_P (XEXP (x, 1)))
+ return false;
+ x = XEXP (x, 0);
+ }
+
+ if (GET_CODE (x) == UNSPEC)
+ {
+ switch (XINT (x, 1))
+ {
+ case UNSPEC_GOT:
+ case UNSPEC_GOTOFF:
+ case UNSPEC_PLT:
+ case UNSPEC_TLSGD:
+ case UNSPEC_TLSLD:
+ case UNSPEC_TLSIE:
+ case UNSPEC_TLSLE:
+ case UNSPEC_ICT:
+ return false;
+ default:
+ return true;
+ }
+ }
+ break;
+ case SYMBOL_REF:
+ /* TLS symbols need a call to resolve in
+ precompute_register_parameters. */
+ if (SYMBOL_REF_TLS_MODEL (x))
+ return false;
+ break;
+ default:
+ return true;
+ }
+
+ return true;
+}
+
+/* Reorgnize the UNSPEC CONST and return its direct symbol. */
+static rtx
+nds32_delegitimize_address (rtx x)
+{
+ x = delegitimize_mem_from_attrs (x);
+
+ if (GET_CODE(x) == CONST)
+ {
+ rtx inner = XEXP (x, 0);
+
+ /* Handle for GOTOFF. */
+ if (GET_CODE (inner) == PLUS)
+ inner = XEXP (inner, 0);
+
+ if (GET_CODE (inner) == UNSPEC)
+ {
+ switch (XINT (inner, 1))
+ {
+ case UNSPEC_GOTINIT:
+ case UNSPEC_GOT:
+ case UNSPEC_GOTOFF:
+ case UNSPEC_PLT:
+ case UNSPEC_TLSGD:
+ case UNSPEC_TLSLD:
+ case UNSPEC_TLSIE:
+ case UNSPEC_TLSLE:
+ case UNSPEC_ICT:
+ x = XVECEXP (inner, 0, 0);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return x;
+}
+static machine_mode
+nds32_vectorize_preferred_simd_mode (scalar_mode mode)
+{
+ if (!NDS32_EXT_DSP_P ())
+ return word_mode;
+
+ switch (mode)
+ {
+ case E_QImode:
+ return V4QImode;
+ case E_HImode:
+ return V2HImode;
+ default:
+ return word_mode;
+ }
+}
+
+static bool
+nds32_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ switch (GET_CODE (x))
+ {
+ case CONST:
+ return !nds32_legitimate_constant_p (mode, x);
+ case SYMBOL_REF:
+ /* All symbols have to be accessed through gp-relative in PIC mode. */
+ /* We don't want to force symbol as constant pool in .text section,
+ because we use the gp-relatived instruction to load in small
+ or medium model. */
+ if (flag_pic
+ || SYMBOL_REF_TLS_MODEL (x)
+ || TARGET_CMODEL_SMALL
+ || TARGET_CMODEL_MEDIUM)
+ return true;
+ break;
+ case CONST_INT:
+ case CONST_DOUBLE:
+ if (flag_pic && (lra_in_progress || reload_completed))
+ return true;
+ break;
default:
return false;
}
+ return false;
}
@@ -2731,13 +3003,33 @@
/* Describing Relative Costs of Operations. */
static int
-nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
+nds32_register_move_cost (machine_mode mode,
reg_class_t from,
reg_class_t to)
{
+ /* In garywolf cpu, FPR to GPR is chaper than other cpu. */
+ if (TARGET_PIPELINE_GRAYWOLF)
+ {
+ if (GET_MODE_SIZE (mode) == 8)
+ {
+ /* DPR to GPR. */
+ if (from == FP_REGS && to != FP_REGS)
+ return 3;
+ /* GPR to DPR. */
+ if (from != FP_REGS && to == FP_REGS)
+ return 2;
+ }
+ else
+ {
+ if ((from == FP_REGS && to != FP_REGS)
+ || (from != FP_REGS && to == FP_REGS))
+ return 2;
+ }
+ }
+
if ((from == FP_REGS && to != FP_REGS)
|| (from != FP_REGS && to == FP_REGS))
- return 9;
+ return 3;
else if (from == HIGH_REGS || to == HIGH_REGS)
return optimize_size ? 6 : 2;
else
@@ -2825,6 +3117,9 @@
{
default_file_start ();
+ if (flag_pic)
+ fprintf (asm_out_file, "\t.pic\n");
+
/* Tell assembler which ABI we are using. */
fprintf (asm_out_file, "\t! ABI version\n");
if (TARGET_HARD_FLOAT)
@@ -2835,10 +3130,36 @@
/* Tell assembler that this asm code is generated by compiler. */
fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
fprintf (asm_out_file, "\t.flag\tverbatim\n");
- /* Give assembler the size of each vector for interrupt handler. */
- fprintf (asm_out_file, "\t! This vector size directive is required "
- "for checking inconsistency on interrupt handler\n");
- fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
+
+ /* Insert directive for linker to distinguish object's ict flag. */
+ if (!TARGET_LINUX_ABI)
+ {
+ if (TARGET_ICT_MODEL_LARGE)
+ fprintf (asm_out_file, "\t.ict_model\tlarge\n");
+ else
+ fprintf (asm_out_file, "\t.ict_model\tsmall\n");
+ }
+
+ /* We need to provide the size of each vector for interrupt handler
+ under elf toolchain. */
+ if (!TARGET_LINUX_ABI)
+ {
+ fprintf (asm_out_file, "\t! This vector size directive is required "
+ "for checking inconsistency on interrupt handler\n");
+ fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
+ }
+
+ /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
+ the compiler may produce 'la $fp,_FP_BASE_' instruction
+ at prologue for fp-as-gp optimization.
+ We should emit weak reference of _FP_BASE_ to avoid undefined reference
+ in case user does not pass '--relax' option to linker. */
+ if (!TARGET_LINUX_ABI && (TARGET_FORCE_FP_AS_GP || optimize_size))
+ {
+ fprintf (asm_out_file, "\t! This weak reference is required to do "
+ "fp-as-gp link time optimization\n");
+ fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
+ }
fprintf (asm_out_file, "\t! ------------------------------------\n");
@@ -2849,6 +3170,49 @@
if (TARGET_ISA_V3M)
fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
+ switch (nds32_cpu_option)
+ {
+ case CPU_N6:
+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N6");
+ break;
+
+ case CPU_N7:
+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N7");
+ break;
+
+ case CPU_N8:
+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N8");
+ break;
+
+ case CPU_E8:
+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "E8");
+ break;
+
+ case CPU_N9:
+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N9");
+ break;
+
+ case CPU_N10:
+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N10");
+ break;
+
+ case CPU_GRAYWOLF:
+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "Graywolf");
+ break;
+
+ case CPU_N12:
+ case CPU_N13:
+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N13");
+ break;
+
+ case CPU_SIMPLE:
+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "SIMPLE");
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
if (TARGET_CMODEL_SMALL)
fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "SMALL");
if (TARGET_CMODEL_MEDIUM)
@@ -2926,9 +3290,65 @@
{
nds32_asm_file_end_for_isr ();
+ /* The NDS32 Linux stack is mapped non-executable by default, so add a
+ .note.GNU-stack section. */
+ if (TARGET_LINUX_ABI)
+ file_end_indicate_exec_stack ();
+
fprintf (asm_out_file, "\t! ------------------------------------\n");
}
+static bool
+nds32_asm_output_addr_const_extra (FILE *file, rtx x)
+{
+ if (GET_CODE (x) == UNSPEC)
+ {
+ switch (XINT (x, 1))
+ {
+ case UNSPEC_GOTINIT:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ break;
+ case UNSPEC_GOTOFF:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ fputs ("@GOTOFF", file);
+ break;
+ case UNSPEC_GOT:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ fputs ("@GOT", file);
+ break;
+ case UNSPEC_PLT:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ fputs ("@PLT", file);
+ break;
+ case UNSPEC_TLSGD:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ fputs ("@TLSDESC", file);
+ break;
+ case UNSPEC_TLSLD:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ fputs ("@TLSDESC", file);
+ break;
+ case UNSPEC_TLSIE:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ fputs ("@GOTTPOFF", file);
+ break;
+ case UNSPEC_TLSLE:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ fputs ("@TPOFF", file);
+ break;
+ case UNSPEC_ICT:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ fputs ("@ICT", file);
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+ else
+ return false;
+}
+
/* -- Output and Generation of Labels. */
static void
@@ -2978,6 +3398,18 @@
/* No need to handle following process, so return immediately. */
return;
+
+ case 'v':
+ gcc_assert (CONST_INT_P (x)
+ && (INTVAL (x) == 0
+ || INTVAL (x) == 8
+ || INTVAL (x) == 16
+ || INTVAL (x) == 24));
+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
+
+ /* No need to handle following process, so return immediately. */
+ return;
+
case 'B':
/* Use exact_log2() to search the 1-bit position. */
gcc_assert (CONST_INT_P (x));
@@ -3084,8 +3516,15 @@
switch (GET_CODE (x))
{
case LABEL_REF:
+ output_addr_const (stream, x);
+ break;
+
case SYMBOL_REF:
output_addr_const (stream, x);
+
+ if (!TARGET_LINUX_ABI && nds32_indirect_call_referenced_p (x))
+ fprintf (stream, "@ICT");
+
break;
case REG:
@@ -3168,6 +3607,17 @@
output_addr_const (stream, x);
break;
+ case CONST_VECTOR:
+ fprintf (stream, HOST_WIDE_INT_PRINT_HEX, const_vector_to_hwint (x));
+ break;
+
+ case LO_SUM:
+ /* This is a special case for inline assembly using memory address 'p'.
+ The inline assembly code is expected to use pesudo instruction
+ for the operand. EX: la */
+ output_addr_const (stream, XEXP(x, 1));
+ break;
+
default:
/* Generally, output_addr_const () is able to handle most cases.
We want to see what CODE could appear,
@@ -3179,7 +3629,9 @@
}
static void
-nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x)
+nds32_print_operand_address (FILE *stream,
+ machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x)
{
rtx op0, op1;
@@ -3194,6 +3646,16 @@
fputs ("]", stream);
break;
+ case LO_SUM:
+ /* This is a special case for inline assembly using memory operand 'm'.
+ The inline assembly code is expected to use pesudo instruction
+ for the operand. EX: [ls].[bhw] */
+ fputs ("[ + ", stream);
+ op1 = XEXP (x, 1);
+ output_addr_const (stream, op1);
+ fputs ("]", stream);
+ break;
+
case REG:
/* Forbid using static chain register ($r16)
on reduced-set registers configuration. */
@@ -3260,6 +3722,20 @@
reg_names[REGNO (XEXP (op0, 0))],
sv);
}
+ else if (GET_CODE (op0) == ASHIFT && REG_P (op1))
+ {
+ /* [Ra + Rb << sv]
+ In normal, ASHIFT can be converted to MULT like above case.
+ But when the address rtx does not go through canonicalize_address
+ defined in fwprop, we'll need this case. */
+ int sv = INTVAL (XEXP (op0, 1));
+ gcc_assert (sv <= 3 && sv >=0);
+
+ fprintf (stream, "[%s + %s << %d]",
+ reg_names[REGNO (op1)],
+ reg_names[REGNO (XEXP (op0, 0))],
+ sv);
+ }
else
{
/* The control flow is not supposed to be here. */
@@ -3454,6 +3930,27 @@
static void
nds32_insert_attributes (tree decl, tree *attributes)
{
+ /* A "indirect_call" function attribute implies "noinline" and "noclone"
+ for elf toolchain to support ROM patch mechanism. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && lookup_attribute ("indirect_call", *attributes) != NULL)
+ {
+ tree new_attrs = *attributes;
+
+ if (TARGET_LINUX_ABI)
+ error("cannot use indirect_call attribute under linux toolchain");
+
+ if (lookup_attribute ("noinline", new_attrs) == NULL)
+ new_attrs = tree_cons (get_identifier ("noinline"), NULL, new_attrs);
+ if (lookup_attribute ("noclone", new_attrs) == NULL)
+ new_attrs = tree_cons (get_identifier ("noclone"), NULL, new_attrs);
+
+ if (!TREE_PUBLIC (decl))
+ error("indirect_call attribute can't apply for static function");
+
+ *attributes = new_attrs;
+ }
+
/* For function declaration, we need to check isr-specific attributes:
1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2. Check valid integer value for interrupt/exception.
@@ -3479,6 +3976,38 @@
excp = lookup_attribute ("exception", func_attrs);
reset = lookup_attribute ("reset", func_attrs);
+ /* The following code may use attribute arguments. If there is no
+ argument from source code, it will cause segmentation fault.
+ Therefore, return dircetly and report error message later. */
+ if ((intr && TREE_VALUE (intr) == NULL)
+ || (excp && TREE_VALUE (excp) == NULL)
+ || (reset && TREE_VALUE (reset) == NULL))
+ return;
+
+ /* ------------------------------------------------------------- */
+ /* FIXME:
+ FOR BACKWARD COMPATIBILITY, we need to support following patterns:
+
+ __attribute__((interrupt("XXX;YYY;id=ZZZ")))
+ __attribute__((exception("XXX;YYY;id=ZZZ")))
+ __attribute__((reset("vectors=XXX;nmi_func=YYY;warm_func=ZZZ")))
+
+ If interrupt/exception/reset appears and its argument is a
+ STRING_CST, we will use other functions to parse string in the
+ nds32_construct_isr_vectors_information() and then set necessary
+ isr information in the nds32_isr_vectors[] array. Here we can
+ just return immediately to avoid new-syntax checking. */
+ if (intr != NULL_TREE
+ && TREE_CODE (TREE_VALUE (TREE_VALUE (intr))) == STRING_CST)
+ return;
+ if (excp != NULL_TREE
+ && TREE_CODE (TREE_VALUE (TREE_VALUE (excp))) == STRING_CST)
+ return;
+ if (reset != NULL_TREE
+ && TREE_CODE (TREE_VALUE (TREE_VALUE (reset))) == STRING_CST)
+ return;
+ /* ------------------------------------------------------------- */
+
if (intr || excp)
{
/* Deal with interrupt/exception. */
@@ -3598,7 +4127,9 @@
}
if (TARGET_ISA_V3)
{
- /* Under V3 ISA, currently nothing should be strictly set. */
+ /* If this is ARCH_V3J, we need to enable TARGET_REDUCED_REGS. */
+ if (nds32_arch_option == ARCH_V3J)
+ target_flags |= MASK_REDUCED_REGS;
}
if (TARGET_ISA_V3M)
{
@@ -3610,6 +4141,9 @@
target_flags &= ~MASK_EXT_PERF2;
/* Under V3M ISA, we need to strictly disable TARGET_EXT_STRING. */
target_flags &= ~MASK_EXT_STRING;
+
+ if (flag_pic)
+ error ("not support -fpic option for v3m toolchain");
}
/* See if we are using reduced-set registers:
@@ -3627,6 +4161,12 @@
fixed_regs[r] = call_used_regs[r] = 1;
}
+ /* See if user explicitly would like to use fp-as-gp optimization.
+ If so, we must prevent $fp from being allocated
+ during register allocation. */
+ if (TARGET_FORCE_FP_AS_GP)
+ fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
+
if (!TARGET_16_BIT)
{
/* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
@@ -3643,9 +4183,7 @@
"must be enable '-mext-fpu-sp' or '-mext-fpu-dp'");
}
- /* Currently, we don't support PIC code generation yet. */
- if (flag_pic)
- sorry ("position-independent code not supported");
+ nds32_init_rtx_costs ();
nds32_register_passes ();
}
@@ -3659,8 +4197,11 @@
vec<const char *> &constraints ATTRIBUTE_UNUSED,
vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs)
{
- clobbers.safe_push (gen_rtx_REG (SImode, TA_REGNUM));
- SET_HARD_REG_BIT (clobbered_regs, TA_REGNUM);
+ if (!flag_inline_asm_r15)
+ {
+ clobbers.safe_push (gen_rtx_REG (SImode, TA_REGNUM));
+ SET_HARD_REG_BIT (clobbered_regs, TA_REGNUM);
+ }
return NULL;
}
@@ -3687,6 +4228,13 @@
return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
}
+/* Implement TARGET_INIT_LIBFUNCS. */
+static void
+nds32_init_libfuncs (void)
+{
+ if (TARGET_LINUX_ABI)
+ init_sync_libfuncs (UNITS_PER_WORD);
+}
/* ------------------------------------------------------------------------ */
@@ -3703,6 +4251,16 @@
builtin_define ("__nds32__");
builtin_define ("__NDS32__");
+ /* We need to provide builtin macro to describe the size of
+ each vector for interrupt handler under elf toolchain. */
+ if (!TARGET_LINUX_ABI)
+ {
+ if (TARGET_ISR_VECTOR_SIZE_4_BYTE)
+ builtin_define ("__NDS32_ISR_VECTOR_SIZE_4__");
+ else
+ builtin_define ("__NDS32_ISR_VECTOR_SIZE_16__");
+ }
+
if (TARGET_HARD_FLOAT)
builtin_define ("__NDS32_ABI_2FP_PLUS__");
else
@@ -3770,6 +4328,8 @@
builtin_define ("__NDS32_GP_DIRECT__");
if (TARGET_VH)
builtin_define ("__NDS32_VH__");
+ if (NDS32_EXT_DSP_P ())
+ builtin_define ("__NDS32_EXT_DSP__");
if (TARGET_BIG_ENDIAN)
builtin_define ("__big_endian__");
@@ -4042,6 +4602,10 @@
The result will be in cfun->machine. */
nds32_compute_stack_frame ();
+ /* Check frame_pointer_needed again to prevent fp is need after reload. */
+ if (frame_pointer_needed)
+ cfun->machine->fp_as_gp_p = false;
+
/* If this is a variadic function, first we need to push argument
registers that hold the unnamed argument value. */
if (cfun->machine->va_args_size != 0)
@@ -4066,7 +4630,7 @@
/* If the function is 'naked',
we do not have to generate prologue code fragment. */
- if (cfun->machine->naked_p)
+ if (cfun->machine->naked_p && !flag_pic)
return;
/* Get callee_first_regno and callee_last_regno. */
@@ -4195,9 +4759,15 @@
-1 * sp_adjust);
}
- /* Prevent the instruction scheduler from
- moving instructions across the boundary. */
- emit_insn (gen_blockage ());
+ /* Emit gp setup instructions for -fpic. */
+ if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
+ nds32_emit_load_gp ();
+
+ /* If user applies -mno-sched-prolog-epilog option,
+ we need to prevent instructions of function body from being
+ scheduled with stack adjustment in prologue. */
+ if (!flag_sched_prolog_epilog)
+ emit_insn (gen_blockage ());
}
/* Function for normal multiple pop epilogue. */
@@ -4211,9 +4781,11 @@
The result will be in cfun->machine. */
nds32_compute_stack_frame ();
- /* Prevent the instruction scheduler from
- moving instructions across the boundary. */
- emit_insn (gen_blockage ());
+ /* If user applies -mno-sched-prolog-epilog option,
+ we need to prevent instructions of function body from being
+ scheduled with stack adjustment in epilogue. */
+ if (!flag_sched_prolog_epilog)
+ emit_insn (gen_blockage ());
/* If the function is 'naked', we do not have to generate
epilogue code fragment BUT 'ret' instruction.
@@ -4239,7 +4811,16 @@
/* Generate return instruction by using 'return_internal' pattern.
Make sure this instruction is after gen_blockage(). */
if (!sibcall_p)
- emit_jump_insn (gen_return_internal ());
+ {
+ /* We need to further check attributes to determine whether
+ there should be return instruction at epilogue.
+ If the attribute naked exists but -mno-ret-in-naked-func
+ is issued, there is NO need to generate return instruction. */
+ if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func)
+ return;
+
+ emit_jump_insn (gen_return_internal ());
+ }
return;
}
@@ -4436,9 +5017,13 @@
if (cfun->machine->callee_saved_gpr_regs_size > 0)
df_set_regs_ever_live (FP_REGNUM, 1);
+ /* Check frame_pointer_needed again to prevent fp is need after reload. */
+ if (frame_pointer_needed)
+ cfun->machine->fp_as_gp_p = false;
+
/* If the function is 'naked',
we do not have to generate prologue code fragment. */
- if (cfun->machine->naked_p)
+ if (cfun->machine->naked_p && !flag_pic)
return;
/* Get callee_first_regno and callee_last_regno. */
@@ -4566,6 +5151,10 @@
-1 * sp_adjust);
}
+ /* Emit gp setup instructions for -fpic. */
+ if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
+ nds32_emit_load_gp ();
+
/* Prevent the instruction scheduler from
moving instructions across the boundary. */
emit_insn (gen_blockage ());
@@ -4591,9 +5180,19 @@
if (cfun->machine->naked_p)
{
/* Generate return instruction by using 'return_internal' pattern.
- Make sure this instruction is after gen_blockage(). */
+ Make sure this instruction is after gen_blockage().
+ First we need to check this is a function without sibling call. */
if (!sibcall_p)
- emit_jump_insn (gen_return_internal ());
+ {
+ /* We need to further check attributes to determine whether
+ there should be return instruction at epilogue.
+ If the attribute naked exists but -mno-ret-in-naked-func
+ is issued, there is NO need to generate return instruction. */
+ if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func)
+ return;
+
+ emit_jump_insn (gen_return_internal ());
+ }
return;
}
@@ -4757,6 +5356,11 @@
if (!reload_completed)
return 0;
+ /* If attribute 'naked' appears but -mno-ret-in-naked-func is used,
+ we cannot use return instruction. */
+ if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func)
+ return 0;
+
sp_adjust = cfun->machine->local_size
+ cfun->machine->out_args_size
+ cfun->machine->callee_saved_area_gpr_padding_bytes
@@ -5010,6 +5614,9 @@
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
+#undef TARGET_VECTOR_MODE_SUPPORTED_P
+#define TARGET_VECTOR_MODE_SUPPORTED_P nds32_vector_mode_supported_p
+
/* -- How Scalar Function Values Are Returned. */
#undef TARGET_FUNCTION_VALUE
@@ -5087,6 +5694,21 @@
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS nds32_legitimize_address
+
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P nds32_legitimate_constant_p
+
+#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
+#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE nds32_vectorize_preferred_simd_mode
+
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM nds32_cannot_force_const_mem
+
+#undef TARGET_DELEGITIMIZE_ADDRESS
+#define TARGET_DELEGITIMIZE_ADDRESS nds32_delegitimize_address
+
/* Anchored Addresses. */
@@ -5147,6 +5769,9 @@
#undef TARGET_ASM_ALIGNED_SI_OP
#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
+#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
+#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nds32_asm_output_addr_const_extra
+
/* -- Output of Uninitialized Variables. */
/* -- Output and Generation of Labels. */
@@ -5216,6 +5841,9 @@
/* Emulating TLS. */
+#undef TARGET_HAVE_TLS
+#define TARGET_HAVE_TLS TARGET_LINUX_ABI
+
/* Defining coprocessor specifics for MIPS targets. */
@@ -5243,6 +5871,8 @@
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN nds32_expand_builtin
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS nds32_init_libfuncs
#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
#define TARGET_USE_BLOCKS_FOR_CONSTANT_P nds32_use_blocks_for_constant_p
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-cost.c gcc-8.2.0/gcc/config/nds32/nds32-cost.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-cost.c 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-cost.c 2019-01-25 15:38:32.821242637 +0100
@@ -34,66 +34,379 @@
#include "optabs.h" /* For GEN_FCN. */
#include "recog.h"
#include "tm-constrs.h"
+#include "tree-pass.h"
/* ------------------------------------------------------------------------ */
-bool
-nds32_rtx_costs_impl (rtx x,
- machine_mode mode ATTRIBUTE_UNUSED,
- int outer_code,
- int opno ATTRIBUTE_UNUSED,
- int *total,
- bool speed)
-{
- int code = GET_CODE (x);
+typedef bool (*rtx_cost_func) (rtx, int, int, int, int*);
- /* According to 'speed', goto suitable cost model section. */
- if (speed)
- goto performance_cost;
- else
- goto size_cost;
-
-
-performance_cost:
- /* This is section for performance cost model. */
+struct rtx_cost_model_t {
+ rtx_cost_func speed_prefer;
+ rtx_cost_func size_prefer;
+};
+
+static rtx_cost_model_t rtx_cost_model;
+
+static int insn_size_16bit; /* Initial at nds32_init_rtx_costs. */
+static const int insn_size_32bit = 4;
+
+static bool
+nds32_rtx_costs_speed_prefer (rtx x ATTRIBUTE_UNUSED,
+ int code,
+ int outer_code ATTRIBUTE_UNUSED,
+ int opno ATTRIBUTE_UNUSED,
+ int *total)
+{
+ rtx op0;
+ rtx op1;
+ machine_mode mode = GET_MODE (x);
+ /* Scale cost by mode size. */
+ int cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode));
- /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
- We treat it as 4-cycle cost for each instruction
- under performance consideration. */
switch (code)
{
- case SET:
- /* For 'SET' rtx, we need to return false
- so that it can recursively calculate costs. */
- return false;
-
case USE:
/* Used in combine.c as a marker. */
*total = 0;
- break;
+ return true;
+
+ case CONST_INT:
+ /* When not optimizing for size, we care more about the cost
+ of hot code, and hot code is often in a loop. If a constant
+ operand needs to be forced into a register, we will often be
+ able to hoist the constant load out of the loop, so the load
+ should not contribute to the cost. */
+ if (outer_code == SET || outer_code == PLUS)
+ *total = satisfies_constraint_Is20 (x) ? 0 : 4;
+ else if (outer_code == AND || outer_code == IOR || outer_code == XOR
+ || outer_code == MINUS)
+ *total = satisfies_constraint_Iu15 (x) ? 0 : 4;
+ else if (outer_code == ASHIFT || outer_code == ASHIFTRT
+ || outer_code == LSHIFTRT)
+ *total = satisfies_constraint_Iu05 (x) ? 0 : 4;
+ else if (GET_RTX_CLASS (outer_code) == RTX_COMPARE
+ || GET_RTX_CLASS (outer_code) == RTX_COMM_COMPARE)
+ *total = satisfies_constraint_Is16 (x) ? 0 : 4;
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case CONST:
+ case LO_SUM:
+ case HIGH:
+ case SYMBOL_REF:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case MEM:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case SET:
+ op0 = SET_DEST (x);
+ op1 = SET_SRC (x);
+ mode = GET_MODE (op0);
+ /* Scale cost by mode size. */
+ cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode));
+
+ switch (GET_CODE (op1))
+ {
+ case REG:
+ case SUBREG:
+ /* Register move and Store instructions. */
+ if ((REG_P (op0) || MEM_P (op0))
+ && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode))
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = cost;
+ return true;
+
+ case MEM:
+ /* Load instructions. */
+ if (REG_P (op0) && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode))
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = cost;
+ return true;
+
+ case CONST_INT:
+ /* movi instruction. */
+ if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode))
+ {
+ if (satisfies_constraint_Is20 (op1))
+ *total = COSTS_N_INSNS (1) - 1;
+ else
+ *total = COSTS_N_INSNS (2);
+ }
+ else
+ *total = cost;
+ return true;
+
+ case CONST:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ /* la instruction. */
+ if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode))
+ *total = COSTS_N_INSNS (1) - 1;
+ else
+ *total = cost;
+ return true;
+ case VEC_SELECT:
+ *total = cost;
+ return true;
+
+ default:
+ *total = cost;
+ return true;
+ }
+
+ case PLUS:
+ op0 = XEXP (x, 0);
+ op1 = XEXP (x, 1);
+
+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
+ *total = cost;
+ else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT
+ || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT)
+ /* ALU_SHIFT */
+ *total = COSTS_N_INSNS (2);
+
+ else if ((GET_CODE (op1) == CONST_INT
+ && satisfies_constraint_Is15 (op1))
+ || REG_P (op1))
+ /* ADD instructions */
+ *total = COSTS_N_INSNS (1);
+ else
+ /* ADD instructions: IMM out of range. */
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case MINUS:
+ op0 = XEXP (x, 0);
+ op1 = XEXP (x, 1);
+
+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
+ *total = cost;
+ else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT
+ || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT)
+ /* ALU_SHIFT */
+ *total = COSTS_N_INSNS (2);
+ else if ((GET_CODE (op0) == CONST_INT
+ && satisfies_constraint_Is15 (op0))
+ || REG_P (op0))
+ /* SUB instructions */
+ *total = COSTS_N_INSNS (1);
+ else
+ /* SUB instructions: IMM out of range. */
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case TRUNCATE:
+ /* TRUNCATE and AND behavior is same. */
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case AND:
+ case IOR:
+ case XOR:
+ op0 = XEXP (x, 0);
+ op1 = XEXP (x, 1);
+
+ if (NDS32_EXT_DSP_P ())
+ {
+ /* We prefer (and (ior) (ior)) than (ior (and) (and)) for
+ synthetize pk** and insb instruction. */
+ if (code == AND && GET_CODE (op0) == IOR && GET_CODE (op1) == IOR)
+ return COSTS_N_INSNS (1);
+
+ if (code == IOR && GET_CODE (op0) == AND && GET_CODE (op1) == AND)
+ return COSTS_N_INSNS (10);
+ }
+
+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
+ *total = cost;
+ else if (GET_CODE (op0) == ASHIFT || GET_CODE (op0) == LSHIFTRT)
+ *total = COSTS_N_INSNS (2);
+ else if ((GET_CODE (op1) == CONST_INT
+ && satisfies_constraint_Iu15 (op1))
+ || REG_P (op1))
+ /* AND, OR, XOR instructions */
+ *total = COSTS_N_INSNS (1);
+ else if (code == AND || GET_CODE (op0) == NOT)
+ /* BITC instruction */
+ *total = COSTS_N_INSNS (1);
+ else
+ /* AND, OR, XOR instructions: IMM out of range. */
+ *total = COSTS_N_INSNS (2);
+ return true;
case MULT:
+ if (GET_MODE (x) == DImode
+ || GET_CODE (XEXP (x, 1)) == SIGN_EXTEND
+ || GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
+ /* MUL instructions */
+ *total = COSTS_N_INSNS (1);
+ else if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
+ *total = cost;
+ else if (outer_code == PLUS || outer_code == MINUS)
+ *total = COSTS_N_INSNS (2);
+ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && satisfies_constraint_Iu05 (XEXP (x, 1)))
+ || REG_P (XEXP (x, 1)))
+ /* MUL instructions */
+ *total = COSTS_N_INSNS (1);
+ else
+ /* MUL instructions: IMM out of range. */
+ *total = COSTS_N_INSNS (2);
+
+ if (TARGET_MUL_SLOW)
+ *total += COSTS_N_INSNS (4);
+
+ return true;
+
+ case LSHIFTRT:
+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
+ *total = cost;
+ else if (outer_code == PLUS || outer_code == MINUS
+ || outer_code == AND || outer_code == IOR
+ || outer_code == XOR)
+ *total = COSTS_N_INSNS (2);
+ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && satisfies_constraint_Iu05 (XEXP (x, 1)))
+ || REG_P (XEXP (x, 1)))
+ /* SRL instructions */
+ *total = COSTS_N_INSNS (1);
+ else
+ /* SRL instructions: IMM out of range. */
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case ASHIFT:
+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
+ *total = cost;
+ else if (outer_code == AND || outer_code == IOR
+ || outer_code == XOR)
+ *total = COSTS_N_INSNS (2);
+ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && satisfies_constraint_Iu05 (XEXP (x, 1)))
+ || REG_P (XEXP (x, 1)))
+ /* SLL instructions */
+ *total = COSTS_N_INSNS (1);
+ else
+ /* SLL instructions: IMM out of range. */
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case ASHIFTRT:
+ case ROTATERT:
+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
+ *total = cost;
+ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && satisfies_constraint_Iu05 (XEXP (x, 1)))
+ || REG_P (XEXP (x, 1)))
+ /* ROTR, SLL instructions */
+ *total = COSTS_N_INSNS (1);
+ else
+ /* ROTR, SLL instructions: IMM out of range. */
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case LT:
+ case LTU:
+ if (outer_code == SET)
+ {
+ if ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && satisfies_constraint_Iu15 (XEXP (x, 1)))
+ || REG_P (XEXP (x, 1)))
+ /* SLT, SLTI instructions */
+ *total = COSTS_N_INSNS (1);
+ else
+ /* SLT, SLT instructions: IMM out of range. */
+ *total = COSTS_N_INSNS (2);
+ }
+ else
+ /* branch */
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case EQ:
+ case NE:
+ case GE:
+ case LE:
+ case GT:
+ /* branch */
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case IF_THEN_ELSE:
+ if (GET_CODE (XEXP (x, 1)) == LABEL_REF)
+ /* branch */
+ *total = COSTS_N_INSNS (2);
+ else
+ /* cmovz, cmovn instructions */
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case LABEL_REF:
+ if (outer_code == IF_THEN_ELSE)
+ /* branch */
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case ZERO_EXTEND:
+ case SIGN_EXTEND:
+ if (MEM_P (XEXP (x, 0)))
+ /* Using memory access. */
+ *total = COSTS_N_INSNS (1);
+ else
+ /* Zero extend and sign extend instructions. */
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case NEG:
+ case NOT:
*total = COSTS_N_INSNS (1);
- break;
+ return true;
case DIV:
case UDIV:
case MOD:
case UMOD:
- *total = COSTS_N_INSNS (7);
- break;
-
- default:
- *total = COSTS_N_INSNS (1);
- break;
- }
+ *total = COSTS_N_INSNS (20);
+ return true;
- return true;
+ case CALL:
+ *total = COSTS_N_INSNS (2);
+ return true;
+ case CLZ:
+ case SMIN:
+ case SMAX:
+ case ZERO_EXTRACT:
+ if (TARGET_EXT_PERF)
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = COSTS_N_INSNS (3);
+ return true;
+ case VEC_SELECT:
+ *total = COSTS_N_INSNS (1);
+ return true;
-size_cost:
- /* This is section for size cost model. */
+ default:
+ *total = COSTS_N_INSNS (3);
+ return true;
+ }
+}
+static bool
+nds32_rtx_costs_size_prefer (rtx x,
+ int code,
+ int outer_code,
+ int opno ATTRIBUTE_UNUSED,
+ int *total)
+{
/* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
We treat it as 4-byte cost for each instruction
under code size consideration. */
@@ -118,85 +431,162 @@
(set X imm20s), use movi, 4-byte cost.
(set X BIG_INT), use sethi/ori, 8-byte cost. */
if (satisfies_constraint_Is05 (x))
- *total = COSTS_N_INSNS (1) - 2;
+ *total = insn_size_16bit;
else if (satisfies_constraint_Is20 (x))
- *total = COSTS_N_INSNS (1);
+ *total = insn_size_32bit;
else
- *total = COSTS_N_INSNS (2);
+ *total = insn_size_32bit * 2;
}
else if (outer_code == PLUS || outer_code == MINUS)
{
/* Possible addi333/subi333 or subi45/addi45, 2-byte cost.
General case, cost 1 instruction with 4-byte. */
if (satisfies_constraint_Iu05 (x))
- *total = COSTS_N_INSNS (1) - 2;
+ *total = insn_size_16bit;
else
- *total = COSTS_N_INSNS (1);
+ *total = insn_size_32bit;
}
else if (outer_code == ASHIFT)
{
/* Possible slli333, 2-byte cost.
General case, cost 1 instruction with 4-byte. */
if (satisfies_constraint_Iu03 (x))
- *total = COSTS_N_INSNS (1) - 2;
+ *total = insn_size_16bit;
else
- *total = COSTS_N_INSNS (1);
+ *total = insn_size_32bit;
}
else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
{
/* Possible srai45 or srli45, 2-byte cost.
General case, cost 1 instruction with 4-byte. */
if (satisfies_constraint_Iu05 (x))
- *total = COSTS_N_INSNS (1) - 2;
+ *total = insn_size_16bit;
else
- *total = COSTS_N_INSNS (1);
+ *total = insn_size_32bit;
}
else
{
/* For other cases, simply set it 4-byte cost. */
- *total = COSTS_N_INSNS (1);
+ *total = insn_size_32bit;
}
break;
case CONST_DOUBLE:
/* It requires high part and low part processing, set it 8-byte cost. */
- *total = COSTS_N_INSNS (2);
+ *total = insn_size_32bit * 2;
+ break;
+
+ case CONST:
+ case SYMBOL_REF:
+ *total = insn_size_32bit * 2;
break;
default:
/* For other cases, generally we set it 4-byte cost
- and stop resurively traversing. */
- *total = COSTS_N_INSNS (1);
+ and stop resurively traversing. */
+ *total = insn_size_32bit;
break;
}
return true;
}
-int
-nds32_address_cost_impl (rtx address,
- machine_mode mode ATTRIBUTE_UNUSED,
- addr_space_t as ATTRIBUTE_UNUSED,
- bool speed)
+void
+nds32_init_rtx_costs (void)
+{
+ rtx_cost_model.speed_prefer = nds32_rtx_costs_speed_prefer;
+ rtx_cost_model.size_prefer = nds32_rtx_costs_size_prefer;
+
+ if (TARGET_16_BIT)
+ insn_size_16bit = 2;
+ else
+ insn_size_16bit = 4;
+}
+
+/* This target hook describes the relative costs of RTL expressions.
+ Return 'true' when all subexpressions of x have been processed.
+ Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
+ Refer to gcc/rtlanal.c for more information. */
+bool
+nds32_rtx_costs_impl (rtx x,
+ machine_mode mode ATTRIBUTE_UNUSED,
+ int outer_code,
+ int opno,
+ int *total,
+ bool speed)
+{
+ int code = GET_CODE (x);
+
+ /* According to 'speed', use suitable cost model section. */
+ if (speed)
+ return rtx_cost_model.speed_prefer(x, code, outer_code, opno, total);
+ else
+ return rtx_cost_model.size_prefer(x, code, outer_code, opno, total);
+}
+
+
+int nds32_address_cost_speed_prefer (rtx address)
{
rtx plus0, plus1;
enum rtx_code code;
code = GET_CODE (address);
- /* According to 'speed', goto suitable cost model section. */
- if (speed)
- goto performance_cost;
- else
- goto size_cost;
+ switch (code)
+ {
+ case POST_MODIFY:
+ case POST_INC:
+ case POST_DEC:
+ /* We encourage that rtx contains
+ POST_MODIFY/POST_INC/POST_DEC behavior. */
+ return COSTS_N_INSNS (1) - 2;
+
+ case SYMBOL_REF:
+ /* We can have gp-relative load/store for symbol_ref.
+ Have it 4-byte cost. */
+ return COSTS_N_INSNS (2);
+
+ case CONST:
+ /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
+ Have it 4-byte cost. */
+ return COSTS_N_INSNS (2);
+
+ case REG:
+ /* Simply return 4-byte costs. */
+ return COSTS_N_INSNS (1) - 2;
+
+ case PLUS:
+ /* We do not need to check if the address is a legitimate address,
+ because this hook is never called with an invalid address.
+ But we better check the range of
+ const_int value for cost, if it exists. */
+ plus0 = XEXP (address, 0);
+ plus1 = XEXP (address, 1);
-performance_cost:
- /* This is section for performance cost model. */
+ if (REG_P (plus0) && CONST_INT_P (plus1))
+ return COSTS_N_INSNS (1) - 2;
+ else if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1))
+ return COSTS_N_INSNS (1) - 1;
+ else if (REG_P (plus0) && REG_P (plus1))
+ return COSTS_N_INSNS (1);
- /* FALLTHRU, currently we use same cost model as size_cost. */
+ /* For other 'plus' situation, make it cost 4-byte. */
+ return COSTS_N_INSNS (1);
-size_cost:
- /* This is section for size cost model. */
+ default:
+ break;
+ }
+
+ return COSTS_N_INSNS (4);
+
+}
+
+int nds32_address_cost_speed_fwprop (rtx address)
+{
+ rtx plus0, plus1;
+ enum rtx_code code;
+
+ code = GET_CODE (address);
switch (code)
{
@@ -210,12 +600,12 @@
case SYMBOL_REF:
/* We can have gp-relative load/store for symbol_ref.
Have it 4-byte cost. */
- return COSTS_N_INSNS (1);
+ return COSTS_N_INSNS (2);
case CONST:
/* It is supposed to be the pattern (const (plus symbol_ref const_int)).
Have it 4-byte cost. */
- return COSTS_N_INSNS (1);
+ return COSTS_N_INSNS (2);
case REG:
/* Simply return 4-byte costs. */
@@ -233,11 +623,78 @@
{
/* If it is possible to be lwi333/swi333 form,
make it 2-byte cost. */
- if (satisfies_constraint_Iu05 (plus1))
+ if (satisfies_constraint_Iu03 (plus1))
return (COSTS_N_INSNS (1) - 2);
else
return COSTS_N_INSNS (1);
}
+ if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1))
+ return COSTS_N_INSNS (1) - 2;
+ else if (REG_P (plus0) && REG_P (plus1))
+ return COSTS_N_INSNS (1);
+
+ /* For other 'plus' situation, make it cost 4-byte. */
+ return COSTS_N_INSNS (1);
+
+ default:
+ break;
+ }
+
+ return COSTS_N_INSNS (4);
+}
+
+
+int nds32_address_cost_size_prefer (rtx address)
+{
+ rtx plus0, plus1;
+ enum rtx_code code;
+
+ code = GET_CODE (address);
+
+ switch (code)
+ {
+ case POST_MODIFY:
+ case POST_INC:
+ case POST_DEC:
+ /* We encourage that rtx contains
+ POST_MODIFY/POST_INC/POST_DEC behavior. */
+ return 0;
+
+ case SYMBOL_REF:
+ /* We can have gp-relative load/store for symbol_ref.
+ Have it 4-byte cost. */
+ return COSTS_N_INSNS (2);
+
+ case CONST:
+ /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
+ Have it 4-byte cost. */
+ return COSTS_N_INSNS (2);
+
+ case REG:
+ /* Simply return 4-byte costs. */
+ return COSTS_N_INSNS (1) - 1;
+
+ case PLUS:
+ /* We do not need to check if the address is a legitimate address,
+ because this hook is never called with an invalid address.
+ But we better check the range of
+ const_int value for cost, if it exists. */
+ plus0 = XEXP (address, 0);
+ plus1 = XEXP (address, 1);
+
+ if (REG_P (plus0) && CONST_INT_P (plus1))
+ {
+ /* If it is possible to be lwi333/swi333 form,
+ make it 2-byte cost. */
+ if (satisfies_constraint_Iu03 (plus1))
+ return (COSTS_N_INSNS (1) - 2);
+ else
+ return COSTS_N_INSNS (1) - 1;
+ }
+
+ /* (plus (reg) (mult (reg) (const))) */
+ if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1))
+ return (COSTS_N_INSNS (1) - 1);
/* For other 'plus' situation, make it cost 4-byte. */
return COSTS_N_INSNS (1);
@@ -247,6 +704,23 @@
}
return COSTS_N_INSNS (4);
+
+}
+
+int nds32_address_cost_impl (rtx address,
+ machine_mode mode ATTRIBUTE_UNUSED,
+ addr_space_t as ATTRIBUTE_UNUSED,
+ bool speed_p)
+{
+ if (speed_p)
+ {
+ if (current_pass->tv_id == TV_FWPROP)
+ return nds32_address_cost_speed_fwprop (address);
+ else
+ return nds32_address_cost_speed_prefer (address);
+ }
+ else
+ return nds32_address_cost_size_prefer (address);
}
/* ------------------------------------------------------------------------ */
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-doubleword.md gcc-8.2.0/gcc/config/nds32/nds32-doubleword.md
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-doubleword.md 2018-05-07 04:09:58.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-doubleword.md 2019-01-25 15:38:32.821242637 +0100
@@ -136,10 +136,28 @@
}
)
+;; Split move_di pattern when the hard register is odd.
+(define_split
+ [(set (match_operand:DIDF 0 "register_operand" "")
+ (match_operand:DIDF 1 "register_operand" ""))]
+ "(NDS32_IS_GPR_REGNUM (REGNO (operands[0]))
+ && ((REGNO (operands[0]) & 0x1) == 1))
+ || (NDS32_IS_GPR_REGNUM (REGNO (operands[1]))
+ && ((REGNO (operands[1]) & 0x1) == 1))"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 4) (match_dup 5))]
+ {
+ operands[2] = gen_lowpart (SImode, operands[0]);
+ operands[4] = gen_highpart (SImode, operands[0]);
+ operands[3] = gen_lowpart (SImode, operands[1]);
+ operands[5] = gen_highpart (SImode, operands[1]);
+ }
+)
+
(define_split
[(set (match_operand:DIDF 0 "register_operand" "")
(match_operand:DIDF 1 "const_double_operand" ""))]
- "reload_completed"
+ "flag_pic || reload_completed"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
{
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-dspext.md gcc-8.2.0/gcc/config/nds32/nds32-dspext.md
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-dspext.md 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-dspext.md 2019-01-25 15:38:32.825242648 +0100
@@ -0,0 +1,5278 @@
+;; Machine description of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; 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
+;; <http://www.gnu.org/licenses/>.
+
+(define_expand "mov<mode>"
+ [(set (match_operand:VQIHI 0 "general_operand" "")
+ (match_operand:VQIHI 1 "general_operand" ""))]
+ "NDS32_EXT_DSP_P ()"
+{
+ /* Need to force register if mem <- !reg. */
+ if (MEM_P (operands[0]) && !REG_P (operands[1]))
+ operands[1] = force_reg (<MODE>mode, operands[1]);
+
+ /* If operands[1] is a large constant and cannot be performed
+ by a single instruction, we need to split it. */
+ if (GET_CODE (operands[1]) == CONST_VECTOR
+ && !satisfies_constraint_CVs2 (operands[1])
+ && !satisfies_constraint_CVhi (operands[1]))
+ {
+ HOST_WIDE_INT ival = const_vector_to_hwint (operands[1]);
+ rtx tmp_rtx;
+
+ tmp_rtx = can_create_pseudo_p ()
+ ? gen_reg_rtx (SImode)
+ : simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
+
+ emit_move_insn (tmp_rtx, gen_int_mode (ival, SImode));
+ convert_move (operands[0], tmp_rtx, false);
+ DONE;
+ }
+
+ if (REG_P (operands[0]) && SYMBOLIC_CONST_P (operands[1]))
+ {
+ if (nds32_tls_referenced_p (operands [1]))
+ {
+ nds32_expand_tls_move (operands);
+ DONE;
+ }
+ else if (flag_pic)
+ {
+ nds32_expand_pic_move (operands);
+ DONE;
+ }
+ }
+})
+
+(define_insn "*mov<mode>"
+ [(set (match_operand:VQIHI 0 "nonimmediate_operand" "=r, r,$U45,$U33,$U37,$U45, m,$ l,$ l,$ l,$ d, d, r,$ d, r, r, r, *f, *f, r, *f, Q")
+ (match_operand:VQIHI 1 "nds32_vmove_operand" " r, r, l, l, l, d, r, U45, U33, U37, U45,Ufe, m, CVp5, CVs5, CVs2, CVhi, *f, r, *f, Q, *f"))]
+ "NDS32_EXT_DSP_P ()
+ && (register_operand(operands[0], <MODE>mode)
+ || register_operand(operands[1], <MODE>mode))"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "mov55\t%0, %1";
+ case 1:
+ return "ori\t%0, %1, 0";
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ return nds32_output_16bit_store (operands, <byte>);
+ case 6:
+ return nds32_output_32bit_store (operands, <byte>);
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ return nds32_output_16bit_load (operands, <byte>);
+ case 12:
+ return nds32_output_32bit_load (operands, <byte>);
+ case 13:
+ return "movpi45\t%0, %1";
+ case 14:
+ return "movi55\t%0, %1";
+ case 15:
+ return "movi\t%0, %1";
+ case 16:
+ return "sethi\t%0, hi20(%1)";
+ case 17:
+ if (TARGET_FPU_SINGLE)
+ return "fcpyss\t%0, %1, %1";
+ else
+ return "#";
+ case 18:
+ return "fmtsr\t%1, %0";
+ case 19:
+ return "fmfsr\t%0, %1";
+ case 20:
+ return nds32_output_float_load (operands);
+ case 21:
+ return nds32_output_float_store (operands);
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,load,alu,alu,alu,alu,fcpy,fmtsr,fmfsr,fload,fstore")
+ (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 4, 2, 2, 4, 4, 4, 4, 4, 4, 4")
+ (set_attr "feature" " v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v3m, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu")])
+
+(define_expand "movv2si"
+ [(set (match_operand:V2SI 0 "general_operand" "")
+ (match_operand:V2SI 1 "general_operand" ""))]
+ "NDS32_EXT_DSP_P ()"
+{
+ /* Need to force register if mem <- !reg. */
+ if (MEM_P (operands[0]) && !REG_P (operands[1]))
+ operands[1] = force_reg (V2SImode, operands[1]);
+})
+
+(define_insn "*movv2si"
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=r, r, r, r, Da, m, f, Q, f, r, f")
+ (match_operand:V2SI 1 "general_operand" " r, i, Da, m, r, r, Q, f, f, f, r"))]
+ "NDS32_EXT_DSP_P ()
+ && (register_operand(operands[0], V2SImode)
+ || register_operand(operands[1], V2SImode))"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "movd44\t%0, %1";
+ case 1:
+ /* reg <- const_int, we ask gcc to split instruction. */
+ return "#";
+ case 2:
+ /* The memory format is (mem (reg)),
+ we can generate 'lmw.bi' instruction. */
+ return nds32_output_double (operands, true);
+ case 3:
+ /* We haven't 64-bit load instruction,
+ we split this pattern to two SImode pattern. */
+ return "#";
+ case 4:
+ /* The memory format is (mem (reg)),
+ we can generate 'smw.bi' instruction. */
+ return nds32_output_double (operands, false);
+ case 5:
+ /* We haven't 64-bit store instruction,
+ we split this pattern to two SImode pattern. */
+ return "#";
+ case 6:
+ return nds32_output_float_load (operands);
+ case 7:
+ return nds32_output_float_store (operands);
+ case 8:
+ return "fcpysd\t%0, %1, %1";
+ case 9:
+ return "fmfdr\t%0, %1";
+ case 10:
+ return "fmtdr\t%1, %0";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "alu,alu,load,load,store,store,unknown,unknown,unknown,unknown,unknown")
+ (set_attr_alternative "length"
+ [
+ ;; Alternative 0
+ (if_then_else (match_test "!TARGET_16_BIT")
+ (const_int 4)
+ (const_int 2))
+ ;; Alternative 1
+ (const_int 16)
+ ;; Alternative 2
+ (const_int 4)
+ ;; Alternative 3
+ (const_int 8)
+ ;; Alternative 4
+ (const_int 4)
+ ;; Alternative 5
+ (const_int 8)
+ ;; Alternative 6
+ (const_int 4)
+ ;; Alternative 7
+ (const_int 4)
+ ;; Alternative 8
+ (const_int 4)
+ ;; Alternative 9
+ (const_int 4)
+ ;; Alternative 10
+ (const_int 4)
+ ])
+ (set_attr "feature" " v1, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu")])
+
+(define_expand "movmisalign<mode>"
+ [(set (match_operand:VQIHI 0 "general_operand" "")
+ (match_operand:VQIHI 1 "general_operand" ""))]
+ "NDS32_EXT_DSP_P ()"
+{
+ rtx addr;
+ if (MEM_P (operands[0]) && !REG_P (operands[1]))
+ operands[1] = force_reg (<MODE>mode, operands[1]);
+
+ if (MEM_P (operands[0]))
+ {
+ addr = force_reg (Pmode, XEXP (operands[0], 0));
+ emit_insn (gen_unaligned_store<mode> (addr, operands[1]));
+ }
+ else
+ {
+ addr = force_reg (Pmode, XEXP (operands[1], 0));
+ emit_insn (gen_unaligned_load<mode> (operands[0], addr));
+ }
+ DONE;
+})
+
+(define_expand "unaligned_load<mode>"
+ [(set (match_operand:VQIHI 0 "register_operand" "=r")
+ (unspec:VQIHI [(mem:VQIHI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_W))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_ISA_V3M)
+ nds32_expand_unaligned_load (operands, <MODE>mode);
+ else
+ emit_insn (gen_unaligned_load_w<mode> (operands[0], gen_rtx_MEM (<MODE>mode, operands[1])));
+ DONE;
+})
+
+(define_insn "unaligned_load_w<mode>"
+ [(set (match_operand:VQIHI 0 "register_operand" "= r")
+ (unspec:VQIHI [(match_operand:VQIHI 1 "nds32_lmw_smw_base_operand" " Umw")] UNSPEC_UALOAD_W))]
+ "NDS32_EXT_DSP_P ()"
+{
+ return nds32_output_lmw_single_word (operands);
+}
+ [(set_attr "type" "load")
+ (set_attr "length" "4")]
+)
+
+(define_expand "unaligned_store<mode>"
+ [(set (mem:VQIHI (match_operand:SI 0 "register_operand" "r"))
+ (unspec:VQIHI [(match_operand:VQIHI 1 "register_operand" "r")] UNSPEC_UASTORE_W))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_ISA_V3M)
+ nds32_expand_unaligned_store (operands, <MODE>mode);
+ else
+ emit_insn (gen_unaligned_store_w<mode> (gen_rtx_MEM (<MODE>mode, operands[0]), operands[1]));
+ DONE;
+})
+
+(define_insn "unaligned_store_w<mode>"
+ [(set (match_operand:VQIHI 0 "nds32_lmw_smw_base_operand" "=Umw")
+ (unspec:VQIHI [(match_operand:VQIHI 1 "register_operand" " r")] UNSPEC_UASTORE_W))]
+ "NDS32_EXT_DSP_P ()"
+{
+ return nds32_output_smw_single_word (operands);
+}
+ [(set_attr "type" "store")
+ (set_attr "length" "4")]
+)
+
+(define_insn "<uk>add<mode>3"
+ [(set (match_operand:VQIHI 0 "register_operand" "=r")
+ (all_plus:VQIHI (match_operand:VQIHI 1 "register_operand" " r")
+ (match_operand:VQIHI 2 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "<uk>add<bits> %0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+(define_insn "<uk>adddi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (all_plus:DI (match_operand:DI 1 "register_operand" " r")
+ (match_operand:DI 2 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "<uk>add64 %0, %1, %2"
+ [(set_attr "type" "dalu64")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+(define_insn "raddv4qi3"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (truncate:V4QI
+ (ashiftrt:V4HI
+ (plus:V4HI (sign_extend:V4HI (match_operand:V4QI 1 "register_operand" " r"))
+ (sign_extend:V4HI (match_operand:V4QI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "radd8\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+
+(define_insn "uraddv4qi3"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (truncate:V4QI
+ (lshiftrt:V4HI
+ (plus:V4HI (zero_extend:V4HI (match_operand:V4QI 1 "register_operand" " r"))
+ (zero_extend:V4HI (match_operand:V4QI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "uradd8\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+(define_insn "raddv2hi3"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (truncate:V2HI
+ (ashiftrt:V2SI
+ (plus:V2SI (sign_extend:V2SI (match_operand:V2HI 1 "register_operand" " r"))
+ (sign_extend:V2SI (match_operand:V2HI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "radd16\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+(define_insn "uraddv2hi3"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (truncate:V2HI
+ (lshiftrt:V2SI
+ (plus:V2SI (zero_extend:V2SI (match_operand:V2HI 1 "register_operand" " r"))
+ (zero_extend:V2SI (match_operand:V2HI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "uradd16\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+(define_insn "radddi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (truncate:DI
+ (ashiftrt:TI
+ (plus:TI (sign_extend:TI (match_operand:DI 1 "register_operand" " r"))
+ (sign_extend:TI (match_operand:DI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "radd64\t%0, %1, %2"
+ [(set_attr "type" "dalu64")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+
+(define_insn "uradddi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (truncate:DI
+ (lshiftrt:TI
+ (plus:TI (zero_extend:TI (match_operand:DI 1 "register_operand" " r"))
+ (zero_extend:TI (match_operand:DI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "uradd64\t%0, %1, %2"
+ [(set_attr "type" "dalu64")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+(define_insn "<uk>sub<mode>3"
+ [(set (match_operand:VQIHI 0 "register_operand" "=r")
+ (all_minus:VQIHI (match_operand:VQIHI 1 "register_operand" " r")
+ (match_operand:VQIHI 2 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "<uk>sub<bits> %0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+(define_insn "<uk>subdi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (all_minus:DI (match_operand:DI 1 "register_operand" " r")
+ (match_operand:DI 2 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "<uk>sub64 %0, %1, %2"
+ [(set_attr "type" "dalu64")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+(define_insn "rsubv4qi3"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (truncate:V4QI
+ (ashiftrt:V4HI
+ (minus:V4HI (sign_extend:V4HI (match_operand:V4QI 1 "register_operand" " r"))
+ (sign_extend:V4HI (match_operand:V4QI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "rsub8\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn "ursubv4qi3"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (truncate:V4QI
+ (lshiftrt:V4HI
+ (minus:V4HI (zero_extend:V4HI (match_operand:V4QI 1 "register_operand" " r"))
+ (zero_extend:V4HI (match_operand:V4QI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "ursub8\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn "rsubv2hi3"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (truncate:V2HI
+ (ashiftrt:V2SI
+ (minus:V2SI (sign_extend:V2SI (match_operand:V2HI 1 "register_operand" " r"))
+ (sign_extend:V2SI (match_operand:V2HI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "rsub16\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn "ursubv2hi3"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (truncate:V2HI
+ (lshiftrt:V2SI
+ (minus:V2SI (zero_extend:V2SI (match_operand:V2HI 1 "register_operand" " r"))
+ (zero_extend:V2SI (match_operand:V2HI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "ursub16\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn "rsubdi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (truncate:DI
+ (ashiftrt:TI
+ (minus:TI (sign_extend:TI (match_operand:DI 1 "register_operand" " r"))
+ (sign_extend:TI (match_operand:DI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "rsub64\t%0, %1, %2"
+ [(set_attr "type" "dalu64")
+ (set_attr "length" "4")])
+
+
+(define_insn "ursubdi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (truncate:DI
+ (lshiftrt:TI
+ (minus:TI (zero_extend:TI (match_operand:DI 1 "register_operand" " r"))
+ (zero_extend:TI (match_operand:DI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "ursub64\t%0, %1, %2"
+ [(set_attr "type" "dalu64")
+ (set_attr "length" "4")])
+
+(define_expand "cras16_1"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_cras16_1_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_cras16_1_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "cras16_1_le"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (vec_duplicate:V2HI
+ (plus:HI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "cras16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_insn "cras16_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (plus:HI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "cras16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_expand "kcras16_1"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_kcras16_1_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_kcras16_1_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "kcras16_1_le"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (ss_minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (vec_duplicate:V2HI
+ (ss_plus:HI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "kcras16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_insn "kcras16_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (ss_minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (ss_plus:HI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "kcras16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_expand "ukcras16_1"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_ukcras16_1_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_ukcras16_1_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "ukcras16_1_le"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (us_minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (vec_duplicate:V2HI
+ (us_plus:HI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "ukcras16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_insn "ukcras16_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (us_minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (us_plus:HI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "ukcras16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_expand "crsa16_1"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_crsa16_1_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_crsa16_1_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "crsa16_1_le"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (plus:HI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "crsa16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_insn "crsa16_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (vec_duplicate:V2HI
+ (plus:HI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "crsa16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_expand "kcrsa16_1"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_kcrsa16_1_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_kcrsa16_1_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "kcrsa16_1_le"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (ss_minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (ss_plus:HI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "kcrsa16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_insn "kcrsa16_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (ss_minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (vec_duplicate:V2HI
+ (ss_plus:HI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "kcrsa16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_expand "ukcrsa16_1"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_ukcrsa16_1_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_ukcrsa16_1_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "ukcrsa16_1_le"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (us_minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (us_plus:HI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "ukcrsa16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_insn "ukcrsa16_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (us_minus:HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (vec_duplicate:V2HI
+ (us_plus:HI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "ukcrsa16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_expand "rcras16_1"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_rcras16_1_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_rcras16_1_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "rcras16_1_le"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (ashiftrt:SI
+ (minus:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (const_int 1))))
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (ashiftrt:SI
+ (plus:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)]))))
+ (const_int 1))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "rcras16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_insn "rcras16_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (ashiftrt:SI
+ (minus:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (const_int 1))))
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (ashiftrt:SI
+ (plus:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)]))))
+ (const_int 1))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "rcras16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_expand "urcras16_1"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_urcras16_1_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_urcras16_1_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "urcras16_1_le"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (lshiftrt:SI
+ (minus:SI
+ (zero_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (zero_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (const_int 1))))
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (lshiftrt:SI
+ (plus:SI
+ (zero_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (zero_extend:SI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)]))))
+ (const_int 1))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "urcras16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_insn "urcras16_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (lshiftrt:SI
+ (minus:SI
+ (zero_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (zero_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (const_int 1))))
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (lshiftrt:SI
+ (plus:SI
+ (zero_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)])))
+ (zero_extend:SI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)]))))
+ (const_int 1))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "urcras16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_expand "rcrsa16_1"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_rcrsa16_1_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_rcrsa16_1_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "rcrsa16_1_le"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (ashiftrt:SI
+ (minus:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (const_int 1))))
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (ashiftrt:SI
+ (plus:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (const_int 1))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "rcrsa16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_insn "rcrsa16_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (ashiftrt:SI
+ (minus:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (const_int 1))))
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (ashiftrt:SI
+ (plus:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))
+ (const_int 1))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "rcrsa16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_expand "urcrsa16_1"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_urcrsa16_1_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_urcrsa16_1_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "urcrsa16_1_le"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (lshiftrt:SI
+ (minus:SI
+ (zero_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (zero_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (const_int 1))))
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (lshiftrt:SI
+ (plus:SI
+ (zero_extend:SI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)])))
+ (zero_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (const_int 1))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "urcrsa16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_insn "urcrsa16_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (lshiftrt:SI
+ (minus:SI
+ (zero_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (zero_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (const_int 1))))
+ (vec_duplicate:V2HI
+ (truncate:HI
+ (lshiftrt:SI
+ (plus:SI
+ (zero_extend:SI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)])))
+ (zero_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))
+ (const_int 1))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "urcrsa16\t%0, %1, %2"
+ [(set_attr "type" "dalu")]
+)
+
+(define_expand "<shift>v2hi3"
+ [(set (match_operand:V2HI 0 "register_operand" "")
+ (shifts:V2HI (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:SI 2 "nds32_rimm4u_operand" "")))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (operands[2] == const0_rtx)
+ {
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+ }
+})
+
+(define_insn "*ashlv2hi3"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r")
+ (ashift:V2HI (match_operand:V2HI 1 "register_operand" " r, r")
+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))]
+ "NDS32_EXT_DSP_P ()"
+ "@
+ slli16\t%0, %1, %2
+ sll16\t%0, %1, %2"
+ [(set_attr "type" "dalu,dalu")
+ (set_attr "length" " 4, 4")])
+
+(define_insn "kslli16"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r")
+ (ss_ashift:V2HI (match_operand:V2HI 1 "register_operand" " r, r")
+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))]
+ "NDS32_EXT_DSP_P ()"
+ "@
+ kslli16\t%0, %1, %2
+ ksll16\t%0, %1, %2"
+ [(set_attr "type" "dalu,dalu")
+ (set_attr "length" " 4, 4")])
+
+(define_insn "*ashrv2hi3"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r")
+ (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r")
+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))]
+ "NDS32_EXT_DSP_P ()"
+ "@
+ srai16\t%0, %1, %2
+ sra16\t%0, %1, %2"
+ [(set_attr "type" "dalu,dalu")
+ (set_attr "length" " 4, 4")])
+
+(define_insn "sra16_round"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r")
+ (unspec:V2HI [(ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r")
+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r"))]
+ UNSPEC_ROUND))]
+ "NDS32_EXT_DSP_P ()"
+ "@
+ srai16.u\t%0, %1, %2
+ sra16.u\t%0, %1, %2"
+ [(set_attr "type" "daluround,daluround")
+ (set_attr "length" " 4, 4")])
+
+(define_insn "*lshrv2hi3"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r")
+ (lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r")
+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))]
+ "NDS32_EXT_DSP_P ()"
+ "@
+ srli16\t%0, %1, %2
+ srl16\t%0, %1, %2"
+ [(set_attr "type" "dalu,dalu")
+ (set_attr "length" " 4, 4")])
+
+(define_insn "srl16_round"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r")
+ (unspec:V2HI [(lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r")
+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r"))]
+ UNSPEC_ROUND))]
+ "NDS32_EXT_DSP_P ()"
+ "@
+ srli16.u\t%0, %1, %2
+ srl16.u\t%0, %1, %2"
+ [(set_attr "type" "daluround,daluround")
+ (set_attr "length" " 4, 4")])
+
+(define_insn "kslra16"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (if_then_else:V2HI
+ (lt:SI (match_operand:SI 2 "register_operand" " r")
+ (const_int 0))
+ (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r")
+ (neg:SI (match_dup 2)))
+ (ashift:V2HI (match_dup 1)
+ (match_dup 2))))]
+ "NDS32_EXT_DSP_P ()"
+ "kslra16\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn "kslra16_round"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (if_then_else:V2HI
+ (lt:SI (match_operand:SI 2 "register_operand" " r")
+ (const_int 0))
+ (unspec:V2HI [(ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r")
+ (neg:SI (match_dup 2)))]
+ UNSPEC_ROUND)
+ (ashift:V2HI (match_dup 1)
+ (match_dup 2))))]
+ "NDS32_EXT_DSP_P ()"
+ "kslra16.u\t%0, %1, %2"
+ [(set_attr "type" "daluround")
+ (set_attr "length" "4")])
+
+(define_insn "cmpeq<bits>"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(eq:SI (match_operand:VQIHI 1 "register_operand" " r")
+ (match_operand:VQIHI 2 "register_operand" " r"))]
+ UNSPEC_VEC_COMPARE))]
+ "NDS32_EXT_DSP_P ()"
+ "cmpeq<bits>\t%0, %1, %2"
+ [(set_attr "type" "dcmp")
+ (set_attr "length" "4")])
+
+(define_insn "scmplt<bits>"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(lt:SI (match_operand:VQIHI 1 "register_operand" " r")
+ (match_operand:VQIHI 2 "register_operand" " r"))]
+ UNSPEC_VEC_COMPARE))]
+ "NDS32_EXT_DSP_P ()"
+ "scmplt<bits>\t%0, %1, %2"
+ [(set_attr "type" "dcmp")
+ (set_attr "length" "4")])
+
+(define_insn "scmple<bits>"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(le:SI (match_operand:VQIHI 1 "register_operand" " r")
+ (match_operand:VQIHI 2 "register_operand" " r"))]
+ UNSPEC_VEC_COMPARE))]
+ "NDS32_EXT_DSP_P ()"
+ "scmple<bits>\t%0, %1, %2"
+ [(set_attr "type" "dcmp")
+ (set_attr "length" "4")])
+
+(define_insn "ucmplt<bits>"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(ltu:SI (match_operand:VQIHI 1 "register_operand" " r")
+ (match_operand:VQIHI 2 "register_operand" " r"))]
+ UNSPEC_VEC_COMPARE))]
+ "NDS32_EXT_DSP_P ()"
+ "ucmplt<bits>\t%0, %1, %2"
+ [(set_attr "type" "dcmp")
+ (set_attr "length" "4")])
+
+(define_insn "ucmple<bits>"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(leu:SI (match_operand:VQIHI 1 "register_operand" " r")
+ (match_operand:VQIHI 2 "register_operand" " r"))]
+ UNSPEC_VEC_COMPARE))]
+ "NDS32_EXT_DSP_P ()"
+ "ucmple<bits>\t%0, %1, %2"
+ [(set_attr "type" "dcmp")
+ (set_attr "length" "4")])
+
+(define_insn "sclip16"
+ [(set (match_operand:V2HI 0 "register_operand" "= r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r")
+ (match_operand:SI 2 "nds32_imm4u_operand" " Iu04")]
+ UNSPEC_CLIPS))]
+ "NDS32_EXT_DSP_P ()"
+ "sclip16\t%0, %1, %2"
+ [(set_attr "type" "dclip")
+ (set_attr "length" "4")])
+
+(define_insn "uclip16"
+ [(set (match_operand:V2HI 0 "register_operand" "= r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r")
+ (match_operand:SI 2 "nds32_imm4u_operand" " Iu04")]
+ UNSPEC_CLIP))]
+ "NDS32_EXT_DSP_P ()"
+ "uclip16\t%0, %1, %2"
+ [(set_attr "type" "dclip")
+ (set_attr "length" "4")])
+
+(define_insn "khm16"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r")
+ (match_operand:V2HI 2 "register_operand" " r")]
+ UNSPEC_KHM))]
+ "NDS32_EXT_DSP_P ()"
+ "khm16\t%0, %1, %2"
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_insn "khmx16"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r")
+ (match_operand:V2HI 2 "register_operand" " r")]
+ UNSPEC_KHMX))]
+ "NDS32_EXT_DSP_P ()"
+ "khmx16\t%0, %1, %2"
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_expand "vec_setv4qi"
+ [(match_operand:V4QI 0 "register_operand" "")
+ (match_operand:QI 1 "register_operand" "")
+ (match_operand:SI 2 "immediate_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ HOST_WIDE_INT pos = INTVAL (operands[2]);
+ if (pos > 4)
+ gcc_unreachable ();
+ HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << pos;
+ emit_insn (gen_vec_setv4qi_internal (operands[0], operands[1],
+ operands[0], GEN_INT (elem)));
+ DONE;
+})
+
+(define_expand "insb"
+ [(match_operand:V4QI 0 "register_operand" "")
+ (match_operand:V4QI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (INTVAL (operands[3]) > 3 || INTVAL (operands[3]) < 0)
+ gcc_unreachable ();
+
+ rtx src = gen_reg_rtx (QImode);
+
+ convert_move (src, operands[2], false);
+
+ HOST_WIDE_INT selector_index;
+ /* Big endian need reverse index. */
+ if (TARGET_BIG_ENDIAN)
+ selector_index = 4 - INTVAL (operands[3]) - 1;
+ else
+ selector_index = INTVAL (operands[3]);
+ rtx selector = gen_int_mode (1 << selector_index, SImode);
+ emit_insn (gen_vec_setv4qi_internal (operands[0], src,
+ operands[1], selector));
+ DONE;
+})
+
+(define_expand "insvsi"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "const_int_operand" "")
+ (match_operand:SI 2 "nds32_insv_operand" ""))
+ (match_operand:SI 3 "register_operand" ""))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (INTVAL (operands[1]) != 8)
+ FAIL;
+}
+ [(set_attr "type" "dinsb")
+ (set_attr "length" "4")])
+
+
+(define_insn "insvsi_internal"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+ (const_int 8)
+ (match_operand:SI 1 "nds32_insv_operand" "i"))
+ (match_operand:SI 2 "register_operand" "r"))]
+ "NDS32_EXT_DSP_P ()"
+ "insb\t%0, %2, %v1"
+ [(set_attr "type" "dinsb")
+ (set_attr "length" "4")])
+
+(define_insn "insvsiqi_internal"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+ (const_int 8)
+ (match_operand:SI 1 "nds32_insv_operand" "i"))
+ (zero_extend:SI (match_operand:QI 2 "register_operand" "r")))]
+ "NDS32_EXT_DSP_P ()"
+ "insb\t%0, %2, %v1"
+ [(set_attr "type" "dinsb")
+ (set_attr "length" "4")])
+
+;; Intermedium pattern for synthetize insvsiqi_internal
+;; v0 = ((v1 & 0xff) << 8)
+(define_insn_and_split "and0xff_s8"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 8))
+ (const_int 65280)))]
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_ashlsi3 (tmp, operands[1], gen_int_mode (8, SImode)));
+ emit_insn (gen_andsi3 (operands[0], tmp, gen_int_mode (0xffff, SImode)));
+ DONE;
+})
+
+;; v0 = (v1 & 0xff00ffff) | ((v2 << 16) | 0xff0000)
+(define_insn_and_split "insbsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int -16711681))
+ (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))
+ (const_int 16711680))))]
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_move_insn (tmp, operands[1]);
+ emit_insn (gen_insvsi_internal (tmp, gen_int_mode(16, SImode), operands[2]));
+ emit_move_insn (operands[0], tmp);
+ DONE;
+})
+
+;; v0 = (v1 & 0xff00ffff) | v2
+(define_insn_and_split "ior_and0xff00ffff_reg"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int -16711681))
+ (match_operand:SI 2 "register_operand" "r")))]
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_andsi3 (tmp, operands[1], gen_int_mode (0xff00ffff, SImode)));
+ emit_insn (gen_iorsi3 (operands[0], tmp, operands[2]));
+ DONE;
+})
+
+(define_insn "vec_setv4qi_internal"
+ [(set (match_operand:V4QI 0 "register_operand" "= r, r, r, r")
+ (vec_merge:V4QI
+ (vec_duplicate:V4QI
+ (match_operand:QI 1 "register_operand" " r, r, r, r"))
+ (match_operand:V4QI 2 "register_operand" " 0, 0, 0, 0")
+ (match_operand:SI 3 "nds32_imm_1_2_4_8_operand" " Iv01, Iv02, Iv04, Iv08")))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "insb\t%0, %1, 3",
+ "insb\t%0, %1, 2",
+ "insb\t%0, %1, 1",
+ "insb\t%0, %1, 0" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "insb\t%0, %1, 0",
+ "insb\t%0, %1, 1",
+ "insb\t%0, %1, 2",
+ "insb\t%0, %1, 3" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dinsb")
+ (set_attr "length" "4")])
+
+(define_insn "vec_setv4qi_internal_vec"
+ [(set (match_operand:V4QI 0 "register_operand" "= r, r, r, r")
+ (vec_merge:V4QI
+ (vec_duplicate:V4QI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r, r, r, r")
+ (parallel [(const_int 0)])))
+ (match_operand:V4QI 2 "register_operand" " 0, 0, 0, 0")
+ (match_operand:SI 3 "nds32_imm_1_2_4_8_operand" " Iv01, Iv02, Iv04, Iv08")))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ insb\t%0, %1, 0
+ insb\t%0, %1, 1
+ insb\t%0, %1, 2
+ insb\t%0, %1, 3"
+ [(set_attr "type" "dinsb")
+ (set_attr "length" "4")])
+
+(define_insn "vec_mergev4qi_and_cv0_1"
+ [(set (match_operand:V4QI 0 "register_operand" "=$l,r")
+ (vec_merge:V4QI
+ (vec_duplicate:V4QI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " l,r")
+ (parallel [(const_int 0)])))
+ (const_vector:V4QI [
+ (const_int 0)
+ (const_int 0)
+ (const_int 0)
+ (const_int 0)])
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ zeb33\t%0, %1
+ zeb\t%0, %1"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_mergev4qi_and_cv0_2"
+ [(set (match_operand:V4QI 0 "register_operand" "=$l,r")
+ (vec_merge:V4QI
+ (const_vector:V4QI [
+ (const_int 0)
+ (const_int 0)
+ (const_int 0)
+ (const_int 0)])
+ (vec_duplicate:V4QI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " l,r")
+ (parallel [(const_int 0)])))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ zeb33\t%0, %1
+ zeb\t%0, %1"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_mergeqi_and_cv0_1"
+ [(set (match_operand:V4QI 0 "register_operand" "=$l,r")
+ (vec_merge:V4QI
+ (vec_duplicate:V4QI (match_operand:QI 1 "register_operand" " l,r"))
+ (const_vector:V4QI [
+ (const_int 0)
+ (const_int 0)
+ (const_int 0)
+ (const_int 0)])
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ zeb33\t%0, %1
+ zeb\t%0, %1"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_mergeqi_and_cv0_2"
+ [(set (match_operand:V4QI 0 "register_operand" "=$l,r")
+ (vec_merge:V4QI
+ (const_vector:V4QI [
+ (const_int 0)
+ (const_int 0)
+ (const_int 0)
+ (const_int 0)])
+ (vec_duplicate:V4QI (match_operand:QI 1 "register_operand" " l,r"))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ zeb33\t%0, %1
+ zeb\t%0, %1"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_expand "vec_setv2hi"
+ [(match_operand:V2HI 0 "register_operand" "")
+ (match_operand:HI 1 "register_operand" "")
+ (match_operand:SI 2 "immediate_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ HOST_WIDE_INT pos = INTVAL (operands[2]);
+ if (pos > 2)
+ gcc_unreachable ();
+ HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << pos;
+ emit_insn (gen_vec_setv2hi_internal (operands[0], operands[1],
+ operands[0], GEN_INT (elem)));
+ DONE;
+})
+
+(define_insn "vec_setv2hi_internal"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (match_operand:HI 1 "register_operand" " r, r"))
+ (match_operand:V2HI 2 "register_operand" " r, r")
+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv02")))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "pkbb16\t%0, %1, %2",
+ "pktb16\t%0, %2, %1" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "pktb16\t%0, %2, %1",
+ "pkbb16\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "vec_mergev2hi_and_cv0_1"
+ [(set (match_operand:V2HI 0 "register_operand" "=$l,r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " l,r")
+ (parallel [(const_int 0)])))
+ (const_vector:V2HI [
+ (const_int 0)
+ (const_int 0)])
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ zeh33\t%0, %1
+ zeh\t%0, %1"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_mergev2hi_and_cv0_2"
+ [(set (match_operand:V2HI 0 "register_operand" "=$l,r")
+ (vec_merge:V2HI
+ (const_vector:V2HI [
+ (const_int 0)
+ (const_int 0)])
+ (vec_duplicate:V2HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " l,r")
+ (parallel [(const_int 0)])))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ zeh33\t%0, %1
+ zeh\t%0, %1"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_mergehi_and_cv0_1"
+ [(set (match_operand:V2HI 0 "register_operand" "=$l,r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI (match_operand:HI 1 "register_operand" " l,r"))
+ (const_vector:V2HI [
+ (const_int 0)
+ (const_int 0)])
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ zeh33\t%0, %1
+ zeh\t%0, %1"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_mergehi_and_cv0_2"
+ [(set (match_operand:V2HI 0 "register_operand" "=$l,r")
+ (vec_merge:V2HI
+ (const_vector:V2HI [
+ (const_int 0)
+ (const_int 0)])
+ (vec_duplicate:V2HI (match_operand:HI 1 "register_operand" " l,r"))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ zeh33\t%0, %1
+ zeh\t%0, %1"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_expand "pkbb"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V2HI 1 "register_operand")
+ (match_operand:V2HI 2 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2],
+ GEN_INT (1), GEN_INT (1), GEN_INT (1)));
+ }
+ else
+ {
+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2],
+ GEN_INT (2), GEN_INT (0), GEN_INT (0)));
+ }
+ DONE;
+})
+
+(define_insn "pkbbsi_1"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 65535))
+ (ashift:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))))]
+ "NDS32_EXT_DSP_P ()"
+ "pkbb16\t%0, %2, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "pkbbsi_2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))
+ (and:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 65535))))]
+ "NDS32_EXT_DSP_P ()"
+ "pkbb16\t%0, %2, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "pkbbsi_3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
+ (ashift:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))))]
+ "NDS32_EXT_DSP_P ()"
+ "pkbb16\t%0, %2, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "pkbbsi_4"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))
+ (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))))]
+ "NDS32_EXT_DSP_P ()"
+ "pkbb16\t%0, %2, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+;; v0 = (v1 & 0xffff0000) | (v2 & 0xffff)
+(define_insn "pktbsi_1"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int -65536))
+ (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
+ "NDS32_EXT_DSP_P ()"
+ "pktb16\t%0, %1, %2"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "pktbsi_2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int -65536))
+ (and:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 65535))))]
+ "NDS32_EXT_DSP_P ()"
+ "pktb16\t%0, %1, %2"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "pktbsi_3"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+ (const_int 16 )
+ (const_int 0))
+ (match_operand:SI 1 "register_operand" " r"))]
+ "NDS32_EXT_DSP_P ()"
+ "pktb16\t%0, %0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "pktbsi_4"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+ (const_int 16 )
+ (const_int 0))
+ (zero_extend:SI (match_operand:HI 1 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "pktb16\t%0, %0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "pkttsi"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" " r")
+ (const_int -65536))
+ (lshiftrt:SI (match_operand:SI 2 "register_operand" " r")
+ (const_int 16))))]
+ "NDS32_EXT_DSP_P ()"
+ "pktt16\t%0, %1, %2"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_expand "pkbt"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V2HI 1 "register_operand")
+ (match_operand:V2HI 2 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2],
+ GEN_INT (1), GEN_INT (1), GEN_INT (0)));
+ }
+ else
+ {
+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2],
+ GEN_INT (2), GEN_INT (0), GEN_INT (1)));
+ }
+ DONE;
+})
+
+(define_expand "pktt"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V2HI 1 "register_operand")
+ (match_operand:V2HI 2 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2],
+ GEN_INT (1), GEN_INT (0), GEN_INT (0)));
+ }
+ else
+ {
+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2],
+ GEN_INT (2), GEN_INT (1), GEN_INT (1)));
+ }
+ DONE;
+})
+
+(define_expand "pktb"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V2HI 1 "register_operand")
+ (match_operand:V2HI 2 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2],
+ GEN_INT (1), GEN_INT (0), GEN_INT (1)));
+ }
+ else
+ {
+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2],
+ GEN_INT (2), GEN_INT (1), GEN_INT (0)));
+ }
+ DONE;
+})
+
+(define_insn "vec_mergerr"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (match_operand:HI 1 "register_operand" " r, r"))
+ (vec_duplicate:V2HI
+ (match_operand:HI 2 "register_operand" " r, r"))
+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv02")))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ pkbb16\t%0, %2, %1
+ pkbb16\t%0, %1, %2"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+
+(define_insn "vec_merge"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r")
+ (vec_merge:V2HI
+ (match_operand:V2HI 1 "register_operand" " r, r")
+ (match_operand:V2HI 2 "register_operand" " r, r")
+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv02")))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "pktb16\t%0, %1, %2",
+ "pktb16\t%0, %2, %1" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "pktb16\t%0, %2, %1",
+ "pktb16\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "vec_mergerv"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r, r, r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (match_operand:HI 1 "register_operand" " r, r, r, r"))
+ (vec_duplicate:V2HI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r, r, r, r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv00, Iv01")])))
+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv01, Iv02, Iv02")))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ pkbb16\t%0, %2, %1
+ pktb16\t%0, %2, %1
+ pkbb16\t%0, %1, %2
+ pkbt16\t%0, %1, %2"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "vec_mergevr"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r, r, r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r, r, r, r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv00, Iv01")])))
+ (vec_duplicate:V2HI
+ (match_operand:HI 2 "register_operand" " r, r, r, r"))
+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv01, Iv02, Iv02")))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ pkbb16\t%0, %2, %1
+ pkbt16\t%0, %2, %1
+ pkbb16\t%0, %1, %2
+ pktb16\t%0, %1, %2"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "vec_mergevv"
+ [(set (match_operand:V2HI 0 "register_operand" "= r, r, r, r, r, r, r, r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r, r, r, r, r, r, r, r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01, Iv00, Iv00, Iv01, Iv01")])))
+ (vec_duplicate:V2HI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r, r, r, r, r, r, r, r")
+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00, Iv00, Iv01, Iv01, Iv00")])))
+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv01, Iv01, Iv01, Iv02, Iv02, Iv02, Iv02")))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "pktt16\t%0, %1, %2",
+ "pktb16\t%0, %1, %2",
+ "pkbb16\t%0, %1, %2",
+ "pkbt16\t%0, %1, %2",
+ "pktt16\t%0, %2, %1",
+ "pkbt16\t%0, %2, %1",
+ "pkbb16\t%0, %2, %1",
+ "pktb16\t%0, %2, %1" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "pkbb16\t%0, %2, %1",
+ "pktb16\t%0, %2, %1",
+ "pktt16\t%0, %2, %1",
+ "pkbt16\t%0, %2, %1",
+ "pkbb16\t%0, %1, %2",
+ "pkbt16\t%0, %1, %2",
+ "pktt16\t%0, %1, %2",
+ "pktb16\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_expand "vec_extractv4qi"
+ [(set (match_operand:QI 0 "register_operand" "")
+ (vec_select:QI
+ (match_operand:V4QI 1 "nonimmediate_operand" "")
+ (parallel [(match_operand:SI 2 "const_int_operand" "")])))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+{
+ if (INTVAL (operands[2]) != 0
+ && INTVAL (operands[2]) != 1
+ && INTVAL (operands[2]) != 2
+ && INTVAL (operands[2]) != 3)
+ gcc_unreachable ();
+
+ if (INTVAL (operands[2]) != 0 && MEM_P (operands[0]))
+ FAIL;
+})
+
+(define_insn "vec_extractv4qi0"
+ [(set (match_operand:QI 0 "register_operand" "=l,r,r")
+ (vec_select:QI
+ (match_operand:V4QI 1 "nonimmediate_operand" " l,r,m")
+ (parallel [(const_int 0)])))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "zeb33\t%0, %1";
+ case 1:
+ return "zeb\t%0, %1";
+ case 2:
+ return nds32_output_32bit_load (operands, 1);
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "vec_extractv4qi0_ze"
+ [(set (match_operand:SI 0 "register_operand" "=l,r,r")
+ (zero_extend:SI
+ (vec_select:QI
+ (match_operand:V4QI 1 "nonimmediate_operand" " l,r,m")
+ (parallel [(const_int 0)]))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "zeb33\t%0, %1";
+ case 1:
+ return "zeb\t%0, %1";
+ case 2:
+ return nds32_output_32bit_load (operands, 1);
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "vec_extractv4qi0_se"
+ [(set (match_operand:SI 0 "register_operand" "=l,r,r")
+ (sign_extend:SI
+ (vec_select:QI
+ (match_operand:V4QI 1 "nonimmediate_operand" " l,r,m")
+ (parallel [(const_int 0)]))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "seb33\t%0, %1";
+ case 1:
+ return "seb\t%0, %1";
+ case 2:
+ return nds32_output_32bit_load_s (operands, 1);
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "vec_extractv4qi1"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 1)])))]
+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx tmp = gen_reg_rtx (V4QImode);
+ emit_insn (gen_rotrv4qi_1 (tmp, operands[1]));
+ emit_insn (gen_vec_extractv4qi0 (operands[0], tmp));
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "vec_extractv4qi2"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 2)])))]
+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx tmp = gen_reg_rtx (V4QImode);
+ emit_insn (gen_rotrv4qi_2 (tmp, operands[1]));
+ emit_insn (gen_vec_extractv4qi0 (operands[0], tmp));
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "vec_extractv4qi3"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 3)])))]
+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx tmp = gen_reg_rtx (V4QImode);
+ emit_insn (gen_rotrv4qi_3 (tmp, operands[1]));
+ emit_insn (gen_vec_extractv4qi0 (operands[0], tmp));
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "vec_extractv4qi3_se"
+ [(set (match_operand:SI 0 "register_operand" "=$d,r")
+ (sign_extend:SI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " 0,r")
+ (parallel [(const_int 3)]))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ srai45\t%0, 24
+ srai\t%0, %1, 24"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_extractv4qi3_ze"
+ [(set (match_operand:SI 0 "register_operand" "=$d,r")
+ (zero_extend:SI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " 0,r")
+ (parallel [(const_int 3)]))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ srli45\t%0, 24
+ srli\t%0, %1, 24"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn_and_split "vec_extractv4qihi0"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))))]
+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx tmp = gen_reg_rtx (QImode);
+ emit_insn (gen_vec_extractv4qi0 (tmp, operands[1]));
+ emit_insn (gen_extendqihi2 (operands[0], tmp));
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "vec_extractv4qihi1"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))))]
+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx tmp = gen_reg_rtx (QImode);
+ emit_insn (gen_vec_extractv4qi1 (tmp, operands[1]));
+ emit_insn (gen_extendqihi2 (operands[0], tmp));
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "vec_extractv4qihi2"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 2)]))))]
+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx tmp = gen_reg_rtx (QImode);
+ emit_insn (gen_vec_extractv4qi2 (tmp, operands[1]));
+ emit_insn (gen_extendqihi2 (operands[0], tmp));
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "vec_extractv4qihi3"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 3)]))))]
+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx tmp = gen_reg_rtx (QImode);
+ emit_insn (gen_vec_extractv4qi3 (tmp, operands[1]));
+ emit_insn (gen_extendqihi2 (operands[0], tmp));
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_expand "vec_extractv2hi"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (vec_select:HI
+ (match_operand:V2HI 1 "nonimmediate_operand" "")
+ (parallel [(match_operand:SI 2 "const_int_operand" "")])))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (INTVAL (operands[2]) != 0
+ && INTVAL (operands[2]) != 1)
+ gcc_unreachable ();
+
+ if (INTVAL (operands[2]) != 0 && MEM_P (operands[0]))
+ FAIL;
+})
+
+(define_insn "vec_extractv2hi0"
+ [(set (match_operand:HI 0 "register_operand" "=$l,r,r")
+ (vec_select:HI
+ (match_operand:V2HI 1 "nonimmediate_operand" " l,r,m")
+ (parallel [(const_int 0)])))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "seh33\t%0, %1";
+ case 1:
+ return "seh\t%0, %1";
+ case 2:
+ return nds32_output_32bit_load_s (operands, 2);
+
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "alu,alu,load")
+ (set_attr "length" " 2, 4, 4")])
+
+(define_insn "vec_extractv2hi0_ze"
+ [(set (match_operand:SI 0 "register_operand" "=$l, r,$ l, *r")
+ (zero_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "nonimmediate_operand" " l, r, U33, m")
+ (parallel [(const_int 0)]))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "zeh33\t%0, %1";
+ case 1:
+ return "zeh\t%0, %1";
+ case 2:
+ return nds32_output_16bit_load (operands, 2);
+ case 3:
+ return nds32_output_32bit_load (operands, 2);
+
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "alu,alu,load,load")
+ (set_attr "length" " 2, 4, 2, 4")])
+
+(define_insn "vec_extractv2hi0_se"
+ [(set (match_operand:SI 0 "register_operand" "=$l, r, r")
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "nonimmediate_operand" " l,r,m")
+ (parallel [(const_int 0)]))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "seh33\t%0, %1";
+ case 1:
+ return "seh\t%0, %1";
+ case 2:
+ return nds32_output_32bit_load_s (operands, 2);
+
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "alu,alu,load")
+ (set_attr "length" " 2, 4, 4")])
+
+(define_insn "vec_extractv2hi0_be"
+ [(set (match_operand:HI 0 "register_operand" "=$d,r")
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " 0,r")
+ (parallel [(const_int 0)])))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "@
+ srai45\t%0, 16
+ srai\t%0, %1, 16"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_extractv2hi1"
+ [(set (match_operand:HI 0 "register_operand" "=$d,r")
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " 0,r")
+ (parallel [(const_int 1)])))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ srai45\t%0, 16
+ srai\t%0, %1, 16"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_extractv2hi1_se"
+ [(set (match_operand:SI 0 "register_operand" "=$d,r")
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " 0,r")
+ (parallel [(const_int 1)]))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ srai45\t%0, 16
+ srai\t%0, %1, 16"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_extractv2hi1_ze"
+ [(set (match_operand:SI 0 "register_operand" "=$d,r")
+ (zero_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " 0,r")
+ (parallel [(const_int 1)]))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "@
+ srli45\t%0, 16
+ srli\t%0, %1, 16"
+ [(set_attr "type" "alu,alu")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "vec_extractv2hi1_be"
+ [(set (match_operand:HI 0 "register_operand" "=$l,r,r")
+ (vec_select:HI
+ (match_operand:V2HI 1 "nonimmediate_operand" " l,r,m")
+ (parallel [(const_int 1)])))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "seh33\t%0, %1";
+ case 1:
+ return "seh\t%0, %1";
+ case 2:
+ return nds32_output_32bit_load_s (operands, 2);
+
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "alu,alu,load")
+ (set_attr "length" " 2, 4, 4")])
+
+(define_insn "<su>mul16"
+ [(set (match_operand:V2SI 0 "register_operand" "=r")
+ (mult:V2SI (extend:V2SI (match_operand:V2HI 1 "register_operand" "%r"))
+ (extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))))]
+ "NDS32_EXT_DSP_P ()"
+ "<su>mul16\t%0, %1, %2"
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_insn "<su>mulx16"
+ [(set (match_operand:V2SI 0 "register_operand" "=r")
+ (vec_merge:V2SI
+ (vec_duplicate:V2SI
+ (mult:SI
+ (extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))))
+ (vec_duplicate:V2SI
+ (mult:SI
+ (extend:SI
+ (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)])))
+ (extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P ()"
+ "<su>mulx16\t%0, %1, %2"
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_insn "rotrv2hi_1"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_select:V2HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1) (const_int 0)])))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "rotri\t%0, %1, 16"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "rotrv2hi_1_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_select:V2HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0) (const_int 1)])))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "rotri\t%0, %1, 16"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "rotrv4qi_1"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (vec_select:V4QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 1) (const_int 2) (const_int 3) (const_int 0)])))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "rotri\t%0, %1, 8"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "rotrv4qi_1_be"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (vec_select:V4QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 2) (const_int 1) (const_int 0) (const_int 3)])))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "rotri\t%0, %1, 8"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "rotrv4qi_2"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (vec_select:V4QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 2) (const_int 3) (const_int 0) (const_int 1)])))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "rotri\t%0, %1, 16"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "rotrv4qi_2_be"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (vec_select:V4QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)])))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "rotri\t%0, %1, 16"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "rotrv4qi_3"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (vec_select:V4QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 3) (const_int 0) (const_int 1) (const_int 2)])))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "rotri\t%0, %1, 24"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "rotrv4qi_3_be"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (vec_select:V4QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 0) (const_int 3) (const_int 2) (const_int 1)])))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "rotri\t%0, %1, 24"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "v4qi_dup_10"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (vec_select:V4QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 0) (const_int 1) (const_int 0) (const_int 1)])))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "pkbb\t%0, %1, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "v4qi_dup_32"
+ [(set (match_operand:V4QI 0 "register_operand" "=r")
+ (vec_select:V4QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 2) (const_int 3) (const_int 2) (const_int 3)])))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "pktt\t%0, %1, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_expand "vec_unpacks_lo_v4qi"
+ [(match_operand:V2HI 0 "register_operand" "=r")
+ (match_operand:V4QI 1 "register_operand" " r")]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+{
+ emit_insn (gen_sunpkd810 (operands[0], operands[1]));
+ DONE;
+})
+
+(define_expand "sunpkd810"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_sunpkd810_imp_be (operands[0], operands[1]));
+ else
+ emit_insn (gen_sunpkd810_imp (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn "<zs>unpkd810_imp"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 0)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "<zs>unpkd810\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd810_imp_inv"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 1)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "<zs>unpkd810\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd810_imp_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 2)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 3)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "<zs>unpkd810\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd810_imp_inv_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 3)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 2)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "<zs>unpkd810\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_expand "sunpkd820"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_sunpkd820_imp_be (operands[0], operands[1]));
+ else
+ emit_insn (gen_sunpkd820_imp (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn "<zs>unpkd820_imp"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 2)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 0)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "<zs>unpkd820\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd820_imp_inv"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 2)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "<zs>unpkd820\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd820_imp_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 3)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "<zs>unpkd820\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd820_imp_inv_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 3)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 1)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "<zs>unpkd820\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_expand "sunpkd830"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_sunpkd830_imp_be (operands[0], operands[1]));
+ else
+ emit_insn (gen_sunpkd830_imp (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn "<zs>unpkd830_imp"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 3)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 0)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "<zs>unpkd830\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd830_imp_inv"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 3)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "<zs>unpkd830\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd830_imp_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 3)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "<zs>unpkd830\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd830_imp_inv_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 3)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 0)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "<zs>unpkd830\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_expand "sunpkd831"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_sunpkd831_imp_be (operands[0], operands[1]));
+ else
+ emit_insn (gen_sunpkd831_imp (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn "<zs>unpkd831_imp"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 3)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 1)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "<zs>unpkd831\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd831_imp_inv"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 3)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "<zs>unpkd831\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd831_imp_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 2)]))))
+ (const_int 1)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "<zs>unpkd831\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "<zs>unpkd831_imp_inv_be"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 2)]))))
+ (vec_duplicate:V2HI
+ (extend:HI
+ (vec_select:QI
+ (match_dup 1)
+ (parallel [(const_int 0)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "<zs>unpkd831\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_expand "zunpkd810"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_zunpkd810_imp_be (operands[0], operands[1]));
+ else
+ emit_insn (gen_zunpkd810_imp (operands[0], operands[1]));
+ DONE;
+})
+
+(define_expand "zunpkd820"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_zunpkd820_imp_be (operands[0], operands[1]));
+ else
+ emit_insn (gen_zunpkd820_imp (operands[0], operands[1]));
+ DONE;
+})
+
+(define_expand "zunpkd830"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_zunpkd830_imp_be (operands[0], operands[1]));
+ else
+ emit_insn (gen_zunpkd830_imp (operands[0], operands[1]));
+ DONE;
+})
+
+(define_expand "zunpkd831"
+ [(match_operand:V2HI 0 "register_operand")
+ (match_operand:V4QI 1 "register_operand")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_zunpkd831_imp_be (operands[0], operands[1]));
+ else
+ emit_insn (gen_zunpkd831_imp (operands[0], operands[1]));
+ DONE;
+})
+
+(define_expand "smbb"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2],
+ GEN_INT (1), GEN_INT (1)));
+ else
+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2],
+ GEN_INT (0), GEN_INT (0)));
+ DONE;
+})
+
+(define_expand "smbt"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2],
+ GEN_INT (1), GEN_INT (0)));
+ else
+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2],
+ GEN_INT (0), GEN_INT (1)));
+ DONE;
+})
+
+(define_expand "smtt"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2],
+ GEN_INT (0), GEN_INT (0)));
+ else
+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2],
+ GEN_INT (1), GEN_INT (1)));
+ DONE;
+})
+
+(define_insn "mulhisi3v"
+ [(set (match_operand:SI 0 "register_operand" "= r, r, r, r")
+ (mult:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r, r, r, r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r, r, r, r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")])))))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "smtt\t%0, %1, %2",
+ "smbt\t%0, %2, %1",
+ "smbb\t%0, %1, %2",
+ "smbt\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "smbb\t%0, %1, %2",
+ "smbt\t%0, %1, %2",
+ "smtt\t%0, %1, %2",
+ "smbt\t%0, %2, %1" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_expand "kmabb"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")
+ (match_operand:V2HI 3 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3],
+ GEN_INT (1), GEN_INT (1),
+ operands[1]));
+ else
+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3],
+ GEN_INT (0), GEN_INT (0),
+ operands[1]));
+ DONE;
+})
+
+(define_expand "kmabt"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")
+ (match_operand:V2HI 3 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3],
+ GEN_INT (1), GEN_INT (0),
+ operands[1]));
+ else
+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3],
+ GEN_INT (0), GEN_INT (1),
+ operands[1]));
+ DONE;
+})
+
+(define_expand "kmatt"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")
+ (match_operand:V2HI 3 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3],
+ GEN_INT (0), GEN_INT (0),
+ operands[1]));
+ else
+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3],
+ GEN_INT (1), GEN_INT (1),
+ operands[1]));
+ DONE;
+})
+
+(define_insn "kma_internal"
+ [(set (match_operand:SI 0 "register_operand" "= r, r, r, r")
+ (ss_plus:SI
+ (mult:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r, r, r, r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r, r, r, r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")]))))
+ (match_operand:SI 5 "register_operand" " 0, 0, 0, 0")))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "kmatt\t%0, %1, %2",
+ "kmabt\t%0, %2, %1",
+ "kmabb\t%0, %1, %2",
+ "kmabt\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "kmabb\t%0, %1, %2",
+ "kmabt\t%0, %1, %2",
+ "kmatt\t%0, %1, %2",
+ "kmabt\t%0, %2, %1" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_expand "smds"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smds_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_smds_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_expand "smds_le"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))))]
+ "NDS32_EXT_DSP_P ()"
+{
+})
+
+(define_expand "smds_be"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))))]
+ "NDS32_EXT_DSP_P ()"
+{
+})
+
+(define_expand "smdrs"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smdrs_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_smdrs_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_expand "smdrs_le"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))))]
+ "NDS32_EXT_DSP_P ()"
+{
+})
+
+(define_expand "smdrs_be"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))))]
+ "NDS32_EXT_DSP_P ()"
+{
+})
+
+(define_expand "smxdsv"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:V2HI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smxdsv_be (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_smxdsv_le (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+
+(define_expand "smxdsv_le"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))))]
+ "NDS32_EXT_DSP_P ()"
+{
+})
+
+(define_expand "smxdsv_be"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))))]
+ "NDS32_EXT_DSP_P ()"
+{
+})
+
+(define_insn "smal1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" " r")
+ (sign_extend:DI
+ (mult:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "smal\t%0, %1, %2"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smal2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" " r")
+ (mult:DI
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:DI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))))]
+ "NDS32_EXT_DSP_P ()"
+ "smal\t%0, %1, %2"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smal3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" " r")
+ (sign_extend:DI
+ (mult:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "smal\t%0, %1, %2"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smal4"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" " r")
+ (mult:DI
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:DI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))))]
+ "NDS32_EXT_DSP_P ()"
+ "smal\t%0, %1, %2"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smal5"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (sign_extend:DI
+ (mult:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)])))))
+ (match_operand:DI 1 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "smal\t%0, %1, %2"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smal6"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (mult:DI
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:DI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (match_operand:DI 1 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "smal\t%0, %1, %2"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smal7"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (sign_extend:DI
+ (mult:SI
+ (sign_extend:SI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))))
+ (match_operand:DI 1 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "smal\t%0, %1, %2"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smal8"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (mult:DI
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:DI
+ (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))
+ (match_operand:DI 1 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "smal\t%0, %1, %2"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+;; We need this dummy pattern for smal
+(define_insn_and_split "extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "nds32_move_operand" "")))]
+ "NDS32_EXT_DSP_P ()"
+ "#"
+ "NDS32_EXT_DSP_P ()"
+ [(const_int 0)]
+{
+ rtx high_part_dst, low_part_dst;
+
+ low_part_dst = nds32_di_low_part_subreg (operands[0]);
+ high_part_dst = nds32_di_high_part_subreg (operands[0]);
+
+ emit_move_insn (low_part_dst, operands[1]);
+ emit_insn (gen_ashrsi3 (high_part_dst, low_part_dst, GEN_INT (31)));
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+;; We need this dummy pattern for usmar64/usmsr64
+(define_insn_and_split "zero_extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI (match_operand:SI 1 "nds32_move_operand" "")))]
+ "NDS32_EXT_DSP_P ()"
+ "#"
+ "NDS32_EXT_DSP_P ()"
+ [(const_int 0)]
+{
+ rtx high_part_dst, low_part_dst;
+
+ low_part_dst = nds32_di_low_part_subreg (operands[0]);
+ high_part_dst = nds32_di_high_part_subreg (operands[0]);
+
+ emit_move_insn (low_part_dst, operands[1]);
+ emit_move_insn (high_part_dst, const0_rtx);
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
+ "NDS32_EXT_DSP_P ()"
+ "#"
+ "NDS32_EXT_DSP_P ()"
+ [(const_int 0)]
+{
+ rtx high_part_dst, low_part_dst;
+
+ low_part_dst = nds32_di_low_part_subreg (operands[0]);
+ high_part_dst = nds32_di_high_part_subreg (operands[0]);
+
+
+ emit_insn (gen_extendhisi2 (low_part_dst, operands[1]));
+ emit_insn (gen_ashrsi3 (high_part_dst, low_part_dst, GEN_INT (31)));
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_insn "extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI (match_operand:QI 1 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "sunpkd820\t%0, %1"
+ [(set_attr "type" "dpack")
+ (set_attr "length" "4")])
+
+(define_insn "smulsi3_highpart"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (lshiftrt:DI
+ (mult:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")))
+ (const_int 32))))]
+ "NDS32_EXT_DSP_P ()"
+ "smmul\t%0, %1, %2"
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_insn "smmul_round"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (lshiftrt:DI
+ (unspec:DI [(mult:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")))]
+ UNSPEC_ROUND)
+ (const_int 32))))]
+ "NDS32_EXT_DSP_P ()"
+ "smmul.u\t%0, %1, %2"
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_insn "kmmac"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI (match_operand:SI 1 "register_operand" " 0")
+ (truncate:SI
+ (lshiftrt:DI
+ (mult:DI
+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))
+ (sign_extend:DI (match_operand:SI 3 "register_operand" " r")))
+ (const_int 32)))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmmac\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmmac_round"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI (match_operand:SI 1 "register_operand" " 0")
+ (truncate:SI
+ (lshiftrt:DI
+ (unspec:DI [(mult:DI
+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))
+ (sign_extend:DI (match_operand:SI 3 "register_operand" " r")))]
+ UNSPEC_ROUND)
+ (const_int 32)))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmmac.u\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmmsb"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_minus:SI (match_operand:SI 1 "register_operand" " 0")
+ (truncate:SI
+ (lshiftrt:DI
+ (mult:DI
+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))
+ (sign_extend:DI (match_operand:SI 3 "register_operand" " r")))
+ (const_int 32)))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmmsb\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmmsb_round"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_minus:SI (match_operand:SI 1 "register_operand" " 0")
+ (truncate:SI
+ (lshiftrt:DI
+ (unspec:DI [(mult:DI
+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))
+ (sign_extend:DI (match_operand:SI 3 "register_operand" " r")))]
+ UNSPEC_ROUND)
+ (const_int 32)))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmmsb.u\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kwmmul"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (lshiftrt:DI
+ (ss_mult:DI
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) (const_int 2))
+ (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) (const_int 2)))
+ (const_int 32))))]
+ "NDS32_EXT_DSP_P ()"
+ "kwmmul\t%0, %1, %2"
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_insn "kwmmul_round"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (lshiftrt:DI
+ (unspec:DI [
+ (ss_mult:DI
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) (const_int 2))
+ (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) (const_int 2)))]
+ UNSPEC_ROUND)
+ (const_int 32))))]
+ "NDS32_EXT_DSP_P ()"
+ "kwmmul.u\t%0, %1, %2"
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_expand "smmwb"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (1)));
+ else
+ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (0)));
+ DONE;
+})
+
+(define_expand "smmwt"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (0)));
+ else
+ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (1)));
+ DONE;
+})
+
+(define_insn "smulhisi3_highpart_1"
+ [(set (match_operand:SI 0 "register_operand" "= r, r")
+ (truncate:SI
+ (lshiftrt:DI
+ (mult:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r"))
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r, r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")]))))
+ (const_int 16))))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "smmwt\t%0, %1, %2",
+ "smmwb\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "smmwb\t%0, %1, %2",
+ "smmwt\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_insn "smulhisi3_highpart_2"
+ [(set (match_operand:SI 0 "register_operand" "= r, r")
+ (truncate:SI
+ (lshiftrt:DI
+ (mult:DI
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r, r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")])))
+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r, r")))
+ (const_int 16))))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "smmwt\t%0, %1, %2",
+ "smmwb\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "smmwb\t%0, %1, %2",
+ "smmwt\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_expand "smmwb_round"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (1)));
+ else
+ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (0)));
+ DONE;
+})
+
+(define_expand "smmwt_round"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (0)));
+ else
+ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (1)));
+ DONE;
+})
+
+(define_insn "smmw_round_internal"
+ [(set (match_operand:SI 0 "register_operand" "= r, r")
+ (truncate:SI
+ (lshiftrt:DI
+ (unspec:DI
+ [(mult:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r"))
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r, r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")]))))]
+ UNSPEC_ROUND)
+ (const_int 16))))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "smmwt.u\t%0, %1, %2",
+ "smmwb.u\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "smmwb.u\t%0, %1, %2",
+ "smmwt.u\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dmul")
+ (set_attr "length" "4")])
+
+(define_expand "kmmawb"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")
+ (match_operand:V2HI 3 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1]));
+ else
+ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1]));
+ DONE;
+})
+
+(define_expand "kmmawt"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")
+ (match_operand:V2HI 3 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1]));
+ else
+ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1]));
+ DONE;
+})
+
+(define_insn "kmmaw_internal"
+ [(set (match_operand:SI 0 "register_operand" "= r, r")
+ (ss_plus:SI
+ (match_operand:SI 4 "register_operand" " 0, 0")
+ (truncate:SI
+ (lshiftrt:DI
+ (mult:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r"))
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r, r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")]))))
+ (const_int 16)))))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "kmmawt\t%0, %1, %2",
+ "kmmawb\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "kmmawb\t%0, %1, %2",
+ "kmmawt\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_expand "kmmawb_round"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")
+ (match_operand:V2HI 3 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1]));
+ else
+ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1]));
+ DONE;
+}
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
+(define_expand "kmmawt_round"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")
+ (match_operand:V2HI 3 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1]));
+ else
+ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1]));
+ DONE;
+}
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+
+(define_insn "kmmaw_round_internal"
+ [(set (match_operand:SI 0 "register_operand" "= r, r")
+ (ss_plus:SI
+ (match_operand:SI 4 "register_operand" " 0, 0")
+ (truncate:SI
+ (lshiftrt:DI
+ (unspec:DI
+ [(mult:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r"))
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r, r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")]))))]
+ UNSPEC_ROUND)
+ (const_int 16)))))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "kmmawt.u\t%0, %1, %2",
+ "kmmawb.u\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "kmmawb.u\t%0, %1, %2",
+ "kmmawt.u\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_expand "smalbb"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")
+ (match_operand:V2HI 3 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smaddhidi (operands[0], operands[2],
+ operands[3], operands[1],
+ GEN_INT (1), GEN_INT (1)));
+ else
+ emit_insn (gen_smaddhidi (operands[0], operands[2],
+ operands[3], operands[1],
+ GEN_INT (0), GEN_INT (0)));
+ DONE;
+})
+
+(define_expand "smalbt"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")
+ (match_operand:V2HI 3 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smaddhidi (operands[0], operands[2],
+ operands[3], operands[1],
+ GEN_INT (1), GEN_INT (0)));
+ else
+ emit_insn (gen_smaddhidi (operands[0], operands[2],
+ operands[3], operands[1],
+ GEN_INT (0), GEN_INT (1)));
+ DONE;
+})
+
+(define_expand "smaltt"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" "")
+ (match_operand:V2HI 3 "register_operand" "")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smaddhidi (operands[0], operands[2],
+ operands[3], operands[1],
+ GEN_INT (0), GEN_INT (0)));
+ else
+ emit_insn (gen_smaddhidi (operands[0], operands[2],
+ operands[3], operands[1],
+ GEN_INT (1), GEN_INT (1)));
+ DONE;
+})
+
+(define_insn "smaddhidi"
+ [(set (match_operand:DI 0 "register_operand" "= r, r, r, r")
+ (plus:DI
+ (match_operand:DI 3 "register_operand" " 0, 0, 0, 0")
+ (mult:DI
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r, r, r, r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")])))
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r, r, r, r")
+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")]))))))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "smaltt\t%0, %1, %2",
+ "smalbt\t%0, %2, %1",
+ "smalbb\t%0, %1, %2",
+ "smalbt\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "smalbb\t%0, %1, %2",
+ "smalbt\t%0, %1, %2",
+ "smaltt\t%0, %1, %2",
+ "smalbt\t%0, %2, %1" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smaddhidi2"
+ [(set (match_operand:DI 0 "register_operand" "= r, r, r, r")
+ (plus:DI
+ (mult:DI
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r, r, r, r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")])))
+ (sign_extend:DI
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r, r, r, r")
+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")]))))
+ (match_operand:DI 3 "register_operand" " 0, 0, 0, 0")))]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ {
+ const char *pats[] = { "smaltt\t%0, %1, %2",
+ "smalbt\t%0, %2, %1",
+ "smalbb\t%0, %1, %2",
+ "smalbt\t%0, %1, %2" };
+ return pats[which_alternative];
+ }
+ else
+ {
+ const char *pats[] = { "smalbb\t%0, %1, %2",
+ "smalbt\t%0, %1, %2",
+ "smaltt\t%0, %1, %2",
+ "smalbt\t%0, %2, %1" };
+ return pats[which_alternative];
+ }
+}
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_expand "smalda1"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" " r")
+ (match_operand:V2HI 3 "register_operand" " r")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smalda1_be (operands[0], operands[1], operands[2], operands[3]));
+ else
+ emit_insn (gen_smalda1_le (operands[0], operands[1], operands[2], operands[3]));
+ DONE;
+})
+
+(define_expand "smalds1"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" " r")
+ (match_operand:V2HI 3 "register_operand" " r")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smalds1_be (operands[0], operands[1], operands[2], operands[3]));
+ else
+ emit_insn (gen_smalds1_le (operands[0], operands[1], operands[2], operands[3]));
+ DONE;
+})
+
+(define_insn "smalda1_le"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (sign_extend:DI
+ (plus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 0)]))))))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "smalda\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smalds1_le"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (sign_extend:DI
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 0)]))))))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "smalds\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smalda1_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (sign_extend:DI
+ (plus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 1)]))))))))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "smalda\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smalds1_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (sign_extend:DI
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 1)]))))))))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "smalds\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_expand "smaldrs3"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" " r")
+ (match_operand:V2HI 3 "register_operand" " r")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smaldrs3_be (operands[0], operands[1], operands[2], operands[3]));
+ else
+ emit_insn (gen_smaldrs3_le (operands[0], operands[1], operands[2], operands[3]));
+ DONE;
+})
+
+(define_insn "smaldrs3_le"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (sign_extend:DI
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 1)]))))))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "smaldrs\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smaldrs3_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (sign_extend:DI
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 0)]))))))))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "smaldrs\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_expand "smalxda1"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" " r")
+ (match_operand:V2HI 3 "register_operand" " r")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smalxda1_be (operands[0], operands[1], operands[2], operands[3]));
+ else
+ emit_insn (gen_smalxda1_le (operands[0], operands[1], operands[2], operands[3]));
+ DONE;
+})
+
+(define_expand "smalxds1"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" "")
+ (match_operand:V2HI 2 "register_operand" " r")
+ (match_operand:V2HI 3 "register_operand" " r")]
+ "NDS32_EXT_DSP_P ()"
+{
+ if (TARGET_BIG_ENDIAN)
+ emit_insn (gen_smalxds1_be (operands[0], operands[1], operands[2], operands[3]));
+ else
+ emit_insn (gen_smalxds1_le (operands[0], operands[1], operands[2], operands[3]));
+ DONE;
+})
+
+(define_insn "smalxd<add_sub>1_le"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (sign_extend:DI
+ (plus_minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 1)]))))))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "smalxd<add_sub>\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+
+(define_insn "smalxd<add_sub>1_be"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (sign_extend:DI
+ (plus_minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 0)]))))))))]
+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN"
+ "smalxd<add_sub>\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smslda1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI
+ (minus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (sign_extend:DI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 1)]))))))
+ (sign_extend:DI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 0)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "smslda\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "smslxda1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI
+ (minus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (sign_extend:DI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 0)]))))))
+ (sign_extend:DI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 1)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "smslxda\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+;; mada for synthetize smalda
+(define_insn_and_split "mada1"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" "r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" "r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))]
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx result0 = gen_reg_rtx (SImode);
+ rtx result1 = gen_reg_rtx (SImode);
+ emit_insn (gen_mulhisi3v (result0, operands[1], operands[2],
+ operands[3], operands[4]));
+ emit_insn (gen_mulhisi3v (result1, operands[1], operands[2],
+ operands[5], operands[6]));
+ emit_insn (gen_addsi3 (operands[0], result0, result1));
+ DONE;
+})
+
+(define_insn_and_split "mada2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" "r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" "r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))]
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 1)]
+{
+ rtx result0 = gen_reg_rtx (SImode);
+ rtx result1 = gen_reg_rtx (SImode);
+ emit_insn (gen_mulhisi3v (result0, operands[1], operands[2],
+ operands[3], operands[4]));
+ emit_insn (gen_mulhisi3v (result1, operands[1], operands[2],
+ operands[6], operands[5]));
+ emit_insn (gen_addsi3 (operands[0], result0, result1));
+ DONE;
+})
+
+;; sms for synthetize smalds
+(define_insn_and_split "sms1"
+ [(set (match_operand:SI 0 "register_operand" "= r")
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))]
+ "NDS32_EXT_DSP_P ()
+ && (!reload_completed
+ || !nds32_need_split_sms_p (operands[3], operands[4],
+ operands[5], operands[6]))"
+
+{
+ return nds32_output_sms (operands[3], operands[4],
+ operands[5], operands[6]);
+}
+ "NDS32_EXT_DSP_P ()
+ && !reload_completed
+ && nds32_need_split_sms_p (operands[3], operands[4],
+ operands[5], operands[6])"
+ [(const_int 1)]
+{
+ nds32_split_sms (operands[0], operands[1], operands[2],
+ operands[3], operands[4],
+ operands[5], operands[6]);
+ DONE;
+}
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "sms2"
+ [(set (match_operand:SI 0 "register_operand" "= r")
+ (minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))]
+ "NDS32_EXT_DSP_P ()
+ && (!reload_completed
+ || !nds32_need_split_sms_p (operands[3], operands[4],
+ operands[6], operands[5]))"
+{
+ return nds32_output_sms (operands[3], operands[4],
+ operands[6], operands[5]);
+}
+ "NDS32_EXT_DSP_P ()
+ && !reload_completed
+ && nds32_need_split_sms_p (operands[3], operands[4],
+ operands[6], operands[5])"
+ [(const_int 1)]
+{
+ nds32_split_sms (operands[0], operands[1], operands[2],
+ operands[3], operands[4],
+ operands[6], operands[5]);
+ DONE;
+}
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmda"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" "r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" "r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)]))))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmda\t%0, %1, %2"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmxda"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" "r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" "r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 1)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmxda\t%0, %1, %2"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmada"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI
+ (match_operand:SI 1 "register_operand" " 0")
+ (ss_plus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 0)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmada\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmada2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI
+ (match_operand:SI 1 "register_operand" " 0")
+ (ss_plus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 1)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmada\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmaxda"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI
+ (match_operand:SI 1 "register_operand" " 0")
+ (ss_plus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 1)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmaxda\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmads"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI
+ (match_operand:SI 1 "register_operand" " 0")
+ (ss_minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 0)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmads\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmadrs"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI
+ (match_operand:SI 1 "register_operand" " 0")
+ (ss_minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 1)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmadrs\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmaxds"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI
+ (match_operand:SI 1 "register_operand" " 0")
+ (ss_minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 1)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmaxds\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmsda"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_minus:SI
+ (match_operand:SI 1 "register_operand" " 0")
+ (ss_minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 0)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmsda\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmsxda"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_minus:SI
+ (match_operand:SI 1 "register_operand" " 0")
+ (ss_minus:SI
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)])))
+ (sign_extend:SI (vec_select:HI
+ (match_operand:V2HI 3 "register_operand" " r")
+ (parallel [(const_int 0)]))))
+ (mult:SI
+ (sign_extend:SI (vec_select:HI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (sign_extend:SI (vec_select:HI
+ (match_dup 3)
+ (parallel [(const_int 1)])))))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmsxda\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+;; smax[8|16] and umax[8|16]
+(define_insn "<opcode><mode>3"
+ [(set (match_operand:VQIHI 0 "register_operand" "=r")
+ (sumax:VQIHI (match_operand:VQIHI 1 "register_operand" " r")
+ (match_operand:VQIHI 2 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "<opcode><bits>\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+;; smin[8|16] and umin[8|16]
+(define_insn "<opcode><mode>3"
+ [(set (match_operand:VQIHI 0 "register_operand" "=r")
+ (sumin:VQIHI (match_operand:VQIHI 1 "register_operand" " r")
+ (match_operand:VQIHI 2 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "<opcode><bits>\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn "<opcode><mode>3_bb"
+ [(set (match_operand:<VELT> 0 "register_operand" "=r")
+ (sumin_max:<VELT> (vec_select:<VELT>
+ (match_operand:VQIHI 1 "register_operand" " r")
+ (parallel [(const_int 0)]))
+ (vec_select:<VELT>
+ (match_operand:VQIHI 2 "register_operand" " r")
+ (parallel [(const_int 0)]))))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "<opcode><bits>\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "<opcode><mode>3_tt"
+ [(set (match_operand:<VELT> 0 "register_operand" "=r")
+ (sumin_max:<VELT> (vec_select:<VELT>
+ (match_operand:VQIHI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))
+ (vec_select:<VELT>
+ (match_operand:VQIHI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))]
+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 0)]
+{
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_<opcode><mode>3 (tmp, operands[1], operands[2]));
+ emit_insn (gen_rotr<mode>_1 (tmp, tmp));
+ emit_move_insn (operands[0], simplify_gen_subreg (<VELT>mode, tmp, <MODE>mode, 0));
+ DONE;
+}
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "<opcode>v4qi3_22"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (sumin_max:QI (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 2)]))
+ (vec_select:QI
+ (match_operand:V4QI 2 "register_operand" " r")
+ (parallel [(const_int 2)]))))]
+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 0)]
+{
+ rtx tmp = gen_reg_rtx (V4QImode);
+ emit_insn (gen_<opcode>v4qi3 (tmp, operands[1], operands[2]));
+ emit_insn (gen_rotrv4qi_2 (tmp, tmp));
+ emit_move_insn (operands[0], simplify_gen_subreg (QImode, tmp, V4QImode, 0));
+ DONE;
+}
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "<opcode>v4qi3_33"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (sumin_max:QI (vec_select:QI
+ (match_operand:V4QI 1 "register_operand" " r")
+ (parallel [(const_int 3)]))
+ (vec_select:QI
+ (match_operand:V4QI 2 "register_operand" " r")
+ (parallel [(const_int 3)]))))]
+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 0)]
+{
+ rtx tmp = gen_reg_rtx (V4QImode);
+ emit_insn (gen_<opcode>v4qi3 (tmp, operands[1], operands[2]));
+ emit_insn (gen_rotrv4qi_3 (tmp, tmp));
+ emit_move_insn (operands[0], simplify_gen_subreg (QImode, tmp, V4QImode, 0));
+ DONE;
+}
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "<opcode>v2hi3_bbtt"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (vec_merge:V2HI
+ (vec_duplicate:V2HI
+ (sumin_max:HI (vec_select:HI
+ (match_operand:V2HI 1 "register_operand" " r")
+ (parallel [(const_int 1)]))
+ (vec_select:HI
+ (match_operand:V2HI 2 "register_operand" " r")
+ (parallel [(const_int 1)]))))
+ (vec_duplicate:V2HI
+ (sumin_max:HI (vec_select:HI
+ (match_dup:V2HI 1)
+ (parallel [(const_int 0)]))
+ (vec_select:HI
+ (match_dup:V2HI 2)
+ (parallel [(const_int 0)]))))
+ (const_int 2)))]
+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN"
+ "#"
+ "NDS32_EXT_DSP_P ()"
+ [(const_int 0)]
+{
+ emit_insn (gen_<opcode>v2hi3 (operands[0], operands[1], operands[2]));
+ DONE;
+}
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_expand "abs<mode>2"
+ [(set (match_operand:VQIHI 0 "register_operand" "=r")
+ (ss_abs:VQIHI (match_operand:VQIHI 1 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P () && TARGET_HW_ABS && !flag_wrapv"
+{
+})
+
+(define_insn "kabs<mode>2"
+ [(set (match_operand:VQIHI 0 "register_operand" "=r")
+ (ss_abs:VQIHI (match_operand:VQIHI 1 "register_operand" " r")))]
+ "NDS32_EXT_DSP_P ()"
+ "kabs<bits>\t%0, %1"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn "<su>mar64_1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (mult:DI
+ (extend:DI
+ (match_operand:SI 2 "register_operand" " r"))
+ (extend:DI
+ (match_operand:SI 3 "register_operand" " r")))))]
+ "NDS32_EXT_DSP_P ()"
+ "<su>mar64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "<su>mar64_2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (mult:DI
+ (extend:DI
+ (match_operand:SI 2 "register_operand" " r"))
+ (extend:DI
+ (match_operand:SI 3 "register_operand" " r")))
+ (match_operand:DI 1 "register_operand" " 0")))]
+ "NDS32_EXT_DSP_P ()"
+ "<su>mar64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "<su>mar64_3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (extend:DI
+ (mult:SI
+ (match_operand:SI 2 "register_operand" " r")
+ (match_operand:SI 3 "register_operand" " r")))))]
+ "NDS32_EXT_DSP_P ()"
+ "<su>mar64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "<su>mar64_4"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (extend:DI
+ (mult:SI
+ (match_operand:SI 2 "register_operand" " r")
+ (match_operand:SI 3 "register_operand" " r")))
+ (match_operand:DI 1 "register_operand" " 0")))]
+ "NDS32_EXT_DSP_P ()"
+ "<su>mar64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "<su>msr64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (mult:DI
+ (extend:DI
+ (match_operand:SI 2 "register_operand" " r"))
+ (extend:DI
+ (match_operand:SI 3 "register_operand" " r")))))]
+ "NDS32_EXT_DSP_P ()"
+ "<su>msr64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "<su>msr64_2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (extend:DI
+ (mult:SI
+ (match_operand:SI 2 "register_operand" " r")
+ (match_operand:SI 3 "register_operand" " r")))))]
+ "NDS32_EXT_DSP_P ()"
+ "<su>msr64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+;; kmar64, kmsr64, ukmar64 and ukmsr64
+(define_insn "kmar64_1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ss_plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (mult:DI
+ (sign_extend:DI
+ (match_operand:SI 2 "register_operand" " r"))
+ (sign_extend:DI
+ (match_operand:SI 3 "register_operand" " r")))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmar64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmar64_2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ss_plus:DI
+ (mult:DI
+ (sign_extend:DI
+ (match_operand:SI 2 "register_operand" " r"))
+ (sign_extend:DI
+ (match_operand:SI 3 "register_operand" " r")))
+ (match_operand:DI 1 "register_operand" " 0")))]
+ "NDS32_EXT_DSP_P ()"
+ "kmar64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "kmsr64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ss_minus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (mult:DI
+ (sign_extend:DI
+ (match_operand:SI 2 "register_operand" " r"))
+ (sign_extend:DI
+ (match_operand:SI 3 "register_operand" " r")))))]
+ "NDS32_EXT_DSP_P ()"
+ "kmsr64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "ukmar64_1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (us_plus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (mult:DI
+ (zero_extend:DI
+ (match_operand:SI 2 "register_operand" " r"))
+ (zero_extend:DI
+ (match_operand:SI 3 "register_operand" " r")))))]
+ "NDS32_EXT_DSP_P ()"
+ "ukmar64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "ukmar64_2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (us_plus:DI
+ (mult:DI
+ (zero_extend:DI
+ (match_operand:SI 2 "register_operand" " r"))
+ (zero_extend:DI
+ (match_operand:SI 3 "register_operand" " r")))
+ (match_operand:DI 1 "register_operand" " 0")))]
+ "NDS32_EXT_DSP_P ()"
+ "ukmar64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "ukmsr64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (us_minus:DI
+ (match_operand:DI 1 "register_operand" " 0")
+ (mult:DI
+ (zero_extend:DI
+ (match_operand:SI 2 "register_operand" " r"))
+ (zero_extend:DI
+ (match_operand:SI 3 "register_operand" " r")))))]
+ "NDS32_EXT_DSP_P ()"
+ "ukmsr64\t%0, %2, %3"
+ [(set_attr "type" "dmac")
+ (set_attr "length" "4")])
+
+(define_insn "bpick1"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI
+ (and:SI
+ (match_operand:SI 1 "register_operand" " r")
+ (match_operand:SI 3 "register_operand" " r"))
+ (and:SI
+ (match_operand:SI 2 "register_operand" " r")
+ (not:SI (match_dup 3)))))]
+ "NDS32_EXT_DSP_P ()"
+ "bpick\t%0, %1, %2, %3"
+ [(set_attr "type" "dbpick")
+ (set_attr "length" "4")])
+
+(define_insn "bpick2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI
+ (and:SI
+ (match_operand:SI 1 "register_operand" " r")
+ (match_operand:SI 2 "register_operand" " r"))
+ (and:SI
+ (not:SI (match_dup 2))
+ (match_operand:SI 3 "register_operand" " r"))))]
+ "NDS32_EXT_DSP_P ()"
+ "bpick\t%0, %1, %3, %2"
+ [(set_attr "type" "dbpick")
+ (set_attr "length" "4")])
+
+(define_insn "bpick3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI
+ (and:SI
+ (match_operand:SI 1 "register_operand" " r")
+ (match_operand:SI 2 "register_operand" " r"))
+ (and:SI
+ (match_operand:SI 3 "register_operand" " r")
+ (not:SI (match_dup 1)))))]
+ "NDS32_EXT_DSP_P ()"
+ "bpick\t%0, %2, %3, %1"
+ [(set_attr "type" "dbpick")
+ (set_attr "length" "4")])
+
+(define_insn "bpick4"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI
+ (and:SI
+ (match_operand:SI 1 "register_operand" " r")
+ (match_operand:SI 2 "register_operand" " r"))
+ (and:SI
+ (not:SI (match_dup 1))
+ (match_operand:SI 3 "register_operand" " r"))))]
+ "NDS32_EXT_DSP_P ()"
+ "bpick\t%0, %2, %3, %1"
+ [(set_attr "type" "dbpick")
+ (set_attr "length" "4")])
+
+(define_insn "bpick5"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI
+ (and:SI
+ (match_operand:SI 1 "register_operand" " r")
+ (not:SI (match_operand:SI 2 "register_operand" " r")))
+ (and:SI
+ (match_operand:SI 3 "register_operand" " r")
+ (match_dup 2))))]
+ "NDS32_EXT_DSP_P ()"
+ "bpick\t%0, %3, %1, %2"
+ [(set_attr "type" "dbpick")
+ (set_attr "length" "4")])
+
+(define_insn "bpick6"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI
+ (and:SI
+ (not:SI (match_operand:SI 1 "register_operand" " r"))
+ (match_operand:SI 2 "register_operand" " r"))
+ (and:SI
+ (match_operand:SI 3 "register_operand" " r")
+ (match_dup 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "bpick\t%0, %3, %2, %1"
+ [(set_attr "type" "dbpick")
+ (set_attr "length" "4")])
+
+(define_insn "bpick7"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI
+ (and:SI
+ (match_operand:SI 1 "register_operand" " r")
+ (not:SI (match_operand:SI 2 "register_operand" " r")))
+ (and:SI
+ (match_dup 2)
+ (match_operand:SI 3 "register_operand" " r"))))]
+ "NDS32_EXT_DSP_P ()"
+ "bpick\t%0, %3, %1, %2"
+ [(set_attr "type" "dbpick")
+ (set_attr "length" "4")])
+
+(define_insn "bpick8"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI
+ (and:SI
+ (not:SI (match_operand:SI 1 "register_operand" " r"))
+ (match_operand:SI 2 "register_operand" " r"))
+ (and:SI
+ (match_dup 1)
+ (match_operand:SI 3 "register_operand" " r"))))]
+ "NDS32_EXT_DSP_P ()"
+ "bpick\t%0, %3, %2, %1"
+ [(set_attr "type" "dbpick")
+ (set_attr "length" "4")])
+
+(define_insn "sraiu"
+ [(set (match_operand:SI 0 "register_operand" "= r, r")
+ (unspec:SI [(ashiftrt:SI (match_operand:SI 1 "register_operand" " r, r")
+ (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r"))]
+ UNSPEC_ROUND))]
+ "NDS32_EXT_DSP_P ()"
+ "@
+ srai.u\t%0, %1, %2
+ sra.u\t%0, %1, %2"
+ [(set_attr "type" "daluround")
+ (set_attr "length" "4")])
+
+(define_insn "kssl"
+ [(set (match_operand:SI 0 "register_operand" "= r, r")
+ (ss_ashift:SI (match_operand:SI 1 "register_operand" " r, r")
+ (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))]
+ "NDS32_EXT_DSP_P ()"
+ "@
+ kslli\t%0, %1, %2
+ ksll\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+(define_insn "kslraw_round"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (if_then_else:SI
+ (lt:SI (match_operand:SI 2 "register_operand" " r")
+ (const_int 0))
+ (unspec:SI [(ashiftrt:SI (match_operand:SI 1 "register_operand" " r")
+ (neg:SI (match_dup 2)))]
+ UNSPEC_ROUND)
+ (ss_ashift:SI (match_dup 1)
+ (match_dup 2))))]
+ "NDS32_EXT_DSP_P ()"
+ "kslraw.u\t%0, %1, %2"
+ [(set_attr "type" "daluround")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "<shift>di3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (shift_rotate:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:SI 2 "nds32_rimm6u_operand" "")))]
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ "#"
+ "NDS32_EXT_DSP_P () && !reload_completed"
+ [(const_int 0)]
+{
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ {
+ rtx tmp = gen_reg_rtx (DImode);
+ nds32_split_<code>di3 (tmp, operands[1], operands[2]);
+ emit_move_insn (operands[0], tmp);
+ }
+ else
+ nds32_split_<code>di3 (operands[0], operands[1], operands[2]);
+ DONE;
+})
+
+(define_insn "sclip32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIPS_OV))]
+ "NDS32_EXT_DSP_P ()"
+ "sclip32\t%0, %1, %2"
+ [(set_attr "type" "dclip")
+ (set_attr "length" "4")]
+)
+
+(define_insn "uclip32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIP_OV))]
+ "NDS32_EXT_DSP_P ()"
+ "uclip32\t%0, %1, %2"
+ [(set_attr "type" "dclip")
+ (set_attr "length" "4")]
+)
+
+(define_insn "bitrev"
+ [(set (match_operand:SI 0 "register_operand" "=r, r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" " r, r")
+ (match_operand:SI 2 "nds32_rimm5u_operand" " r, Iu05")]
+ UNSPEC_BITREV))]
+ ""
+ "@
+ bitrev\t%0, %1, %2
+ bitrevi\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")]
+)
+
+;; wext, wexti
+(define_insn "<su>wext"
+ [(set (match_operand:SI 0 "register_operand" "=r, r")
+ (truncate:SI
+ (shiftrt:DI
+ (match_operand:DI 1 "register_operand" " r, r")
+ (match_operand:SI 2 "nds32_rimm5u_operand" " r,Iu05"))))]
+ "NDS32_EXT_DSP_P ()"
+ "@
+ wext\t%0, %1, %2
+ wexti\t%0, %1, %2"
+ [(set_attr "type" "dwext")
+ (set_attr "length" "4")])
+
+;; 32-bit add/sub instruction: raddw and rsubw.
+(define_insn "r<opcode>si3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (ashiftrt:DI
+ (plus_minus:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "r<opcode>w\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
+
+;; 32-bit add/sub instruction: uraddw and ursubw.
+(define_insn "ur<opcode>si3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (lshiftrt:DI
+ (plus_minus:DI
+ (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
+ (zero_extend:DI (match_operand:SI 2 "register_operand" " r")))
+ (const_int 1))))]
+ "NDS32_EXT_DSP_P ()"
+ "ur<opcode>w\t%0, %1, %2"
+ [(set_attr "type" "dalu")
+ (set_attr "length" "4")])
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-elf.opt gcc-8.2.0/gcc/config/nds32/nds32-elf.opt
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-elf.opt 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-elf.opt 2019-01-25 15:38:32.825242648 +0100
@@ -0,0 +1,16 @@
+mcmodel=
+Target RejectNegative Joined Enum(nds32_cmodel_type) Var(nds32_cmodel_option) Init(CMODEL_MEDIUM)
+Specify the address generation strategy for code model.
+
+Enum
+Name(nds32_cmodel_type) Type(enum nds32_cmodel_type)
+Known cmodel types (for use with the -mcmodel= option):
+
+EnumValue
+Enum(nds32_cmodel_type) String(small) Value(CMODEL_SMALL)
+
+EnumValue
+Enum(nds32_cmodel_type) String(medium) Value(CMODEL_MEDIUM)
+
+EnumValue
+Enum(nds32_cmodel_type) String(large) Value(CMODEL_LARGE)
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-fp-as-gp.c gcc-8.2.0/gcc/config/nds32/nds32-fp-as-gp.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-fp-as-gp.c 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-fp-as-gp.c 2019-01-25 15:38:32.825242648 +0100
@@ -26,19 +26,256 @@
#include "system.h"
#include "coretypes.h"
#include "backend.h"
+#include "hard-reg-set.h"
+#include "tm_p.h"
+#include "rtl.h"
+#include "memmodel.h"
+#include "emit-rtl.h"
+#include "insn-config.h"
+#include "regs.h"
+#include "hard-reg-set.h"
+#include "ira.h"
+#include "ira-int.h"
+#include "df.h"
+#include "tree-core.h"
+#include "tree-pass.h"
+#include "nds32-protos.h"
/* ------------------------------------------------------------------------ */
+/* A helper function to check if this function should contain prologue. */
+static bool
+nds32_have_prologue_p (void)
+{
+ int i;
+
+ for (i = 0; i < 28; i++)
+ if (NDS32_REQUIRED_CALLEE_SAVED_P (i))
+ return true;
+
+ return (flag_pic
+ || NDS32_REQUIRED_CALLEE_SAVED_P (FP_REGNUM)
+ || NDS32_REQUIRED_CALLEE_SAVED_P (LP_REGNUM));
+}
+
+static int
+nds32_get_symbol_count (void)
+{
+ int symbol_count = 0;
+ rtx_insn *insn;
+ basic_block bb;
+
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ FOR_BB_INSNS (bb, insn)
+ {
+ /* Counting the insn number which the addressing mode is symbol. */
+ if (single_set (insn) && nds32_symbol_load_store_p (insn))
+ {
+ rtx pattern = PATTERN (insn);
+ rtx mem;
+ gcc_assert (GET_CODE (pattern) == SET);
+ if (GET_CODE (SET_SRC (pattern)) == REG )
+ mem = SET_DEST (pattern);
+ else
+ mem = SET_SRC (pattern);
+
+ /* We have only lwi37 and swi37 for fp-as-gp optimization,
+ so don't count any other than SImode.
+ MEM for QImode and HImode will wrap by ZERO_EXTEND
+ or SIGN_EXTEND */
+ if (GET_CODE (mem) == MEM)
+ symbol_count++;
+ }
+ }
+ }
+
+ return symbol_count;
+}
+
/* Function to determine whether it is worth to do fp_as_gp optimization.
- Return 0: It is NOT worth to do fp_as_gp optimization.
- Return 1: It is APPROXIMATELY worth to do fp_as_gp optimization.
+ Return false: It is NOT worth to do fp_as_gp optimization.
+ Return true: It is APPROXIMATELY worth to do fp_as_gp optimization.
Note that if it is worth to do fp_as_gp optimization,
we MUST set FP_REGNUM ever live in this function. */
-int
+static bool
nds32_fp_as_gp_check_available (void)
{
- /* By default we return 0. */
- return 0;
+ basic_block bb;
+ basic_block exit_bb;
+ edge_iterator ei;
+ edge e;
+ bool first_exit_blocks_p;
+
+ /* If there exists ANY of following conditions,
+ we DO NOT perform fp_as_gp optimization:
+ 1. TARGET_FORBID_FP_AS_GP is set
+ regardless of the TARGET_FORCE_FP_AS_GP.
+ 2. User explicitly uses 'naked'/'no_prologue' attribute.
+ We use nds32_naked_function_p() to help such checking.
+ 3. Not optimize for size.
+ 4. Need frame pointer.
+ 5. If $fp is already required to be saved,
+ it means $fp is already choosen by register allocator.
+ Thus we better not to use it for fp_as_gp optimization.
+ 6. This function is a vararg function.
+ DO NOT apply fp_as_gp optimization on this function
+ because it may change and break stack frame.
+ 7. The epilogue is empty.
+ This happens when the function uses exit()
+ or its attribute is no_return.
+ In that case, compiler will not expand epilogue
+ so that we have no chance to output .omit_fp_end directive. */
+ if (TARGET_FORBID_FP_AS_GP
+ || nds32_naked_function_p (current_function_decl)
+ || !optimize_size
+ || frame_pointer_needed
+ || NDS32_REQUIRED_CALLEE_SAVED_P (FP_REGNUM)
+ || (cfun->stdarg == 1)
+ || (find_fallthru_edge (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) == NULL))
+ return false;
+
+ /* Disable fp_as_gp if there is any infinite loop since the fp may
+ reuse in infinite loops by register rename.
+ For check infinite loops we should make sure exit_bb is post dominate
+ all other basic blocks if there is no infinite loops. */
+ first_exit_blocks_p = true;
+ exit_bb = NULL;
+
+ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
+ {
+ /* More than one exit block also do not perform fp_as_gp optimization. */
+ if (!first_exit_blocks_p)
+ return false;
+
+ exit_bb = e->src;
+ first_exit_blocks_p = false;
+ }
+
+ /* Not found exit_bb? just abort fp_as_gp! */
+ if (!exit_bb)
+ return false;
+
+ /* Each bb should post dominate by exit_bb if there is no infinite loop! */
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ if (!dominated_by_p (CDI_POST_DOMINATORS,
+ bb,
+ exit_bb))
+ return false;
+ }
+
+ /* Now we can check the possibility of using fp_as_gp optimization. */
+ if (TARGET_FORCE_FP_AS_GP)
+ {
+ /* User explicitly issues -mforce-fp-as-gp option. */
+ return true;
+ }
+ else
+ {
+ /* In the following we are going to evaluate whether
+ it is worth to do fp_as_gp optimization. */
+ bool good_gain = false;
+ int symbol_count;
+
+ int threshold;
+
+ /* We check if there already requires prologue.
+ Note that $gp will be saved in prologue for PIC code generation.
+ After that, we can set threshold by the existence of prologue.
+ Each fp-implied instruction will gain 2-byte code size
+ from gp-aware instruction, so we have following heuristics. */
+ if (flag_pic
+ || nds32_have_prologue_p ())
+ {
+ /* Have-prologue:
+ Compiler already intends to generate prologue content,
+ so the fp_as_gp optimization will only insert
+ 'la $fp,_FP_BASE_' instruction, which will be
+ converted into 4-byte instruction at link time.
+ The threshold is "3" symbol accesses, 2 + 2 + 2 > 4. */
+ threshold = 3;
+ }
+ else
+ {
+ /* None-prologue:
+ Compiler originally does not generate prologue content,
+ so the fp_as_gp optimization will NOT ONLY insert
+ 'la $fp,_FP_BASE' instruction, but also causes
+ push/pop instructions.
+ If we are using v3push (push25/pop25),
+ the threshold is "5" symbol accesses, 5*2 > 4 + 2 + 2;
+ If we are using normal push (smw/lmw),
+ the threshold is "5+2" symbol accesses 7*2 > 4 + 4 + 4. */
+ threshold = 5 + (TARGET_V3PUSH ? 0 : 2);
+ }
+
+ symbol_count = nds32_get_symbol_count ();
+
+ if (symbol_count >= threshold)
+ good_gain = true;
+
+ /* Enable fp_as_gp optimization when potential gain is good enough. */
+ return good_gain;
+ }
+}
+
+static unsigned int
+nds32_fp_as_gp (void)
+{
+ bool fp_as_gp_p;
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+ fp_as_gp_p = nds32_fp_as_gp_check_available ();
+
+ /* Here is a hack to IRA for enable/disable a hard register per function.
+ We *MUST* review this way after migrate gcc 4.9! */
+ if (fp_as_gp_p) {
+ SET_HARD_REG_BIT(this_target_ira_int->x_no_unit_alloc_regs, FP_REGNUM);
+ df_set_regs_ever_live (FP_REGNUM, 1);
+ } else {
+ CLEAR_HARD_REG_BIT(this_target_ira_int->x_no_unit_alloc_regs, FP_REGNUM);
+ }
+
+ cfun->machine->fp_as_gp_p = fp_as_gp_p;
+
+ free_dominance_info (CDI_POST_DOMINATORS);
+ return 1;
+}
+
+const pass_data pass_data_nds32_fp_as_gp =
+{
+ RTL_PASS, /* type */
+ "fp_as_gp", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_MACH_DEP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+class pass_nds32_fp_as_gp : public rtl_opt_pass
+{
+public:
+ pass_nds32_fp_as_gp (gcc::context *ctxt)
+ : rtl_opt_pass (pass_data_nds32_fp_as_gp, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate (function *)
+ {
+ return !TARGET_LINUX_ABI
+ && TARGET_16_BIT
+ && optimize_size;
+ }
+ unsigned int execute (function *) { return nds32_fp_as_gp (); }
+};
+
+rtl_opt_pass *
+make_pass_nds32_fp_as_gp (gcc::context *ctxt)
+{
+ return new pass_nds32_fp_as_gp (ctxt);
}
/* ------------------------------------------------------------------------ */
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-fpu.md gcc-8.2.0/gcc/config/nds32/nds32-fpu.md
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-fpu.md 2018-04-06 07:51:33.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-fpu.md 2019-01-25 15:38:32.825242648 +0100
@@ -1,5 +1,5 @@
;; Machine description of Andes NDS32 cpu for GNU compiler
-;; Copyright (C) 2012-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
;; Contributed by Andes Technology Corporation.
;;
;; This file is part of GCC.
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-graywolf.md gcc-8.2.0/gcc/config/nds32/nds32-graywolf.md
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-graywolf.md 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-graywolf.md 2019-01-25 15:38:32.825242648 +0100
@@ -0,0 +1,471 @@
+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; 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
+;; <http://www.gnu.org/licenses/>.
+
+;; ------------------------------------------------------------------------
+;; Define Graywolf pipeline settings.
+;; ------------------------------------------------------------------------
+
+(define_automaton "nds32_graywolf_machine")
+
+(define_cpu_unit "gw_ii_0" "nds32_graywolf_machine")
+(define_cpu_unit "gw_ii_1" "nds32_graywolf_machine")
+(define_cpu_unit "gw_ex_p0" "nds32_graywolf_machine")
+(define_cpu_unit "gw_mm_p0" "nds32_graywolf_machine")
+(define_cpu_unit "gw_wb_p0" "nds32_graywolf_machine")
+(define_cpu_unit "gw_ex_p1" "nds32_graywolf_machine")
+(define_cpu_unit "gw_mm_p1" "nds32_graywolf_machine")
+(define_cpu_unit "gw_wb_p1" "nds32_graywolf_machine")
+(define_cpu_unit "gw_iq_p2" "nds32_graywolf_machine")
+(define_cpu_unit "gw_rf_p2" "nds32_graywolf_machine")
+(define_cpu_unit "gw_e1_p2" "nds32_graywolf_machine")
+(define_cpu_unit "gw_e2_p2" "nds32_graywolf_machine")
+(define_cpu_unit "gw_e3_p2" "nds32_graywolf_machine")
+(define_cpu_unit "gw_e4_p2" "nds32_graywolf_machine")
+
+(define_reservation "gw_ii" "gw_ii_0 | gw_ii_1")
+(define_reservation "gw_ex" "gw_ex_p0 | gw_ex_p1")
+(define_reservation "gw_mm" "gw_mm_p0 | gw_mm_p1")
+(define_reservation "gw_wb" "gw_wb_p0 | gw_wb_p1")
+
+(define_reservation "gw_ii_all" "gw_ii_0 + gw_ii_1")
+
+(define_insn_reservation "nds_gw_unknown" 1
+ (and (eq_attr "type" "unknown")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_ex, gw_mm, gw_wb")
+
+(define_insn_reservation "nds_gw_misc" 1
+ (and (eq_attr "type" "misc")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_ex, gw_mm, gw_wb")
+
+(define_insn_reservation "nds_gw_mmu" 1
+ (and (eq_attr "type" "mmu")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_ex, gw_mm, gw_wb")
+
+(define_insn_reservation "nds_gw_alu" 1
+ (and (and (eq_attr "type" "alu")
+ (match_test "!nds32::movd44_insn_p (insn)"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_ex, gw_mm, gw_wb")
+
+(define_insn_reservation "nds_gw_movd44" 1
+ (and (and (eq_attr "type" "alu")
+ (match_test "nds32::movd44_insn_p (insn)"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex, gw_mm, gw_wb")
+
+(define_insn_reservation "nds_gw_alu_shift" 1
+ (and (eq_attr "type" "alu_shift")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_ex*2, gw_mm, gw_wb")
+
+(define_insn_reservation "nds_gw_pbsad" 1
+ (and (eq_attr "type" "pbsad")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_ex*3, gw_mm, gw_wb")
+
+(define_insn_reservation "nds_gw_pbsada" 1
+ (and (eq_attr "type" "pbsada")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_ex*3, gw_mm, gw_wb")
+
+(define_insn_reservation "nds_gw_load" 1
+ (and (and (eq_attr "type" "load")
+ (match_test "!nds32::post_update_insn_p (insn)"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_load_2w" 1
+ (and (and (eq_attr "type" "load")
+ (match_test "nds32::post_update_insn_p (insn)"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_all, gw_ex_p1, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store" 1
+ (and (and (eq_attr "type" "store")
+ (match_test "!nds32::store_offset_reg_p (insn)"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store_3r" 1
+ (and (and (eq_attr "type" "store")
+ (match_test "nds32::store_offset_reg_p (insn)"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_all, gw_ex_p1, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_load_multiple_1" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "1"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_load_multiple_2" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "2"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*2, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_load_multiple_3" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "3"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*3, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_load_multiple_4" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "4"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_load_multiple_5" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "5"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_load_multiple_6" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "6"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_load_multiple_7" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "7"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_load_multiple_8" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "8"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_load_multiple_12" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "12"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store_multiple_1" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "1"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store_multiple_2" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "2"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*2, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store_multiple_3" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "3"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*3, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store_multiple_4" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "4"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store_multiple_5" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "5"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store_multiple_6" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "6"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store_multiple_7" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "7"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store_multiple_8" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "8"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_store_multiple_12" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "12"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1")
+
+(define_insn_reservation "nds_gw_mul_fast1" 1
+ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_1")
+ (and (eq_attr "type" "mul")
+ (eq_attr "pipeline_model" "graywolf")))
+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_mul_fast2" 1
+ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_2")
+ (and (eq_attr "type" "mul")
+ (eq_attr "pipeline_model" "graywolf")))
+ "gw_ii_0, gw_ex_p0*2, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_mul_slow" 1
+ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW")
+ (and (eq_attr "type" "mul")
+ (eq_attr "pipeline_model" "graywolf")))
+ "gw_ii_0, gw_ex_p0*4, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_mac_fast1" 1
+ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_1")
+ (and (eq_attr "type" "mac")
+ (eq_attr "pipeline_model" "graywolf")))
+ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_mac_fast2" 1
+ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_2")
+ (and (eq_attr "type" "mac")
+ (eq_attr "pipeline_model" "graywolf")))
+ "gw_ii_all, gw_ex_p0*2, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_mac_slow" 1
+ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW")
+ (and (eq_attr "type" "mac")
+ (eq_attr "pipeline_model" "graywolf")))
+ "gw_ii_all, gw_ex_p0*4, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_div" 1
+ (and (and (eq_attr "type" "div")
+ (match_test "!nds32::divmod_p (insn)"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_0, gw_ex_p0*4, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_div_2w" 1
+ (and (and (eq_attr "type" "div")
+ (match_test "nds32::divmod_p (insn)"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_all, gw_ex_p0*4, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_branch" 1
+ (and (eq_attr "type" "branch")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_dsp_alu" 1
+ (and (eq_attr "type" "dalu")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_ex, gw_mm, gw_wb")
+
+(define_insn_reservation "nds_gw_dsp_alu64" 1
+ (and (eq_attr "type" "dalu64")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_dsp_alu_round" 1
+ (and (eq_attr "type" "daluround")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_dsp_cmp" 1
+ (and (eq_attr "type" "dcmp")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_dsp_clip" 1
+ (and (eq_attr "type" "dclip")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_dsp_mul" 1
+ (and (eq_attr "type" "dmul")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_dsp_mac" 1
+ (and (eq_attr "type" "dmac")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_dsp_insb" 1
+ (and (eq_attr "type" "dinsb")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_dsp_pack" 1
+ (and (eq_attr "type" "dpack")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_dsp_bpick" 1
+ (and (eq_attr "type" "dbpick")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_dsp_wext" 1
+ (and (eq_attr "type" "dwext")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0")
+
+(define_insn_reservation "nds_gw_fpu_alu" 4
+ (and (eq_attr "type" "falu")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_muls" 4
+ (and (eq_attr "type" "fmuls")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_muld" 4
+ (and (eq_attr "type" "fmuld")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*2, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_macs" 4
+ (and (eq_attr "type" "fmacs")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*3, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_macd" 4
+ (and (eq_attr "type" "fmacd")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*4, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_divs" 4
+ (and (ior (eq_attr "type" "fdivs")
+ (eq_attr "type" "fsqrts"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*14, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_divd" 4
+ (and (ior (eq_attr "type" "fdivd")
+ (eq_attr "type" "fsqrtd"))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*28, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_fast_alu" 2
+ (and (ior (eq_attr "type" "fcmp")
+ (ior (eq_attr "type" "fabs")
+ (ior (eq_attr "type" "fcpy")
+ (eq_attr "type" "fcmov"))))
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_fmtsr" 1
+ (and (eq_attr "type" "fmtsr")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_fmtdr" 1
+ (and (eq_attr "type" "fmtdr")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_ii+gw_iq_p2, gw_iq_p2+gw_rf_p2, gw_rf_p2+gw_e1_p2, gw_e1_p2+gw_e2_p2, gw_e2_p2+gw_e3_p2, gw_e3_p2+gw_e4_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_fmfsr" 1
+ (and (eq_attr "type" "fmfsr")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_fmfdr" 1
+ (and (eq_attr "type" "fmfdr")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_ii+gw_iq_p2, gw_iq_p2+gw_rf_p2, gw_rf_p2+gw_e1_p2, gw_e1_p2+gw_e2_p2, gw_e2_p2+gw_e3_p2, gw_e3_p2+gw_e4_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_load" 3
+ (and (eq_attr "type" "fload")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2")
+
+(define_insn_reservation "nds_gw_fpu_store" 1
+ (and (eq_attr "type" "fstore")
+ (eq_attr "pipeline_model" "graywolf"))
+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2")
+
+;; FPU_ADDR_OUT -> FPU_ADDR_IN
+;; Main pipeline rules don't need this because those default latency is 1.
+(define_bypass 1
+ "nds_gw_fpu_load, nds_gw_fpu_store"
+ "nds_gw_fpu_load, nds_gw_fpu_store"
+ "nds32_gw_ex_to_ex_p"
+)
+
+;; LD, MUL, MAC, DIV, DALU64, DMUL, DMAC, DALUROUND, DBPICK, DWEXT
+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU,
+;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb
+(define_bypass 2
+ "nds_gw_load, nds_gw_load_2w,\
+ nds_gw_mul_fast1, nds_gw_mul_fast2, nds_gw_mul_slow,\
+ nds_gw_mac_fast1, nds_gw_mac_fast2, nds_gw_mac_slow,\
+ nds_gw_div, nds_gw_div_2w,\
+ nds_gw_dsp_alu64, nds_gw_dsp_mul, nds_gw_dsp_mac,\
+ nds_gw_dsp_alu_round, nds_gw_dsp_bpick, nds_gw_dsp_wext"
+ "nds_gw_alu, nds_gw_movd44, nds_gw_alu_shift,\
+ nds_gw_pbsad, nds_gw_pbsada,\
+ nds_gw_mul_fast1, nds_gw_mul_fast2, nds_gw_mul_slow,\
+ nds_gw_mac_fast1, nds_gw_mac_fast2, nds_gw_mac_slow,\
+ nds_gw_branch,\
+ nds_gw_div, nds_gw_div_2w,\
+ nds_gw_load, nds_gw_load_2w, nds_gw_store, nds_gw_store_3r,\
+ nds_gw_load_multiple_1,nds_gw_load_multiple_2, nds_gw_load_multiple_3,\
+ nds_gw_load_multiple_4,nds_gw_load_multiple_5, nds_gw_load_multiple_6,\
+ nds_gw_load_multiple_7,nds_gw_load_multiple_8, nds_gw_load_multiple_12,\
+ nds_gw_store_multiple_1,nds_gw_store_multiple_2, nds_gw_store_multiple_3,\
+ nds_gw_store_multiple_4,nds_gw_store_multiple_5, nds_gw_store_multiple_6,\
+ nds_gw_store_multiple_7,nds_gw_store_multiple_8, nds_gw_store_multiple_12,\
+ nds_gw_mmu,\
+ nds_gw_dsp_alu, nds_gw_dsp_alu_round,\
+ nds_gw_dsp_mul, nds_gw_dsp_mac, nds_gw_dsp_pack,\
+ nds_gw_dsp_insb, nds_gw_dsp_cmp, nds_gw_dsp_clip,\
+ nds_gw_dsp_wext, nds_gw_dsp_bpick"
+ "nds32_gw_mm_to_ex_p"
+)
+
+;; LMW(N, N)
+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU
+;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb
+(define_bypass 2
+ "nds_gw_load_multiple_1,nds_gw_load_multiple_2, nds_gw_load_multiple_3,\
+ nds_gw_load_multiple_4,nds_gw_load_multiple_5, nds_gw_load_multiple_6,\
+ nds_gw_load_multiple_7,nds_gw_load_multiple_8, nds_gw_load_multiple_12"
+ "nds_gw_alu, nds_gw_movd44, nds_gw_alu_shift,\
+ nds_gw_pbsad, nds_gw_pbsada,\
+ nds_gw_mul_fast1, nds_gw_mul_fast2, nds_gw_mul_slow,\
+ nds_gw_mac_fast1, nds_gw_mac_fast2, nds_gw_mac_slow,\
+ nds_gw_branch,\
+ nds_gw_div, nds_gw_div_2w,\
+ nds_gw_load, nds_gw_load_2w, nds_gw_store, nds_gw_store_3r,\
+ nds_gw_load_multiple_1,nds_gw_load_multiple_2, nds_gw_load_multiple_3,\
+ nds_gw_load_multiple_4,nds_gw_load_multiple_5, nds_gw_load_multiple_6,\
+ nds_gw_load_multiple_7,nds_gw_load_multiple_8, nds_gw_load_multiple_12,\
+ nds_gw_store_multiple_1,nds_gw_store_multiple_2, nds_gw_store_multiple_3,\
+ nds_gw_store_multiple_4,nds_gw_store_multiple_5, nds_gw_store_multiple_6,\
+ nds_gw_store_multiple_7,nds_gw_store_multiple_8, nds_gw_store_multiple_12,\
+ nds_gw_mmu,\
+ nds_gw_dsp_alu, nds_gw_dsp_alu_round,\
+ nds_gw_dsp_mul, nds_gw_dsp_mac, nds_gw_dsp_pack,\
+ nds_gw_dsp_insb, nds_gw_dsp_cmp, nds_gw_dsp_clip,\
+ nds_gw_dsp_wext, nds_gw_dsp_bpick"
+ "nds32_gw_last_load_to_ex_p"
+)
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32.h gcc-8.2.0/gcc/config/nds32/nds32.h
--- gcc-8.2.0.orig/gcc/config/nds32/nds32.h 2018-05-07 03:27:52.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32.h 2019-01-25 15:44:03.534160189 +0100
@@ -36,6 +36,16 @@
#define NDS32_SYMBOL_REF_RODATA_P(x) \
((SYMBOL_REF_FLAGS (x) & NDS32_SYMBOL_FLAG_RODATA) != 0)
+enum nds32_relax_insn_type
+{
+ RELAX_ORI,
+ RELAX_PLT_ADD,
+ RELAX_TLS_ADD_or_LW,
+ RELAX_TLS_ADD_LW,
+ RELAX_TLS_LW_JRAL,
+ RELAX_DONE
+};
+
/* Classifies expand result for expand helper function. */
enum nds32_expand_result_type
{
@@ -140,6 +150,9 @@
Check gcc/common/config/nds32/nds32-common.c for the optimizations that
apply -malways-align. */
#define NDS32_ALIGN_P() (TARGET_ALWAYS_ALIGN)
+
+#define NDS32_EXT_DSP_P() (TARGET_EXT_DSP && !TARGET_FORCE_NO_EXT_DSP)
+
/* Get alignment according to mode or type information.
When 'type' is nonnull, there is no need to look at 'mode'. */
#define NDS32_MODE_TYPE_ALIGN(mode, type) \
@@ -305,6 +318,10 @@
2. The rtl lowering and optimization are close to target code.
For this case we need address to be strictly aligned. */
int strict_aligned_p;
+
+ /* Record two similar attributes status. */
+ int attr_naked_p;
+ int attr_no_prologue_p;
};
/* A C structure that contains the arguments information. */
@@ -350,7 +367,8 @@
{
NDS32_NESTED,
NDS32_NOT_NESTED,
- NDS32_NESTED_READY
+ NDS32_NESTED_READY,
+ NDS32_CRITICAL
};
/* Define structure to record isr information.
@@ -378,6 +396,13 @@
unless user specifies attribute to change it. */
enum nds32_isr_nested_type nested_type;
+ /* Secure isr level.
+ Currently we have 0-3 security level.
+ It should be set to 0 by default.
+ For security processors, this is determined by secure
+ attribute or compiler options. */
+ unsigned int security_level;
+
/* Total vectors.
The total vectors = interrupt + exception numbers + reset.
It should be set to 0 by default.
@@ -439,7 +464,30 @@
NDS32_BUILTIN_FFB,
NDS32_BUILTIN_FFMISM,
NDS32_BUILTIN_FLMISM,
-
+ NDS32_BUILTIN_KADDW,
+ NDS32_BUILTIN_KSUBW,
+ NDS32_BUILTIN_KADDH,
+ NDS32_BUILTIN_KSUBH,
+ NDS32_BUILTIN_KDMBB,
+ NDS32_BUILTIN_V_KDMBB,
+ NDS32_BUILTIN_KDMBT,
+ NDS32_BUILTIN_V_KDMBT,
+ NDS32_BUILTIN_KDMTB,
+ NDS32_BUILTIN_V_KDMTB,
+ NDS32_BUILTIN_KDMTT,
+ NDS32_BUILTIN_V_KDMTT,
+ NDS32_BUILTIN_KHMBB,
+ NDS32_BUILTIN_V_KHMBB,
+ NDS32_BUILTIN_KHMBT,
+ NDS32_BUILTIN_V_KHMBT,
+ NDS32_BUILTIN_KHMTB,
+ NDS32_BUILTIN_V_KHMTB,
+ NDS32_BUILTIN_KHMTT,
+ NDS32_BUILTIN_V_KHMTT,
+ NDS32_BUILTIN_KSLRAW,
+ NDS32_BUILTIN_KSLRAW_U,
+ NDS32_BUILTIN_RDOV,
+ NDS32_BUILTIN_CLROV,
NDS32_BUILTIN_ROTR,
NDS32_BUILTIN_SVA,
NDS32_BUILTIN_SVS,
@@ -512,7 +560,295 @@
NDS32_BUILTIN_SET_TRIG_LEVEL,
NDS32_BUILTIN_SET_TRIG_EDGE,
NDS32_BUILTIN_GET_TRIG_TYPE,
-
+ NDS32_BUILTIN_DSP_BEGIN,
+ NDS32_BUILTIN_ADD16,
+ NDS32_BUILTIN_V_UADD16,
+ NDS32_BUILTIN_V_SADD16,
+ NDS32_BUILTIN_RADD16,
+ NDS32_BUILTIN_V_RADD16,
+ NDS32_BUILTIN_URADD16,
+ NDS32_BUILTIN_V_URADD16,
+ NDS32_BUILTIN_KADD16,
+ NDS32_BUILTIN_V_KADD16,
+ NDS32_BUILTIN_UKADD16,
+ NDS32_BUILTIN_V_UKADD16,
+ NDS32_BUILTIN_SUB16,
+ NDS32_BUILTIN_V_USUB16,
+ NDS32_BUILTIN_V_SSUB16,
+ NDS32_BUILTIN_RSUB16,
+ NDS32_BUILTIN_V_RSUB16,
+ NDS32_BUILTIN_URSUB16,
+ NDS32_BUILTIN_V_URSUB16,
+ NDS32_BUILTIN_KSUB16,
+ NDS32_BUILTIN_V_KSUB16,
+ NDS32_BUILTIN_UKSUB16,
+ NDS32_BUILTIN_V_UKSUB16,
+ NDS32_BUILTIN_CRAS16,
+ NDS32_BUILTIN_V_UCRAS16,
+ NDS32_BUILTIN_V_SCRAS16,
+ NDS32_BUILTIN_RCRAS16,
+ NDS32_BUILTIN_V_RCRAS16,
+ NDS32_BUILTIN_URCRAS16,
+ NDS32_BUILTIN_V_URCRAS16,
+ NDS32_BUILTIN_KCRAS16,
+ NDS32_BUILTIN_V_KCRAS16,
+ NDS32_BUILTIN_UKCRAS16,
+ NDS32_BUILTIN_V_UKCRAS16,
+ NDS32_BUILTIN_CRSA16,
+ NDS32_BUILTIN_V_UCRSA16,
+ NDS32_BUILTIN_V_SCRSA16,
+ NDS32_BUILTIN_RCRSA16,
+ NDS32_BUILTIN_V_RCRSA16,
+ NDS32_BUILTIN_URCRSA16,
+ NDS32_BUILTIN_V_URCRSA16,
+ NDS32_BUILTIN_KCRSA16,
+ NDS32_BUILTIN_V_KCRSA16,
+ NDS32_BUILTIN_UKCRSA16,
+ NDS32_BUILTIN_V_UKCRSA16,
+ NDS32_BUILTIN_ADD8,
+ NDS32_BUILTIN_V_UADD8,
+ NDS32_BUILTIN_V_SADD8,
+ NDS32_BUILTIN_RADD8,
+ NDS32_BUILTIN_V_RADD8,
+ NDS32_BUILTIN_URADD8,
+ NDS32_BUILTIN_V_URADD8,
+ NDS32_BUILTIN_KADD8,
+ NDS32_BUILTIN_V_KADD8,
+ NDS32_BUILTIN_UKADD8,
+ NDS32_BUILTIN_V_UKADD8,
+ NDS32_BUILTIN_SUB8,
+ NDS32_BUILTIN_V_USUB8,
+ NDS32_BUILTIN_V_SSUB8,
+ NDS32_BUILTIN_RSUB8,
+ NDS32_BUILTIN_V_RSUB8,
+ NDS32_BUILTIN_URSUB8,
+ NDS32_BUILTIN_V_URSUB8,
+ NDS32_BUILTIN_KSUB8,
+ NDS32_BUILTIN_V_KSUB8,
+ NDS32_BUILTIN_UKSUB8,
+ NDS32_BUILTIN_V_UKSUB8,
+ NDS32_BUILTIN_SRA16,
+ NDS32_BUILTIN_V_SRA16,
+ NDS32_BUILTIN_SRA16_U,
+ NDS32_BUILTIN_V_SRA16_U,
+ NDS32_BUILTIN_SRL16,
+ NDS32_BUILTIN_V_SRL16,
+ NDS32_BUILTIN_SRL16_U,
+ NDS32_BUILTIN_V_SRL16_U,
+ NDS32_BUILTIN_SLL16,
+ NDS32_BUILTIN_V_SLL16,
+ NDS32_BUILTIN_KSLL16,
+ NDS32_BUILTIN_V_KSLL16,
+ NDS32_BUILTIN_KSLRA16,
+ NDS32_BUILTIN_V_KSLRA16,
+ NDS32_BUILTIN_KSLRA16_U,
+ NDS32_BUILTIN_V_KSLRA16_U,
+ NDS32_BUILTIN_CMPEQ16,
+ NDS32_BUILTIN_V_SCMPEQ16,
+ NDS32_BUILTIN_V_UCMPEQ16,
+ NDS32_BUILTIN_SCMPLT16,
+ NDS32_BUILTIN_V_SCMPLT16,
+ NDS32_BUILTIN_SCMPLE16,
+ NDS32_BUILTIN_V_SCMPLE16,
+ NDS32_BUILTIN_UCMPLT16,
+ NDS32_BUILTIN_V_UCMPLT16,
+ NDS32_BUILTIN_UCMPLE16,
+ NDS32_BUILTIN_V_UCMPLE16,
+ NDS32_BUILTIN_CMPEQ8,
+ NDS32_BUILTIN_V_SCMPEQ8,
+ NDS32_BUILTIN_V_UCMPEQ8,
+ NDS32_BUILTIN_SCMPLT8,
+ NDS32_BUILTIN_V_SCMPLT8,
+ NDS32_BUILTIN_SCMPLE8,
+ NDS32_BUILTIN_V_SCMPLE8,
+ NDS32_BUILTIN_UCMPLT8,
+ NDS32_BUILTIN_V_UCMPLT8,
+ NDS32_BUILTIN_UCMPLE8,
+ NDS32_BUILTIN_V_UCMPLE8,
+ NDS32_BUILTIN_SMIN16,
+ NDS32_BUILTIN_V_SMIN16,
+ NDS32_BUILTIN_UMIN16,
+ NDS32_BUILTIN_V_UMIN16,
+ NDS32_BUILTIN_SMAX16,
+ NDS32_BUILTIN_V_SMAX16,
+ NDS32_BUILTIN_UMAX16,
+ NDS32_BUILTIN_V_UMAX16,
+ NDS32_BUILTIN_SCLIP16,
+ NDS32_BUILTIN_V_SCLIP16,
+ NDS32_BUILTIN_UCLIP16,
+ NDS32_BUILTIN_V_UCLIP16,
+ NDS32_BUILTIN_KHM16,
+ NDS32_BUILTIN_V_KHM16,
+ NDS32_BUILTIN_KHMX16,
+ NDS32_BUILTIN_V_KHMX16,
+ NDS32_BUILTIN_KABS16,
+ NDS32_BUILTIN_V_KABS16,
+ NDS32_BUILTIN_SMIN8,
+ NDS32_BUILTIN_V_SMIN8,
+ NDS32_BUILTIN_UMIN8,
+ NDS32_BUILTIN_V_UMIN8,
+ NDS32_BUILTIN_SMAX8,
+ NDS32_BUILTIN_V_SMAX8,
+ NDS32_BUILTIN_UMAX8,
+ NDS32_BUILTIN_V_UMAX8,
+ NDS32_BUILTIN_KABS8,
+ NDS32_BUILTIN_V_KABS8,
+ NDS32_BUILTIN_SUNPKD810,
+ NDS32_BUILTIN_V_SUNPKD810,
+ NDS32_BUILTIN_SUNPKD820,
+ NDS32_BUILTIN_V_SUNPKD820,
+ NDS32_BUILTIN_SUNPKD830,
+ NDS32_BUILTIN_V_SUNPKD830,
+ NDS32_BUILTIN_SUNPKD831,
+ NDS32_BUILTIN_V_SUNPKD831,
+ NDS32_BUILTIN_ZUNPKD810,
+ NDS32_BUILTIN_V_ZUNPKD810,
+ NDS32_BUILTIN_ZUNPKD820,
+ NDS32_BUILTIN_V_ZUNPKD820,
+ NDS32_BUILTIN_ZUNPKD830,
+ NDS32_BUILTIN_V_ZUNPKD830,
+ NDS32_BUILTIN_ZUNPKD831,
+ NDS32_BUILTIN_V_ZUNPKD831,
+ NDS32_BUILTIN_RADDW,
+ NDS32_BUILTIN_URADDW,
+ NDS32_BUILTIN_RSUBW,
+ NDS32_BUILTIN_URSUBW,
+ NDS32_BUILTIN_SRA_U,
+ NDS32_BUILTIN_KSLL,
+ NDS32_BUILTIN_PKBB16,
+ NDS32_BUILTIN_V_PKBB16,
+ NDS32_BUILTIN_PKBT16,
+ NDS32_BUILTIN_V_PKBT16,
+ NDS32_BUILTIN_PKTB16,
+ NDS32_BUILTIN_V_PKTB16,
+ NDS32_BUILTIN_PKTT16,
+ NDS32_BUILTIN_V_PKTT16,
+ NDS32_BUILTIN_SMMUL,
+ NDS32_BUILTIN_SMMUL_U,
+ NDS32_BUILTIN_KMMAC,
+ NDS32_BUILTIN_KMMAC_U,
+ NDS32_BUILTIN_KMMSB,
+ NDS32_BUILTIN_KMMSB_U,
+ NDS32_BUILTIN_KWMMUL,
+ NDS32_BUILTIN_KWMMUL_U,
+ NDS32_BUILTIN_SMMWB,
+ NDS32_BUILTIN_V_SMMWB,
+ NDS32_BUILTIN_SMMWB_U,
+ NDS32_BUILTIN_V_SMMWB_U,
+ NDS32_BUILTIN_SMMWT,
+ NDS32_BUILTIN_V_SMMWT,
+ NDS32_BUILTIN_SMMWT_U,
+ NDS32_BUILTIN_V_SMMWT_U,
+ NDS32_BUILTIN_KMMAWB,
+ NDS32_BUILTIN_V_KMMAWB,
+ NDS32_BUILTIN_KMMAWB_U,
+ NDS32_BUILTIN_V_KMMAWB_U,
+ NDS32_BUILTIN_KMMAWT,
+ NDS32_BUILTIN_V_KMMAWT,
+ NDS32_BUILTIN_KMMAWT_U,
+ NDS32_BUILTIN_V_KMMAWT_U,
+ NDS32_BUILTIN_SMBB,
+ NDS32_BUILTIN_V_SMBB,
+ NDS32_BUILTIN_SMBT,
+ NDS32_BUILTIN_V_SMBT,
+ NDS32_BUILTIN_SMTT,
+ NDS32_BUILTIN_V_SMTT,
+ NDS32_BUILTIN_KMDA,
+ NDS32_BUILTIN_V_KMDA,
+ NDS32_BUILTIN_KMXDA,
+ NDS32_BUILTIN_V_KMXDA,
+ NDS32_BUILTIN_SMDS,
+ NDS32_BUILTIN_V_SMDS,
+ NDS32_BUILTIN_SMDRS,
+ NDS32_BUILTIN_V_SMDRS,
+ NDS32_BUILTIN_SMXDS,
+ NDS32_BUILTIN_V_SMXDS,
+ NDS32_BUILTIN_KMABB,
+ NDS32_BUILTIN_V_KMABB,
+ NDS32_BUILTIN_KMABT,
+ NDS32_BUILTIN_V_KMABT,
+ NDS32_BUILTIN_KMATT,
+ NDS32_BUILTIN_V_KMATT,
+ NDS32_BUILTIN_KMADA,
+ NDS32_BUILTIN_V_KMADA,
+ NDS32_BUILTIN_KMAXDA,
+ NDS32_BUILTIN_V_KMAXDA,
+ NDS32_BUILTIN_KMADS,
+ NDS32_BUILTIN_V_KMADS,
+ NDS32_BUILTIN_KMADRS,
+ NDS32_BUILTIN_V_KMADRS,
+ NDS32_BUILTIN_KMAXDS,
+ NDS32_BUILTIN_V_KMAXDS,
+ NDS32_BUILTIN_KMSDA,
+ NDS32_BUILTIN_V_KMSDA,
+ NDS32_BUILTIN_KMSXDA,
+ NDS32_BUILTIN_V_KMSXDA,
+ NDS32_BUILTIN_SMAL,
+ NDS32_BUILTIN_V_SMAL,
+ NDS32_BUILTIN_BITREV,
+ NDS32_BUILTIN_WEXT,
+ NDS32_BUILTIN_BPICK,
+ NDS32_BUILTIN_INSB,
+ NDS32_BUILTIN_SADD64,
+ NDS32_BUILTIN_UADD64,
+ NDS32_BUILTIN_RADD64,
+ NDS32_BUILTIN_URADD64,
+ NDS32_BUILTIN_KADD64,
+ NDS32_BUILTIN_UKADD64,
+ NDS32_BUILTIN_SSUB64,
+ NDS32_BUILTIN_USUB64,
+ NDS32_BUILTIN_RSUB64,
+ NDS32_BUILTIN_URSUB64,
+ NDS32_BUILTIN_KSUB64,
+ NDS32_BUILTIN_UKSUB64,
+ NDS32_BUILTIN_SMAR64,
+ NDS32_BUILTIN_SMSR64,
+ NDS32_BUILTIN_UMAR64,
+ NDS32_BUILTIN_UMSR64,
+ NDS32_BUILTIN_KMAR64,
+ NDS32_BUILTIN_KMSR64,
+ NDS32_BUILTIN_UKMAR64,
+ NDS32_BUILTIN_UKMSR64,
+ NDS32_BUILTIN_SMALBB,
+ NDS32_BUILTIN_V_SMALBB,
+ NDS32_BUILTIN_SMALBT,
+ NDS32_BUILTIN_V_SMALBT,
+ NDS32_BUILTIN_SMALTT,
+ NDS32_BUILTIN_V_SMALTT,
+ NDS32_BUILTIN_SMALDA,
+ NDS32_BUILTIN_V_SMALDA,
+ NDS32_BUILTIN_SMALXDA,
+ NDS32_BUILTIN_V_SMALXDA,
+ NDS32_BUILTIN_SMALDS,
+ NDS32_BUILTIN_V_SMALDS,
+ NDS32_BUILTIN_SMALDRS,
+ NDS32_BUILTIN_V_SMALDRS,
+ NDS32_BUILTIN_SMALXDS,
+ NDS32_BUILTIN_V_SMALXDS,
+ NDS32_BUILTIN_SMUL16,
+ NDS32_BUILTIN_V_SMUL16,
+ NDS32_BUILTIN_SMULX16,
+ NDS32_BUILTIN_V_SMULX16,
+ NDS32_BUILTIN_UMUL16,
+ NDS32_BUILTIN_V_UMUL16,
+ NDS32_BUILTIN_UMULX16,
+ NDS32_BUILTIN_V_UMULX16,
+ NDS32_BUILTIN_SMSLDA,
+ NDS32_BUILTIN_V_SMSLDA,
+ NDS32_BUILTIN_SMSLXDA,
+ NDS32_BUILTIN_V_SMSLXDA,
+ NDS32_BUILTIN_UCLIP32,
+ NDS32_BUILTIN_SCLIP32,
+ NDS32_BUILTIN_KABS,
+ NDS32_BUILTIN_UALOAD_U16,
+ NDS32_BUILTIN_UALOAD_S16,
+ NDS32_BUILTIN_UALOAD_U8,
+ NDS32_BUILTIN_UALOAD_S8,
+ NDS32_BUILTIN_UASTORE_U16,
+ NDS32_BUILTIN_UASTORE_S16,
+ NDS32_BUILTIN_UASTORE_U8,
+ NDS32_BUILTIN_UASTORE_S8,
+ NDS32_BUILTIN_DSP_END,
NDS32_BUILTIN_UNALIGNED_FEATURE,
NDS32_BUILTIN_ENABLE_UNALIGNED,
NDS32_BUILTIN_DISABLE_UNALIGNED,
@@ -521,16 +857,30 @@
/* ------------------------------------------------------------------------ */
-#define TARGET_ISA_V2 (nds32_arch_option == ARCH_V2)
+#define TARGET_ISR_VECTOR_SIZE_4_BYTE \
+ (nds32_isr_vector_size == 4)
+#define TARGET_ISA_V2 (nds32_arch_option == ARCH_V2)
#define TARGET_ISA_V3 \
(nds32_arch_option == ARCH_V3 \
+ || nds32_arch_option == ARCH_V3J \
|| nds32_arch_option == ARCH_V3F \
|| nds32_arch_option == ARCH_V3S)
#define TARGET_ISA_V3M (nds32_arch_option == ARCH_V3M)
+#define TARGET_PIPELINE_N7 \
+ (nds32_cpu_option == CPU_N7)
+#define TARGET_PIPELINE_N8 \
+ (nds32_cpu_option == CPU_N6 \
+ || nds32_cpu_option == CPU_N8)
#define TARGET_PIPELINE_N9 \
(nds32_cpu_option == CPU_N9)
+#define TARGET_PIPELINE_N10 \
+ (nds32_cpu_option == CPU_N10)
+#define TARGET_PIPELINE_N13 \
+ (nds32_cpu_option == CPU_N12 || nds32_cpu_option == CPU_N13)
+#define TARGET_PIPELINE_GRAYWOLF \
+ (nds32_cpu_option == CPU_GRAYWOLF)
#define TARGET_PIPELINE_SIMPLE \
(nds32_cpu_option == CPU_SIMPLE)
@@ -541,6 +891,12 @@
#define TARGET_CMODEL_LARGE \
(nds32_cmodel_option == CMODEL_LARGE)
+#define TARGET_ICT_MODEL_SMALL \
+ (nds32_ict_model == ICT_MODEL_SMALL)
+
+#define TARGET_ICT_MODEL_LARGE \
+ (nds32_ict_model == ICT_MODEL_LARGE)
+
/* When -mcmodel=small or -mcmodel=medium,
compiler may generate gp-base instruction directly. */
#define TARGET_GP_DIRECT \
@@ -576,6 +932,21 @@
#endif
#define TARGET_CONFIG_FPU_DEFAULT NDS32_CONFIG_FPU_2
+
+/* ------------------------------------------------------------------------ */
+
+#ifdef TARGET_DEFAULT_RELAX
+# define NDS32_RELAX_SPEC " %{!mno-relax:--relax}"
+#else
+# define NDS32_RELAX_SPEC " %{mrelax:--relax}"
+#endif
+
+#ifdef TARGET_DEFAULT_EXT_DSP
+# define NDS32_EXT_DSP_SPEC " %{!mno-ext-dsp:-mext-dsp}"
+#else
+# define NDS32_EXT_DSP_SPEC ""
+#endif
+
/* ------------------------------------------------------------------------ */
/* Controlling the Compilation Driver. */
@@ -591,11 +962,15 @@
{"float", "%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}" }
#define CC1_SPEC \
- ""
+ NDS32_EXT_DSP_SPEC
#define ASM_SPEC \
" %{mbig-endian:-EB} %{mlittle-endian:-EL}" \
" %{march=*:-march=%*}" \
+ " %{mno-16-bit|mno-16bit:-mno-16bit-ext}" \
+ " %{march=v3m:%{!mfull-regs:%{!mreduced-regs:-mreduced-regs}}}" \
+ " %{mfull-regs:-mno-reduced-regs}" \
+ " %{mreduced-regs:-mreduced-regs}" \
" %{mabi=*:-mabi=v%*}" \
" %{mconfig-fpu=*:-mfpu-freg=%*}" \
" %{mext-fpu-mac:-mmac}" \
@@ -603,35 +978,9 @@
" %{mext-fpu-sp:-mfpu-sp-ext}" \
" %{mno-ext-fpu-sp:-mno-fpu-sp-ext}" \
" %{mext-fpu-dp:-mfpu-dp-ext}" \
- " %{mno-ext-fpu-sp:-mno-fpu-dp-ext}"
-
-/* If user issues -mrelax, we need to pass '--relax' to linker. */
-#define LINK_SPEC \
- " %{mbig-endian:-EB} %{mlittle-endian:-EL}" \
- " %{mrelax:--relax}"
-
-#define LIB_SPEC \
- " -lc -lgloss"
-
-/* The option -mno-ctor-dtor can disable constructor/destructor feature
- by applying different crt stuff. In the convention, crt0.o is the
- startup file without constructor/destructor;
- crt1.o, crti.o, crtbegin.o, crtend.o, and crtn.o are the
- startup files with constructor/destructor.
- Note that crt0.o, crt1.o, crti.o, and crtn.o are provided
- by newlib/mculib/glibc/ublic, while crtbegin.o and crtend.o are
- currently provided by GCC for nds32 target.
-
- For nds32 target so far:
- If -mno-ctor-dtor, we are going to link
- "crt0.o [user objects]".
- If general cases, we are going to link
- "crt1.o crtbegin1.o [user objects] crtend1.o". */
-#define STARTFILE_SPEC \
- " %{!mno-ctor-dtor:crt1.o%s;:crt0.o%s}" \
- " %{!mno-ctor-dtor:crtbegin1.o%s}"
-#define ENDFILE_SPEC \
- " %{!mno-ctor-dtor:crtend1.o%s}"
+ " %{mno-ext-fpu-sp:-mno-fpu-dp-ext}" \
+ " %{mext-dsp:-mdsp-ext}" \
+ " %{O|O1|O2|O3|Ofast:-O1;:-Os}"
/* The TARGET_BIG_ENDIAN_DEFAULT is defined if we
configure gcc with --target=nds32be-* setting.
@@ -642,9 +991,11 @@
# define NDS32_ENDIAN_DEFAULT "mlittle-endian"
#endif
-/* Currently we only have elf toolchain,
- where -mcmodel=medium is always the default. */
-#define NDS32_CMODEL_DEFAULT "mcmodel=medium"
+#if TARGET_ELF
+# define NDS32_CMODEL_DEFAULT "mcmodel=medium"
+#else
+# define NDS32_CMODEL_DEFAULT "mcmodel=large"
+#endif
#define MULTILIB_DEFAULTS \
{ NDS32_ENDIAN_DEFAULT, NDS32_CMODEL_DEFAULT }
@@ -1139,6 +1490,11 @@
#define PIC_OFFSET_TABLE_REGNUM GP_REGNUM
+#define SYMBOLIC_CONST_P(X) \
+(GET_CODE (X) == SYMBOL_REF \
+ || GET_CODE (X) == LABEL_REF \
+ || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
+
/* Defining the Output Assembler Language. */
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32_init.inc gcc-8.2.0/gcc/config/nds32/nds32_init.inc
--- gcc-8.2.0.orig/gcc/config/nds32/nds32_init.inc 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32_init.inc 2019-01-25 15:38:32.833242671 +0100
@@ -0,0 +1,43 @@
+/*
+ * nds32_init.inc
+ *
+ * NDS32 architecture startup assembler header file
+ *
+ */
+
+.macro nds32_init
+
+ ! Initialize GP for data access
+ la $gp, _SDA_BASE_
+
+#if defined(__NDS32_EXT_EX9__)
+ ! Check HW for EX9
+ mfsr $r0, $MSC_CFG
+ li $r1, (1 << 24)
+ and $r2, $r0, $r1
+ beqz $r2, 1f
+
+ ! Initialize the table base of EX9 instruction
+ la $r0, _ITB_BASE_
+ mtusr $r0, $ITB
+1:
+#endif
+
+#if defined(__NDS32_EXT_FPU_DP__) || defined(__NDS32_EXT_FPU_SP__)
+ ! Enable FPU
+ mfsr $r0, $FUCOP_CTL
+ ori $r0, $r0, #0x1
+ mtsr $r0, $FUCOP_CTL
+ dsb
+
+ ! Enable denormalized flush-to-Zero mode
+ fmfcsr $r0
+ ori $r0,$r0,#0x1000
+ fmtcsr $r0
+ dsb
+#endif
+
+ ! Initialize default stack pointer
+ la $sp, _stack
+
+.endm
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-intrinsic.c gcc-8.2.0/gcc/config/nds32/nds32-intrinsic.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-intrinsic.c 2018-04-22 09:46:39.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-intrinsic.c 2019-01-25 15:38:32.825242648 +0100
@@ -519,6 +519,7 @@
{
NDS32_BUILTIN(unspec_fmfcfg, "fmfcfg", FMFCFG)
NDS32_BUILTIN(unspec_fmfcsr, "fmfcsr", FMFCSR)
+ NDS32_BUILTIN(unspec_volatile_rdov, "rdov", RDOV)
NDS32_BUILTIN(unspec_get_current_sp, "get_current_sp", GET_CURRENT_SP)
NDS32_BUILTIN(unspec_return_address, "return_address", RETURN_ADDRESS)
NDS32_BUILTIN(unspec_get_all_pending_int, "get_all_pending_int",
@@ -558,6 +559,31 @@
NDS32_NO_TARGET_BUILTIN(unspec_ret_itoff, "ret_itoff", RET_ITOFF)
NDS32_NO_TARGET_BUILTIN(unspec_set_current_sp,
"set_current_sp", SET_CURRENT_SP)
+ NDS32_BUILTIN(kabsv2hi2, "kabs16", KABS16)
+ NDS32_BUILTIN(kabsv2hi2, "v_kabs16", V_KABS16)
+ NDS32_BUILTIN(kabsv4qi2, "kabs8", KABS8)
+ NDS32_BUILTIN(kabsv4qi2, "v_kabs8", V_KABS8)
+ NDS32_BUILTIN(sunpkd810, "sunpkd810", SUNPKD810)
+ NDS32_BUILTIN(sunpkd810, "v_sunpkd810", V_SUNPKD810)
+ NDS32_BUILTIN(sunpkd820, "sunpkd820", SUNPKD820)
+ NDS32_BUILTIN(sunpkd820, "v_sunpkd820", V_SUNPKD820)
+ NDS32_BUILTIN(sunpkd830, "sunpkd830", SUNPKD830)
+ NDS32_BUILTIN(sunpkd830, "v_sunpkd830", V_SUNPKD830)
+ NDS32_BUILTIN(sunpkd831, "sunpkd831", SUNPKD831)
+ NDS32_BUILTIN(sunpkd831, "v_sunpkd831", V_SUNPKD831)
+ NDS32_BUILTIN(zunpkd810, "zunpkd810", ZUNPKD810)
+ NDS32_BUILTIN(zunpkd810, "v_zunpkd810", V_ZUNPKD810)
+ NDS32_BUILTIN(zunpkd820, "zunpkd820", ZUNPKD820)
+ NDS32_BUILTIN(zunpkd820, "v_zunpkd820", V_ZUNPKD820)
+ NDS32_BUILTIN(zunpkd830, "zunpkd830", ZUNPKD830)
+ NDS32_BUILTIN(zunpkd830, "v_zunpkd830", V_ZUNPKD830)
+ NDS32_BUILTIN(zunpkd831, "zunpkd831", ZUNPKD831)
+ NDS32_BUILTIN(zunpkd831, "v_zunpkd831", V_ZUNPKD831)
+ NDS32_BUILTIN(unspec_kabs, "kabs", KABS)
+ NDS32_BUILTIN(unaligned_loadv2hi, "get_unaligned_u16x2", UALOAD_U16)
+ NDS32_BUILTIN(unaligned_loadv2hi, "get_unaligned_s16x2", UALOAD_S16)
+ NDS32_BUILTIN(unaligned_loadv4qi, "get_unaligned_u8x4", UALOAD_U8)
+ NDS32_BUILTIN(unaligned_loadv4qi, "get_unaligned_s8x4", UALOAD_S8)
};
/* Intrinsics that take just one argument. and the argument is immediate. */
@@ -593,6 +619,28 @@
NDS32_BUILTIN(unspec_ffb, "ffb", FFB)
NDS32_BUILTIN(unspec_ffmism, "ffmsim", FFMISM)
NDS32_BUILTIN(unspec_flmism, "flmism", FLMISM)
+ NDS32_BUILTIN(unspec_kaddw, "kaddw", KADDW)
+ NDS32_BUILTIN(unspec_kaddh, "kaddh", KADDH)
+ NDS32_BUILTIN(unspec_ksubw, "ksubw", KSUBW)
+ NDS32_BUILTIN(unspec_ksubh, "ksubh", KSUBH)
+ NDS32_BUILTIN(unspec_kdmbb, "kdmbb", KDMBB)
+ NDS32_BUILTIN(unspec_kdmbb, "v_kdmbb", V_KDMBB)
+ NDS32_BUILTIN(unspec_kdmbt, "kdmbt", KDMBT)
+ NDS32_BUILTIN(unspec_kdmbt, "v_kdmbt", V_KDMBT)
+ NDS32_BUILTIN(unspec_kdmtb, "kdmtb", KDMTB)
+ NDS32_BUILTIN(unspec_kdmtb, "v_kdmtb", V_KDMTB)
+ NDS32_BUILTIN(unspec_kdmtt, "kdmtt", KDMTT)
+ NDS32_BUILTIN(unspec_kdmtt, "v_kdmtt", V_KDMTT)
+ NDS32_BUILTIN(unspec_khmbb, "khmbb", KHMBB)
+ NDS32_BUILTIN(unspec_khmbb, "v_khmbb", V_KHMBB)
+ NDS32_BUILTIN(unspec_khmbt, "khmbt", KHMBT)
+ NDS32_BUILTIN(unspec_khmbt, "v_khmbt", V_KHMBT)
+ NDS32_BUILTIN(unspec_khmtb, "khmtb", KHMTB)
+ NDS32_BUILTIN(unspec_khmtb, "v_khmtb", V_KHMTB)
+ NDS32_BUILTIN(unspec_khmtt, "khmtt", KHMTT)
+ NDS32_BUILTIN(unspec_khmtt, "v_khmtt", V_KHMTT)
+ NDS32_BUILTIN(unspec_kslraw, "kslraw", KSLRAW)
+ NDS32_BUILTIN(unspec_kslrawu, "kslraw_u", KSLRAW_U)
NDS32_BUILTIN(rotrsi3, "rotr", ROTR)
NDS32_BUILTIN(unspec_sva, "sva", SVA)
NDS32_BUILTIN(unspec_svs, "svs", SVS)
@@ -603,7 +651,202 @@
NDS32_NO_TARGET_BUILTIN(unaligned_store_hw, "unaligned_store_hw", UASTORE_HW)
NDS32_NO_TARGET_BUILTIN(unaligned_storesi, "unaligned_store_hw", UASTORE_W)
NDS32_NO_TARGET_BUILTIN(unaligned_storedi, "unaligned_store_hw", UASTORE_DW)
-
+ NDS32_BUILTIN(addv2hi3, "add16", ADD16)
+ NDS32_BUILTIN(addv2hi3, "v_uadd16", V_UADD16)
+ NDS32_BUILTIN(addv2hi3, "v_sadd16", V_SADD16)
+ NDS32_BUILTIN(raddv2hi3, "radd16", RADD16)
+ NDS32_BUILTIN(raddv2hi3, "v_radd16", V_RADD16)
+ NDS32_BUILTIN(uraddv2hi3, "uradd16", URADD16)
+ NDS32_BUILTIN(uraddv2hi3, "v_uradd16", V_URADD16)
+ NDS32_BUILTIN(kaddv2hi3, "kadd16", KADD16)
+ NDS32_BUILTIN(kaddv2hi3, "v_kadd16", V_KADD16)
+ NDS32_BUILTIN(ukaddv2hi3, "ukadd16", UKADD16)
+ NDS32_BUILTIN(ukaddv2hi3, "v_ukadd16", V_UKADD16)
+ NDS32_BUILTIN(subv2hi3, "sub16", SUB16)
+ NDS32_BUILTIN(subv2hi3, "v_usub16", V_USUB16)
+ NDS32_BUILTIN(subv2hi3, "v_ssub16", V_SSUB16)
+ NDS32_BUILTIN(rsubv2hi3, "rsub16", RSUB16)
+ NDS32_BUILTIN(rsubv2hi3, "v_rsub16", V_RSUB16)
+ NDS32_BUILTIN(ursubv2hi3, "ursub16", URSUB16)
+ NDS32_BUILTIN(ursubv2hi3, "v_ursub16", V_URSUB16)
+ NDS32_BUILTIN(ksubv2hi3, "ksub16", KSUB16)
+ NDS32_BUILTIN(ksubv2hi3, "v_ksub16", V_KSUB16)
+ NDS32_BUILTIN(uksubv2hi3, "uksub16", UKSUB16)
+ NDS32_BUILTIN(uksubv2hi3, "v_uksub16", V_UKSUB16)
+ NDS32_BUILTIN(cras16_1, "cras16", CRAS16)
+ NDS32_BUILTIN(cras16_1, "v_ucras16", V_UCRAS16)
+ NDS32_BUILTIN(cras16_1, "v_scras16", V_SCRAS16)
+ NDS32_BUILTIN(rcras16_1, "rcras16", RCRAS16)
+ NDS32_BUILTIN(rcras16_1, "v_rcras16", V_RCRAS16)
+ NDS32_BUILTIN(urcras16_1, "urcras16", URCRAS16)
+ NDS32_BUILTIN(urcras16_1, "v_urcras16", V_URCRAS16)
+ NDS32_BUILTIN(kcras16_1, "kcras16", KCRAS16)
+ NDS32_BUILTIN(kcras16_1, "v_kcras16", V_KCRAS16)
+ NDS32_BUILTIN(ukcras16_1, "ukcras16", UKCRAS16)
+ NDS32_BUILTIN(ukcras16_1, "v_ukcras16", V_UKCRAS16)
+ NDS32_BUILTIN(crsa16_1, "crsa16", CRSA16)
+ NDS32_BUILTIN(crsa16_1, "v_ucrsa16", V_UCRSA16)
+ NDS32_BUILTIN(crsa16_1, "v_scrsa16", V_SCRSA16)
+ NDS32_BUILTIN(rcrsa16_1, "rcrsa16", RCRSA16)
+ NDS32_BUILTIN(rcrsa16_1, "v_rcrsa16", V_RCRSA16)
+ NDS32_BUILTIN(urcrsa16_1, "urcrsa16", URCRSA16)
+ NDS32_BUILTIN(urcrsa16_1, "v_urcrsa16", V_URCRSA16)
+ NDS32_BUILTIN(kcrsa16_1, "kcrsa16", KCRSA16)
+ NDS32_BUILTIN(kcrsa16_1, "v_kcrsa16", V_KCRSA16)
+ NDS32_BUILTIN(ukcrsa16_1, "ukcrsa16", UKCRSA16)
+ NDS32_BUILTIN(ukcrsa16_1, "v_ukcrsa16", V_UKCRSA16)
+ NDS32_BUILTIN(addv4qi3, "add8", ADD8)
+ NDS32_BUILTIN(addv4qi3, "v_uadd8", V_UADD8)
+ NDS32_BUILTIN(addv4qi3, "v_sadd8", V_SADD8)
+ NDS32_BUILTIN(raddv4qi3, "radd8", RADD8)
+ NDS32_BUILTIN(raddv4qi3, "v_radd8", V_RADD8)
+ NDS32_BUILTIN(uraddv4qi3, "uradd8", URADD8)
+ NDS32_BUILTIN(uraddv4qi3, "v_uradd8", V_URADD8)
+ NDS32_BUILTIN(kaddv4qi3, "kadd8", KADD8)
+ NDS32_BUILTIN(kaddv4qi3, "v_kadd8", V_KADD8)
+ NDS32_BUILTIN(ukaddv4qi3, "ukadd8", UKADD8)
+ NDS32_BUILTIN(ukaddv4qi3, "v_ukadd8", V_UKADD8)
+ NDS32_BUILTIN(subv4qi3, "sub8", SUB8)
+ NDS32_BUILTIN(subv4qi3, "v_usub8", V_USUB8)
+ NDS32_BUILTIN(subv4qi3, "v_ssub8", V_SSUB8)
+ NDS32_BUILTIN(rsubv4qi3, "rsub8", RSUB8)
+ NDS32_BUILTIN(rsubv4qi3, "v_rsub8", V_RSUB8)
+ NDS32_BUILTIN(ursubv4qi3, "ursub8", URSUB8)
+ NDS32_BUILTIN(ursubv4qi3, "v_ursub8", V_URSUB8)
+ NDS32_BUILTIN(ksubv4qi3, "ksub8", KSUB8)
+ NDS32_BUILTIN(ksubv4qi3, "v_ksub8", V_KSUB8)
+ NDS32_BUILTIN(uksubv4qi3, "uksub8", UKSUB8)
+ NDS32_BUILTIN(uksubv4qi3, "v_uksub8", V_UKSUB8)
+ NDS32_BUILTIN(ashrv2hi3, "sra16", SRA16)
+ NDS32_BUILTIN(ashrv2hi3, "v_sra16", V_SRA16)
+ NDS32_BUILTIN(sra16_round, "sra16_u", SRA16_U)
+ NDS32_BUILTIN(sra16_round, "v_sra16_u", V_SRA16_U)
+ NDS32_BUILTIN(lshrv2hi3, "srl16", SRL16)
+ NDS32_BUILTIN(lshrv2hi3, "v_srl16", V_SRL16)
+ NDS32_BUILTIN(srl16_round, "srl16_u", SRL16_U)
+ NDS32_BUILTIN(srl16_round, "v_srl16_u", V_SRL16_U)
+ NDS32_BUILTIN(ashlv2hi3, "sll16", SLL16)
+ NDS32_BUILTIN(ashlv2hi3, "v_sll16", V_SLL16)
+ NDS32_BUILTIN(kslli16, "ksll16", KSLL16)
+ NDS32_BUILTIN(kslli16, "v_ksll16", V_KSLL16)
+ NDS32_BUILTIN(kslra16, "kslra16", KSLRA16)
+ NDS32_BUILTIN(kslra16, "v_kslra16", V_KSLRA16)
+ NDS32_BUILTIN(kslra16_round, "kslra16_u", KSLRA16_U)
+ NDS32_BUILTIN(kslra16_round, "v_kslra16_u", V_KSLRA16_U)
+ NDS32_BUILTIN(cmpeq16, "cmpeq16", CMPEQ16)
+ NDS32_BUILTIN(cmpeq16, "v_scmpeq16", V_SCMPEQ16)
+ NDS32_BUILTIN(cmpeq16, "v_ucmpeq16", V_UCMPEQ16)
+ NDS32_BUILTIN(scmplt16, "scmplt16", SCMPLT16)
+ NDS32_BUILTIN(scmplt16, "v_scmplt16", V_SCMPLT16)
+ NDS32_BUILTIN(scmple16, "scmple16", SCMPLE16)
+ NDS32_BUILTIN(scmple16, "v_scmple16", V_SCMPLE16)
+ NDS32_BUILTIN(ucmplt16, "ucmplt16", UCMPLT16)
+ NDS32_BUILTIN(ucmplt16, "v_ucmplt16", V_UCMPLT16)
+ NDS32_BUILTIN(ucmplt16, "ucmple16", UCMPLE16)
+ NDS32_BUILTIN(ucmplt16, "v_ucmple16", V_UCMPLE16)
+ NDS32_BUILTIN(cmpeq8, "cmpeq8", CMPEQ8)
+ NDS32_BUILTIN(cmpeq8, "v_scmpeq8", V_SCMPEQ8)
+ NDS32_BUILTIN(cmpeq8, "v_ucmpeq8", V_UCMPEQ8)
+ NDS32_BUILTIN(scmplt8, "scmplt8", SCMPLT8)
+ NDS32_BUILTIN(scmplt8, "v_scmplt8", V_SCMPLT8)
+ NDS32_BUILTIN(scmple8, "scmple8", SCMPLE8)
+ NDS32_BUILTIN(scmple8, "v_scmple8", V_SCMPLE8)
+ NDS32_BUILTIN(ucmplt8, "ucmplt8", UCMPLT8)
+ NDS32_BUILTIN(ucmplt8, "v_ucmplt8", V_UCMPLT8)
+ NDS32_BUILTIN(ucmplt8, "ucmple8", UCMPLE8)
+ NDS32_BUILTIN(ucmplt8, "v_ucmple8", V_UCMPLE8)
+ NDS32_BUILTIN(sminv2hi3, "smin16", SMIN16)
+ NDS32_BUILTIN(sminv2hi3, "v_smin16", V_SMIN16)
+ NDS32_BUILTIN(uminv2hi3, "umin16", UMIN16)
+ NDS32_BUILTIN(uminv2hi3, "v_umin16", V_UMIN16)
+ NDS32_BUILTIN(smaxv2hi3, "smax16", SMAX16)
+ NDS32_BUILTIN(smaxv2hi3, "v_smax16", V_SMAX16)
+ NDS32_BUILTIN(umaxv2hi3, "umax16", UMAX16)
+ NDS32_BUILTIN(umaxv2hi3, "v_umax16", V_UMAX16)
+ NDS32_BUILTIN(khm16, "khm16", KHM16)
+ NDS32_BUILTIN(khm16, "v_khm16", V_KHM16)
+ NDS32_BUILTIN(khmx16, "khmx16", KHMX16)
+ NDS32_BUILTIN(khmx16, "v_khmx16", V_KHMX16)
+ NDS32_BUILTIN(sminv4qi3, "smin8", SMIN8)
+ NDS32_BUILTIN(sminv4qi3, "v_smin8", V_SMIN8)
+ NDS32_BUILTIN(uminv4qi3, "umin8", UMIN8)
+ NDS32_BUILTIN(uminv4qi3, "v_umin8", V_UMIN8)
+ NDS32_BUILTIN(smaxv4qi3, "smax8", SMAX8)
+ NDS32_BUILTIN(smaxv4qi3, "v_smax8", V_SMAX8)
+ NDS32_BUILTIN(umaxv4qi3, "umax8", UMAX8)
+ NDS32_BUILTIN(umaxv4qi3, "v_umax8", V_UMAX8)
+ NDS32_BUILTIN(raddsi3, "raddw", RADDW)
+ NDS32_BUILTIN(uraddsi3, "uraddw", URADDW)
+ NDS32_BUILTIN(rsubsi3, "rsubw", RSUBW)
+ NDS32_BUILTIN(ursubsi3, "ursubw", URSUBW)
+ NDS32_BUILTIN(sraiu, "sra_u", SRA_U)
+ NDS32_BUILTIN(kssl, "ksll", KSLL)
+ NDS32_BUILTIN(pkbb, "pkbb16", PKBB16)
+ NDS32_BUILTIN(pkbb, "v_pkbb16", V_PKBB16)
+ NDS32_BUILTIN(pkbt, "pkbt16", PKBT16)
+ NDS32_BUILTIN(pkbt, "v_pkbt16", V_PKBT16)
+ NDS32_BUILTIN(pktb, "pktb16", PKTB16)
+ NDS32_BUILTIN(pktb, "v_pktb16", V_PKTB16)
+ NDS32_BUILTIN(pktt, "pktt16", PKTT16)
+ NDS32_BUILTIN(pktt, "v_pktt16", V_PKTT16)
+ NDS32_BUILTIN(smulsi3_highpart, "smmul", SMMUL)
+ NDS32_BUILTIN(smmul_round, "smmul_u", SMMUL_U)
+ NDS32_BUILTIN(smmwb, "smmwb", SMMWB)
+ NDS32_BUILTIN(smmwb, "v_smmwb", V_SMMWB)
+ NDS32_BUILTIN(smmwb_round, "smmwb_u", SMMWB_U)
+ NDS32_BUILTIN(smmwb_round, "v_smmwb_u", V_SMMWB_U)
+ NDS32_BUILTIN(smmwt, "smmwt", SMMWT)
+ NDS32_BUILTIN(smmwt, "v_smmwt", V_SMMWT)
+ NDS32_BUILTIN(smmwt_round, "smmwt_u", SMMWT_U)
+ NDS32_BUILTIN(smmwt_round, "v_smmwt_u", V_SMMWT_U)
+ NDS32_BUILTIN(smbb, "smbb", SMBB)
+ NDS32_BUILTIN(smbb, "v_smbb", V_SMBB)
+ NDS32_BUILTIN(smbt, "smbt", SMBT)
+ NDS32_BUILTIN(smbt, "v_smbt", V_SMBT)
+ NDS32_BUILTIN(smtt, "smtt", SMTT)
+ NDS32_BUILTIN(smtt, "v_smtt", V_SMTT)
+ NDS32_BUILTIN(kmda, "kmda", KMDA)
+ NDS32_BUILTIN(kmda, "v_kmda", V_KMDA)
+ NDS32_BUILTIN(kmxda, "kmxda", KMXDA)
+ NDS32_BUILTIN(kmxda, "v_kmxda", V_KMXDA)
+ NDS32_BUILTIN(smds, "smds", SMDS)
+ NDS32_BUILTIN(smds, "v_smds", V_SMDS)
+ NDS32_BUILTIN(smdrs, "smdrs", SMDRS)
+ NDS32_BUILTIN(smdrs, "v_smdrs", V_SMDRS)
+ NDS32_BUILTIN(smxdsv, "smxds", SMXDS)
+ NDS32_BUILTIN(smxdsv, "v_smxds", V_SMXDS)
+ NDS32_BUILTIN(smal1, "smal", SMAL)
+ NDS32_BUILTIN(smal1, "v_smal", V_SMAL)
+ NDS32_BUILTIN(bitrev, "bitrev", BITREV)
+ NDS32_BUILTIN(wext, "wext", WEXT)
+ NDS32_BUILTIN(adddi3, "sadd64", SADD64)
+ NDS32_BUILTIN(adddi3, "uadd64", UADD64)
+ NDS32_BUILTIN(radddi3, "radd64", RADD64)
+ NDS32_BUILTIN(uradddi3, "uradd64", URADD64)
+ NDS32_BUILTIN(kadddi3, "kadd64", KADD64)
+ NDS32_BUILTIN(ukadddi3, "ukadd64", UKADD64)
+ NDS32_BUILTIN(subdi3, "ssub64", SSUB64)
+ NDS32_BUILTIN(subdi3, "usub64", USUB64)
+ NDS32_BUILTIN(rsubdi3, "rsub64", RSUB64)
+ NDS32_BUILTIN(ursubdi3, "ursub64", URSUB64)
+ NDS32_BUILTIN(ksubdi3, "ksub64", KSUB64)
+ NDS32_BUILTIN(uksubdi3, "uksub64", UKSUB64)
+ NDS32_BUILTIN(smul16, "smul16", SMUL16)
+ NDS32_BUILTIN(smul16, "v_smul16", V_SMUL16)
+ NDS32_BUILTIN(smulx16, "smulx16", SMULX16)
+ NDS32_BUILTIN(smulx16, "v_smulx16", V_SMULX16)
+ NDS32_BUILTIN(umul16, "umul16", UMUL16)
+ NDS32_BUILTIN(umul16, "v_umul16", V_UMUL16)
+ NDS32_BUILTIN(umulx16, "umulx16", UMULX16)
+ NDS32_BUILTIN(umulx16, "v_umulx16", V_UMULX16)
+ NDS32_BUILTIN(kwmmul, "kwmmul", KWMMUL)
+ NDS32_BUILTIN(kwmmul_round, "kwmmul_u", KWMMUL_U)
+ NDS32_NO_TARGET_BUILTIN(unaligned_storev2hi,
+ "put_unaligned_u16x2", UASTORE_U16)
+ NDS32_NO_TARGET_BUILTIN(unaligned_storev2hi,
+ "put_unaligned_s16x2", UASTORE_S16)
+ NDS32_NO_TARGET_BUILTIN(unaligned_storev4qi, "put_unaligned_u8x4", UASTORE_U8)
+ NDS32_NO_TARGET_BUILTIN(unaligned_storev4qi, "put_unaligned_s8x4", UASTORE_S8)
};
/* Two-argument intrinsics with an immediate second argument. */
@@ -617,6 +860,22 @@
NDS32_BUILTIN(unspec_clips, "clips", CLIPS)
NDS32_NO_TARGET_BUILTIN(unspec_teqz, "teqz", TEQZ)
NDS32_NO_TARGET_BUILTIN(unspec_tnez, "tnez", TNEZ)
+ NDS32_BUILTIN(ashrv2hi3, "srl16", SRL16)
+ NDS32_BUILTIN(ashrv2hi3, "v_srl16", V_SRL16)
+ NDS32_BUILTIN(srl16_round, "srl16_u", SRL16_U)
+ NDS32_BUILTIN(srl16_round, "v_srl16_u", V_SRL16_U)
+ NDS32_BUILTIN(kslli16, "ksll16", KSLL16)
+ NDS32_BUILTIN(kslli16, "v_ksll16", V_KSLL16)
+ NDS32_BUILTIN(sclip16, "sclip16", SCLIP16)
+ NDS32_BUILTIN(sclip16, "v_sclip16", V_SCLIP16)
+ NDS32_BUILTIN(uclip16, "uclip16", UCLIP16)
+ NDS32_BUILTIN(uclip16, "v_uclip16", V_UCLIP16)
+ NDS32_BUILTIN(sraiu, "sra_u", SRA_U)
+ NDS32_BUILTIN(kssl, "ksll", KSLL)
+ NDS32_BUILTIN(bitrev, "bitrev", BITREV)
+ NDS32_BUILTIN(wext, "wext", WEXT)
+ NDS32_BUILTIN(uclip32, "uclip32", UCLIP32)
+ NDS32_BUILTIN(sclip32, "sclip32", SCLIP32)
};
/* Intrinsics that take three arguments. */
@@ -625,6 +884,67 @@
NDS32_BUILTIN(unspec_pbsada, "pbsada", PBSADA)
NDS32_NO_TARGET_BUILTIN(bse, "bse", BSE)
NDS32_NO_TARGET_BUILTIN(bsp, "bsp", BSP)
+ NDS32_BUILTIN(kmabb, "kmabb", KMABB)
+ NDS32_BUILTIN(kmabb, "v_kmabb", V_KMABB)
+ NDS32_BUILTIN(kmabt, "kmabt", KMABT)
+ NDS32_BUILTIN(kmabt, "v_kmabt", V_KMABT)
+ NDS32_BUILTIN(kmatt, "kmatt", KMATT)
+ NDS32_BUILTIN(kmatt, "v_kmatt", V_KMATT)
+ NDS32_BUILTIN(kmada, "kmada", KMADA)
+ NDS32_BUILTIN(kmada, "v_kmada", V_KMADA)
+ NDS32_BUILTIN(kmaxda, "kmaxda", KMAXDA)
+ NDS32_BUILTIN(kmaxda, "v_kmaxda", V_KMAXDA)
+ NDS32_BUILTIN(kmads, "kmads", KMADS)
+ NDS32_BUILTIN(kmads, "v_kmads", V_KMADS)
+ NDS32_BUILTIN(kmadrs, "kmadrs", KMADRS)
+ NDS32_BUILTIN(kmadrs, "v_kmadrs", V_KMADRS)
+ NDS32_BUILTIN(kmaxds, "kmaxds", KMAXDS)
+ NDS32_BUILTIN(kmaxds, "v_kmaxds", V_KMAXDS)
+ NDS32_BUILTIN(kmsda, "kmsda", KMSDA)
+ NDS32_BUILTIN(kmsda, "v_kmsda", V_KMSDA)
+ NDS32_BUILTIN(kmsxda, "kmsxda", KMSXDA)
+ NDS32_BUILTIN(kmsxda, "v_kmsxda", V_KMSXDA)
+ NDS32_BUILTIN(bpick1, "bpick", BPICK)
+ NDS32_BUILTIN(smar64_1, "smar64", SMAR64)
+ NDS32_BUILTIN(smsr64, "smsr64", SMSR64)
+ NDS32_BUILTIN(umar64_1, "umar64", UMAR64)
+ NDS32_BUILTIN(umsr64, "umsr64", UMSR64)
+ NDS32_BUILTIN(kmar64_1, "kmar64", KMAR64)
+ NDS32_BUILTIN(kmsr64, "kmsr64", KMSR64)
+ NDS32_BUILTIN(ukmar64_1, "ukmar64", UKMAR64)
+ NDS32_BUILTIN(ukmsr64, "ukmsr64", UKMSR64)
+ NDS32_BUILTIN(smalbb, "smalbb", SMALBB)
+ NDS32_BUILTIN(smalbb, "v_smalbb", V_SMALBB)
+ NDS32_BUILTIN(smalbt, "smalbt", SMALBT)
+ NDS32_BUILTIN(smalbt, "v_smalbt", V_SMALBT)
+ NDS32_BUILTIN(smaltt, "smaltt", SMALTT)
+ NDS32_BUILTIN(smaltt, "v_smaltt", V_SMALTT)
+ NDS32_BUILTIN(smalda1, "smalda", SMALDA)
+ NDS32_BUILTIN(smalda1, "v_smalda", V_SMALDA)
+ NDS32_BUILTIN(smalxda1, "smalxda", SMALXDA)
+ NDS32_BUILTIN(smalxda1, "v_smalxda", V_SMALXDA)
+ NDS32_BUILTIN(smalds1, "smalds", SMALDS)
+ NDS32_BUILTIN(smalds1, "v_smalds", V_SMALDS)
+ NDS32_BUILTIN(smaldrs3, "smaldrs", SMALDRS)
+ NDS32_BUILTIN(smaldrs3, "v_smaldrs", V_SMALDRS)
+ NDS32_BUILTIN(smalxds1, "smalxds", SMALXDS)
+ NDS32_BUILTIN(smalxds1, "v_smalxds", V_SMALXDS)
+ NDS32_BUILTIN(smslda1, "smslda", SMSLDA)
+ NDS32_BUILTIN(smslda1, "v_smslda", V_SMSLDA)
+ NDS32_BUILTIN(smslxda1, "smslxda", SMSLXDA)
+ NDS32_BUILTIN(smslxda1, "v_smslxda", V_SMSLXDA)
+ NDS32_BUILTIN(kmmawb, "kmmawb", KMMAWB)
+ NDS32_BUILTIN(kmmawb, "v_kmmawb", V_KMMAWB)
+ NDS32_BUILTIN(kmmawb_round, "kmmawb_u", KMMAWB_U)
+ NDS32_BUILTIN(kmmawb_round, "v_kmmawb_u", V_KMMAWB_U)
+ NDS32_BUILTIN(kmmawt, "kmmawt", KMMAWT)
+ NDS32_BUILTIN(kmmawt, "v_kmmawt", V_KMMAWT)
+ NDS32_BUILTIN(kmmawt_round, "kmmawt_u", KMMAWT_U)
+ NDS32_BUILTIN(kmmawt_round, "v_kmmawt_u", V_KMMAWT_U)
+ NDS32_BUILTIN(kmmac, "kmmac", KMMAC)
+ NDS32_BUILTIN(kmmac_round, "kmmac_u", KMMAC_U)
+ NDS32_BUILTIN(kmmsb, "kmmsb", KMMSB)
+ NDS32_BUILTIN(kmmsb_round, "kmmsb_u", KMMSB_U)
};
/* Three-argument intrinsics with an immediate third argument. */
@@ -634,6 +954,7 @@
NDS32_NO_TARGET_BUILTIN(prefetch_hw, "prefetch_hw", DPREF_HW)
NDS32_NO_TARGET_BUILTIN(prefetch_w, "prefetch_w", DPREF_W)
NDS32_NO_TARGET_BUILTIN(prefetch_dw, "prefetch_dw", DPREF_DW)
+ NDS32_BUILTIN(insb, "insb", INSB)
};
/* Intrinsics that load a value. */
@@ -676,6 +997,11 @@
unsigned i;
struct builtin_description *d;
+ if (!NDS32_EXT_DSP_P ()
+ && fcode > NDS32_BUILTIN_DSP_BEGIN
+ && fcode < NDS32_BUILTIN_DSP_END)
+ error ("don't support DSP extension instructions");
+
switch (fcode)
{
/* FPU Register Transfer. */
@@ -812,6 +1138,9 @@
case NDS32_BUILTIN_CCTL_L1D_WBALL_ONE_LVL:
emit_insn (gen_cctl_l1d_wball_one_lvl());
return target;
+ case NDS32_BUILTIN_CLROV:
+ emit_insn (gen_unspec_volatile_clrov ());
+ return target;
case NDS32_BUILTIN_STANDBY_NO_WAKE_GRANT:
emit_insn (gen_unspec_standby_no_wake_grant ());
return target;
@@ -947,10 +1276,18 @@
NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE)
/* Looking for return type and argument can be found in tree.h file. */
+ tree ptr_char_type_node = build_pointer_type (char_type_node);
tree ptr_uchar_type_node = build_pointer_type (unsigned_char_type_node);
tree ptr_ushort_type_node = build_pointer_type (short_unsigned_type_node);
+ tree ptr_short_type_node = build_pointer_type (short_integer_type_node);
tree ptr_uint_type_node = build_pointer_type (unsigned_type_node);
tree ptr_ulong_type_node = build_pointer_type (long_long_unsigned_type_node);
+ tree v4qi_type_node = build_vector_type (intQI_type_node, 4);
+ tree u_v4qi_type_node = build_vector_type (unsigned_intQI_type_node, 4);
+ tree v2hi_type_node = build_vector_type (intHI_type_node, 2);
+ tree u_v2hi_type_node = build_vector_type (unsigned_intHI_type_node, 2);
+ tree v2si_type_node = build_vector_type (intSI_type_node, 2);
+ tree u_v2si_type_node = build_vector_type (unsigned_intSI_type_node, 2);
/* Cache. */
ADD_NDS32_BUILTIN1 ("isync", void, ptr_uint, ISYNC);
@@ -1050,6 +1387,31 @@
ADD_NDS32_BUILTIN2 ("se_ffmism", integer, unsigned, unsigned, FFMISM);
ADD_NDS32_BUILTIN2 ("se_flmism", integer, unsigned, unsigned, FLMISM);
+ /* SATURATION */
+ ADD_NDS32_BUILTIN2 ("kaddw", integer, integer, integer, KADDW);
+ ADD_NDS32_BUILTIN2 ("ksubw", integer, integer, integer, KSUBW);
+ ADD_NDS32_BUILTIN2 ("kaddh", integer, integer, integer, KADDH);
+ ADD_NDS32_BUILTIN2 ("ksubh", integer, integer, integer, KSUBH);
+ ADD_NDS32_BUILTIN2 ("kdmbb", integer, unsigned, unsigned, KDMBB);
+ ADD_NDS32_BUILTIN2 ("v_kdmbb", integer, v2hi, v2hi, V_KDMBB);
+ ADD_NDS32_BUILTIN2 ("kdmbt", integer, unsigned, unsigned, KDMBT);
+ ADD_NDS32_BUILTIN2 ("v_kdmbt", integer, v2hi, v2hi, V_KDMBT);
+ ADD_NDS32_BUILTIN2 ("kdmtb", integer, unsigned, unsigned, KDMTB);
+ ADD_NDS32_BUILTIN2 ("v_kdmtb", integer, v2hi, v2hi, V_KDMTB);
+ ADD_NDS32_BUILTIN2 ("kdmtt", integer, unsigned, unsigned, KDMTT);
+ ADD_NDS32_BUILTIN2 ("v_kdmtt", integer, v2hi, v2hi, V_KDMTT);
+ ADD_NDS32_BUILTIN2 ("khmbb", integer, unsigned, unsigned, KHMBB);
+ ADD_NDS32_BUILTIN2 ("v_khmbb", integer, v2hi, v2hi, V_KHMBB);
+ ADD_NDS32_BUILTIN2 ("khmbt", integer, unsigned, unsigned, KHMBT);
+ ADD_NDS32_BUILTIN2 ("v_khmbt", integer, v2hi, v2hi, V_KHMBT);
+ ADD_NDS32_BUILTIN2 ("khmtb", integer, unsigned, unsigned, KHMTB);
+ ADD_NDS32_BUILTIN2 ("v_khmtb", integer, v2hi, v2hi, V_KHMTB);
+ ADD_NDS32_BUILTIN2 ("khmtt", integer, unsigned, unsigned, KHMTT);
+ ADD_NDS32_BUILTIN2 ("v_khmtt", integer, v2hi, v2hi, V_KHMTT);
+ ADD_NDS32_BUILTIN2 ("kslraw", integer, integer, integer, KSLRAW);
+ ADD_NDS32_BUILTIN2 ("kslraw_u", integer, integer, integer, KSLRAW_U);
+ ADD_NDS32_BUILTIN0 ("rdov", unsigned, RDOV);
+ ADD_NDS32_BUILTIN0 ("clrov", void, CLROV);
/* ROTR */
ADD_NDS32_BUILTIN2 ("rotr", unsigned, unsigned, unsigned, ROTR);
@@ -1109,4 +1471,384 @@
ADD_NDS32_BUILTIN0 ("enable_unaligned", void, ENABLE_UNALIGNED);
ADD_NDS32_BUILTIN0 ("disable_unaligned", void, DISABLE_UNALIGNED);
+ /* DSP Extension: SIMD 16bit Add and Subtract. */
+ ADD_NDS32_BUILTIN2 ("add16", unsigned, unsigned, unsigned, ADD16);
+ ADD_NDS32_BUILTIN2 ("v_uadd16", u_v2hi, u_v2hi, u_v2hi, V_UADD16);
+ ADD_NDS32_BUILTIN2 ("v_sadd16", v2hi, v2hi, v2hi, V_SADD16);
+ ADD_NDS32_BUILTIN2 ("radd16", unsigned, unsigned, unsigned, RADD16);
+ ADD_NDS32_BUILTIN2 ("v_radd16", v2hi, v2hi, v2hi, V_RADD16);
+ ADD_NDS32_BUILTIN2 ("uradd16", unsigned, unsigned, unsigned, URADD16);
+ ADD_NDS32_BUILTIN2 ("v_uradd16", u_v2hi, u_v2hi, u_v2hi, V_URADD16);
+ ADD_NDS32_BUILTIN2 ("kadd16", unsigned, unsigned, unsigned, KADD16);
+ ADD_NDS32_BUILTIN2 ("v_kadd16", v2hi, v2hi, v2hi, V_KADD16);
+ ADD_NDS32_BUILTIN2 ("ukadd16", unsigned, unsigned, unsigned, UKADD16);
+ ADD_NDS32_BUILTIN2 ("v_ukadd16", u_v2hi, u_v2hi, u_v2hi, V_UKADD16);
+ ADD_NDS32_BUILTIN2 ("sub16", unsigned, unsigned, unsigned, SUB16);
+ ADD_NDS32_BUILTIN2 ("v_usub16", u_v2hi, u_v2hi, u_v2hi, V_USUB16);
+ ADD_NDS32_BUILTIN2 ("v_ssub16", v2hi, v2hi, v2hi, V_SSUB16);
+ ADD_NDS32_BUILTIN2 ("rsub16", unsigned, unsigned, unsigned, RSUB16);
+ ADD_NDS32_BUILTIN2 ("v_rsub16", v2hi, v2hi, v2hi, V_RSUB16);
+ ADD_NDS32_BUILTIN2 ("ursub16", unsigned, unsigned, unsigned, URSUB16);
+ ADD_NDS32_BUILTIN2 ("v_ursub16", u_v2hi, u_v2hi, u_v2hi, V_URSUB16);
+ ADD_NDS32_BUILTIN2 ("ksub16", unsigned, unsigned, unsigned, KSUB16);
+ ADD_NDS32_BUILTIN2 ("v_ksub16", v2hi, v2hi, v2hi, V_KSUB16);
+ ADD_NDS32_BUILTIN2 ("uksub16", unsigned, unsigned, unsigned, UKSUB16);
+ ADD_NDS32_BUILTIN2 ("v_uksub16", u_v2hi, u_v2hi, u_v2hi, V_UKSUB16);
+ ADD_NDS32_BUILTIN2 ("cras16", unsigned, unsigned, unsigned, CRAS16);
+ ADD_NDS32_BUILTIN2 ("v_ucras16", u_v2hi, u_v2hi, u_v2hi, V_UCRAS16);
+ ADD_NDS32_BUILTIN2 ("v_scras16", v2hi, v2hi, v2hi, V_SCRAS16);
+ ADD_NDS32_BUILTIN2 ("rcras16", unsigned, unsigned, unsigned, RCRAS16);
+ ADD_NDS32_BUILTIN2 ("v_rcras16", v2hi, v2hi, v2hi, V_RCRAS16);
+ ADD_NDS32_BUILTIN2 ("urcras16", unsigned, unsigned, unsigned, URCRAS16);
+ ADD_NDS32_BUILTIN2 ("v_urcras16", u_v2hi, u_v2hi, u_v2hi, V_URCRAS16);
+ ADD_NDS32_BUILTIN2 ("kcras16", unsigned, unsigned, unsigned, KCRAS16);
+ ADD_NDS32_BUILTIN2 ("v_kcras16", v2hi, v2hi, v2hi, V_KCRAS16);
+ ADD_NDS32_BUILTIN2 ("ukcras16", unsigned, unsigned, unsigned, UKCRAS16);
+ ADD_NDS32_BUILTIN2 ("v_ukcras16", u_v2hi, u_v2hi, u_v2hi, V_UKCRAS16);
+ ADD_NDS32_BUILTIN2 ("crsa16", unsigned, unsigned, unsigned, CRSA16);
+ ADD_NDS32_BUILTIN2 ("v_ucrsa16", u_v2hi, u_v2hi, u_v2hi, V_UCRSA16);
+ ADD_NDS32_BUILTIN2 ("v_scrsa16", v2hi, v2hi, v2hi, V_SCRSA16);
+ ADD_NDS32_BUILTIN2 ("rcrsa16", unsigned, unsigned, unsigned, RCRSA16);
+ ADD_NDS32_BUILTIN2 ("v_rcrsa16", v2hi, v2hi, v2hi, V_RCRSA16);
+ ADD_NDS32_BUILTIN2 ("urcrsa16", unsigned, unsigned, unsigned, URCRSA16);
+ ADD_NDS32_BUILTIN2 ("v_urcrsa16", u_v2hi, u_v2hi, u_v2hi, V_URCRSA16);
+ ADD_NDS32_BUILTIN2 ("kcrsa16", unsigned, unsigned, unsigned, KCRSA16);
+ ADD_NDS32_BUILTIN2 ("v_kcrsa16", v2hi, v2hi, v2hi, V_KCRSA16);
+ ADD_NDS32_BUILTIN2 ("ukcrsa16", unsigned, unsigned, unsigned, UKCRSA16);
+ ADD_NDS32_BUILTIN2 ("v_ukcrsa16", u_v2hi, u_v2hi, u_v2hi, V_UKCRSA16);
+
+ /* DSP Extension: SIMD 8bit Add and Subtract. */
+ ADD_NDS32_BUILTIN2 ("add8", integer, integer, integer, ADD8);
+ ADD_NDS32_BUILTIN2 ("v_uadd8", u_v4qi, u_v4qi, u_v4qi, V_UADD8);
+ ADD_NDS32_BUILTIN2 ("v_sadd8", v4qi, v4qi, v4qi, V_SADD8);
+ ADD_NDS32_BUILTIN2 ("radd8", unsigned, unsigned, unsigned, RADD8);
+ ADD_NDS32_BUILTIN2 ("v_radd8", v4qi, v4qi, v4qi, V_RADD8);
+ ADD_NDS32_BUILTIN2 ("uradd8", unsigned, unsigned, unsigned, URADD8);
+ ADD_NDS32_BUILTIN2 ("v_uradd8", u_v4qi, u_v4qi, u_v4qi, V_URADD8);
+ ADD_NDS32_BUILTIN2 ("kadd8", unsigned, unsigned, unsigned, KADD8);
+ ADD_NDS32_BUILTIN2 ("v_kadd8", v4qi, v4qi, v4qi, V_KADD8);
+ ADD_NDS32_BUILTIN2 ("ukadd8", unsigned, unsigned, unsigned, UKADD8);
+ ADD_NDS32_BUILTIN2 ("v_ukadd8", u_v4qi, u_v4qi, u_v4qi, V_UKADD8);
+ ADD_NDS32_BUILTIN2 ("sub8", integer, integer, integer, SUB8);
+ ADD_NDS32_BUILTIN2 ("v_usub8", u_v4qi, u_v4qi, u_v4qi, V_USUB8);
+ ADD_NDS32_BUILTIN2 ("v_ssub8", v4qi, v4qi, v4qi, V_SSUB8);
+ ADD_NDS32_BUILTIN2 ("rsub8", unsigned, unsigned, unsigned, RSUB8);
+ ADD_NDS32_BUILTIN2 ("v_rsub8", v4qi, v4qi, v4qi, V_RSUB8);
+ ADD_NDS32_BUILTIN2 ("ursub8", unsigned, unsigned, unsigned, URSUB8);
+ ADD_NDS32_BUILTIN2 ("v_ursub8", u_v4qi, u_v4qi, u_v4qi, V_URSUB8);
+ ADD_NDS32_BUILTIN2 ("ksub8", unsigned, unsigned, unsigned, KSUB8);
+ ADD_NDS32_BUILTIN2 ("v_ksub8", v4qi, v4qi, v4qi, V_KSUB8);
+ ADD_NDS32_BUILTIN2 ("uksub8", unsigned, unsigned, unsigned, UKSUB8);
+ ADD_NDS32_BUILTIN2 ("v_uksub8", u_v4qi, u_v4qi, u_v4qi, V_UKSUB8);
+
+ /* DSP Extension: SIMD 16bit Shift. */
+ ADD_NDS32_BUILTIN2 ("sra16", unsigned, unsigned, unsigned, SRA16);
+ ADD_NDS32_BUILTIN2 ("v_sra16", v2hi, v2hi, unsigned, V_SRA16);
+ ADD_NDS32_BUILTIN2 ("sra16_u", unsigned, unsigned, unsigned, SRA16_U);
+ ADD_NDS32_BUILTIN2 ("v_sra16_u", v2hi, v2hi, unsigned, V_SRA16_U);
+ ADD_NDS32_BUILTIN2 ("srl16", unsigned, unsigned, unsigned, SRL16);
+ ADD_NDS32_BUILTIN2 ("v_srl16", u_v2hi, u_v2hi, unsigned, V_SRL16);
+ ADD_NDS32_BUILTIN2 ("srl16_u", unsigned, unsigned, unsigned, SRL16_U);
+ ADD_NDS32_BUILTIN2 ("v_srl16_u", u_v2hi, u_v2hi, unsigned, V_SRL16_U);
+ ADD_NDS32_BUILTIN2 ("sll16", unsigned, unsigned, unsigned, SLL16);
+ ADD_NDS32_BUILTIN2 ("v_sll16", u_v2hi, u_v2hi, unsigned, V_SLL16);
+ ADD_NDS32_BUILTIN2 ("ksll16", unsigned, unsigned, unsigned, KSLL16);
+ ADD_NDS32_BUILTIN2 ("v_ksll16", v2hi, v2hi, unsigned, V_KSLL16);
+ ADD_NDS32_BUILTIN2 ("kslra16", unsigned, unsigned, unsigned, KSLRA16);
+ ADD_NDS32_BUILTIN2 ("v_kslra16", v2hi, v2hi, unsigned, V_KSLRA16);
+ ADD_NDS32_BUILTIN2 ("kslra16_u", unsigned, unsigned, unsigned, KSLRA16_U);
+ ADD_NDS32_BUILTIN2 ("v_kslra16_u", v2hi, v2hi, unsigned, V_KSLRA16_U);
+
+ /* DSP Extension: 16bit Compare. */
+ ADD_NDS32_BUILTIN2 ("cmpeq16", unsigned, unsigned, unsigned, CMPEQ16);
+ ADD_NDS32_BUILTIN2 ("v_scmpeq16", u_v2hi, v2hi, v2hi, V_SCMPEQ16);
+ ADD_NDS32_BUILTIN2 ("v_ucmpeq16", u_v2hi, u_v2hi, u_v2hi, V_UCMPEQ16);
+ ADD_NDS32_BUILTIN2 ("scmplt16", unsigned, unsigned, unsigned, SCMPLT16);
+ ADD_NDS32_BUILTIN2 ("v_scmplt16", u_v2hi, v2hi, v2hi, V_SCMPLT16);
+ ADD_NDS32_BUILTIN2 ("scmple16", unsigned, unsigned, unsigned, SCMPLE16);
+ ADD_NDS32_BUILTIN2 ("v_scmple16", u_v2hi, v2hi, v2hi, V_SCMPLE16);
+ ADD_NDS32_BUILTIN2 ("ucmplt16", unsigned, unsigned, unsigned, UCMPLT16);
+ ADD_NDS32_BUILTIN2 ("v_ucmplt16", u_v2hi, u_v2hi, u_v2hi, V_UCMPLT16);
+ ADD_NDS32_BUILTIN2 ("ucmple16", unsigned, unsigned, unsigned, UCMPLE16);
+ ADD_NDS32_BUILTIN2 ("v_ucmple16", u_v2hi, u_v2hi, u_v2hi, V_UCMPLE16);
+
+ /* DSP Extension: 8bit Compare. */
+ ADD_NDS32_BUILTIN2 ("cmpeq8", unsigned, unsigned, unsigned, CMPEQ8);
+ ADD_NDS32_BUILTIN2 ("v_scmpeq8", u_v4qi, v4qi, v4qi, V_SCMPEQ8);
+ ADD_NDS32_BUILTIN2 ("v_ucmpeq8", u_v4qi, u_v4qi, u_v4qi, V_UCMPEQ8);
+ ADD_NDS32_BUILTIN2 ("scmplt8", unsigned, unsigned, unsigned, SCMPLT8);
+ ADD_NDS32_BUILTIN2 ("v_scmplt8", u_v4qi, v4qi, v4qi, V_SCMPLT8);
+ ADD_NDS32_BUILTIN2 ("scmple8", unsigned, unsigned, unsigned, SCMPLE8);
+ ADD_NDS32_BUILTIN2 ("v_scmple8", u_v4qi, v4qi, v4qi, V_SCMPLE8);
+ ADD_NDS32_BUILTIN2 ("ucmplt8", unsigned, unsigned, unsigned, UCMPLT8);
+ ADD_NDS32_BUILTIN2 ("v_ucmplt8", u_v4qi, u_v4qi, u_v4qi, V_UCMPLT8);
+ ADD_NDS32_BUILTIN2 ("ucmple8", unsigned, unsigned, unsigned, UCMPLE8);
+ ADD_NDS32_BUILTIN2 ("v_ucmple8", u_v4qi, u_v4qi, u_v4qi, V_UCMPLE8);
+
+ /* DSP Extension: SIMD 16bit MISC. */
+ ADD_NDS32_BUILTIN2 ("smin16", unsigned, unsigned, unsigned, SMIN16);
+ ADD_NDS32_BUILTIN2 ("v_smin16", v2hi, v2hi, v2hi, V_SMIN16);
+ ADD_NDS32_BUILTIN2 ("umin16", unsigned, unsigned, unsigned, UMIN16);
+ ADD_NDS32_BUILTIN2 ("v_umin16", u_v2hi, u_v2hi, u_v2hi, V_UMIN16);
+ ADD_NDS32_BUILTIN2 ("smax16", unsigned, unsigned, unsigned, SMAX16);
+ ADD_NDS32_BUILTIN2 ("v_smax16", v2hi, v2hi, v2hi, V_SMAX16);
+ ADD_NDS32_BUILTIN2 ("umax16", unsigned, unsigned, unsigned, UMAX16);
+ ADD_NDS32_BUILTIN2 ("v_umax16", u_v2hi, u_v2hi, u_v2hi, V_UMAX16);
+ ADD_NDS32_BUILTIN2 ("sclip16", unsigned, unsigned, unsigned, SCLIP16);
+ ADD_NDS32_BUILTIN2 ("v_sclip16", v2hi, v2hi, unsigned, V_SCLIP16);
+ ADD_NDS32_BUILTIN2 ("uclip16", unsigned, unsigned, unsigned, UCLIP16);
+ ADD_NDS32_BUILTIN2 ("v_uclip16", v2hi, v2hi, unsigned, V_UCLIP16);
+ ADD_NDS32_BUILTIN2 ("khm16", unsigned, unsigned, unsigned, KHM16);
+ ADD_NDS32_BUILTIN2 ("v_khm16", v2hi, v2hi, v2hi, V_KHM16);
+ ADD_NDS32_BUILTIN2 ("khmx16", unsigned, unsigned, unsigned, KHMX16);
+ ADD_NDS32_BUILTIN2 ("v_khmx16", v2hi, v2hi, v2hi, V_KHMX16);
+ ADD_NDS32_BUILTIN1 ("kabs16", unsigned, unsigned, KABS16);
+ ADD_NDS32_BUILTIN1 ("v_kabs16", v2hi, v2hi, V_KABS16);
+ ADD_NDS32_BUILTIN2 ("smul16", long_long_unsigned, unsigned, unsigned, SMUL16);
+ ADD_NDS32_BUILTIN2 ("v_smul16", v2si, v2hi, v2hi, V_SMUL16);
+ ADD_NDS32_BUILTIN2 ("smulx16",
+ long_long_unsigned, unsigned, unsigned, SMULX16);
+ ADD_NDS32_BUILTIN2 ("v_smulx16", v2si, v2hi, v2hi, V_SMULX16);
+ ADD_NDS32_BUILTIN2 ("umul16", long_long_unsigned, unsigned, unsigned, UMUL16);
+ ADD_NDS32_BUILTIN2 ("v_umul16", u_v2si, u_v2hi, u_v2hi, V_UMUL16);
+ ADD_NDS32_BUILTIN2 ("umulx16",
+ long_long_unsigned, unsigned, unsigned, UMULX16);
+ ADD_NDS32_BUILTIN2 ("v_umulx16", u_v2si, u_v2hi, u_v2hi, V_UMULX16);
+
+ /* DSP Extension: SIMD 8bit MISC. */
+ ADD_NDS32_BUILTIN2 ("smin8", unsigned, unsigned, unsigned, SMIN8);
+ ADD_NDS32_BUILTIN2 ("v_smin8", v4qi, v4qi, v4qi, V_SMIN8);
+ ADD_NDS32_BUILTIN2 ("umin8", unsigned, unsigned, unsigned, UMIN8);
+ ADD_NDS32_BUILTIN2 ("v_umin8", u_v4qi, u_v4qi, u_v4qi, V_UMIN8);
+ ADD_NDS32_BUILTIN2 ("smax8", unsigned, unsigned, unsigned, SMAX8);
+ ADD_NDS32_BUILTIN2 ("v_smax8", v4qi, v4qi, v4qi, V_SMAX8);
+ ADD_NDS32_BUILTIN2 ("umax8", unsigned, unsigned, unsigned, UMAX8);
+ ADD_NDS32_BUILTIN2 ("v_umax8", u_v4qi, u_v4qi, u_v4qi, V_UMAX8);
+ ADD_NDS32_BUILTIN1 ("kabs8", unsigned, unsigned, KABS8);
+ ADD_NDS32_BUILTIN1 ("v_kabs8", v4qi, v4qi, V_KABS8);
+
+ /* DSP Extension: 8bit Unpacking. */
+ ADD_NDS32_BUILTIN1 ("sunpkd810", unsigned, unsigned, SUNPKD810);
+ ADD_NDS32_BUILTIN1 ("v_sunpkd810", v2hi, v4qi, V_SUNPKD810);
+ ADD_NDS32_BUILTIN1 ("sunpkd820", unsigned, unsigned, SUNPKD820);
+ ADD_NDS32_BUILTIN1 ("v_sunpkd820", v2hi, v4qi, V_SUNPKD820);
+ ADD_NDS32_BUILTIN1 ("sunpkd830", unsigned, unsigned, SUNPKD830);
+ ADD_NDS32_BUILTIN1 ("v_sunpkd830", v2hi, v4qi, V_SUNPKD830);
+ ADD_NDS32_BUILTIN1 ("sunpkd831", unsigned, unsigned, SUNPKD831);
+ ADD_NDS32_BUILTIN1 ("v_sunpkd831", v2hi, v4qi, V_SUNPKD831);
+ ADD_NDS32_BUILTIN1 ("zunpkd810", unsigned, unsigned, ZUNPKD810);
+ ADD_NDS32_BUILTIN1 ("v_zunpkd810", u_v2hi, u_v4qi, V_ZUNPKD810);
+ ADD_NDS32_BUILTIN1 ("zunpkd820", unsigned, unsigned, ZUNPKD820);
+ ADD_NDS32_BUILTIN1 ("v_zunpkd820", u_v2hi, u_v4qi, V_ZUNPKD820);
+ ADD_NDS32_BUILTIN1 ("zunpkd830", unsigned, unsigned, ZUNPKD830);
+ ADD_NDS32_BUILTIN1 ("v_zunpkd830", u_v2hi, u_v4qi, V_ZUNPKD830);
+ ADD_NDS32_BUILTIN1 ("zunpkd831", unsigned, unsigned, ZUNPKD831);
+ ADD_NDS32_BUILTIN1 ("v_zunpkd831", u_v2hi, u_v4qi, V_ZUNPKD831);
+
+ /* DSP Extension: 32bit Add and Subtract. */
+ ADD_NDS32_BUILTIN2 ("raddw", integer, integer, integer, RADDW);
+ ADD_NDS32_BUILTIN2 ("uraddw", unsigned, unsigned, unsigned, URADDW);
+ ADD_NDS32_BUILTIN2 ("rsubw", integer, integer, integer, RSUBW);
+ ADD_NDS32_BUILTIN2 ("ursubw", unsigned, unsigned, unsigned, URSUBW);
+
+ /* DSP Extension: 32bit Shift. */
+ ADD_NDS32_BUILTIN2 ("sra_u", integer, integer, unsigned, SRA_U);
+ ADD_NDS32_BUILTIN2 ("ksll", integer, integer, unsigned, KSLL);
+
+ /* DSP Extension: 16bit Packing. */
+ ADD_NDS32_BUILTIN2 ("pkbb16", unsigned, unsigned, unsigned, PKBB16);
+ ADD_NDS32_BUILTIN2 ("v_pkbb16", u_v2hi, u_v2hi, u_v2hi, V_PKBB16);
+ ADD_NDS32_BUILTIN2 ("pkbt16", unsigned, unsigned, unsigned, PKBT16);
+ ADD_NDS32_BUILTIN2 ("v_pkbt16", u_v2hi, u_v2hi, u_v2hi, V_PKBT16);
+ ADD_NDS32_BUILTIN2 ("pktb16", unsigned, unsigned, unsigned, PKTB16);
+ ADD_NDS32_BUILTIN2 ("v_pktb16", u_v2hi, u_v2hi, u_v2hi, V_PKTB16);
+ ADD_NDS32_BUILTIN2 ("pktt16", unsigned, unsigned, unsigned, PKTT16);
+ ADD_NDS32_BUILTIN2 ("v_pktt16", u_v2hi, u_v2hi, u_v2hi, V_PKTT16);
+
+ /* DSP Extension: Signed MSW 32x32 Multiply and ADD. */
+ ADD_NDS32_BUILTIN2 ("smmul", integer, integer, integer, SMMUL);
+ ADD_NDS32_BUILTIN2 ("smmul_u", integer, integer, integer, SMMUL_U);
+ ADD_NDS32_BUILTIN3 ("kmmac", integer, integer, integer, integer, KMMAC);
+ ADD_NDS32_BUILTIN3 ("kmmac_u", integer, integer, integer, integer, KMMAC_U);
+ ADD_NDS32_BUILTIN3 ("kmmsb", integer, integer, integer, integer, KMMSB);
+ ADD_NDS32_BUILTIN3 ("kmmsb_u", integer, integer, integer, integer, KMMSB_U);
+ ADD_NDS32_BUILTIN2 ("kwmmul", integer, integer, integer, KWMMUL);
+ ADD_NDS32_BUILTIN2 ("kwmmul_u", integer, integer, integer, KWMMUL_U);
+
+ /* DSP Extension: Most Significant Word 32x16 Multiply and ADD. */
+ ADD_NDS32_BUILTIN2 ("smmwb", integer, integer, unsigned, SMMWB);
+ ADD_NDS32_BUILTIN2 ("v_smmwb", integer, integer, v2hi, V_SMMWB);
+ ADD_NDS32_BUILTIN2 ("smmwb_u", integer, integer, unsigned, SMMWB_U);
+ ADD_NDS32_BUILTIN2 ("v_smmwb_u", integer, integer, v2hi, V_SMMWB_U);
+ ADD_NDS32_BUILTIN2 ("smmwt", integer, integer, unsigned, SMMWT);
+ ADD_NDS32_BUILTIN2 ("v_smmwt", integer, integer, v2hi, V_SMMWT);
+ ADD_NDS32_BUILTIN2 ("smmwt_u", integer, integer, unsigned, SMMWT_U);
+ ADD_NDS32_BUILTIN2 ("v_smmwt_u", integer, integer, v2hi, V_SMMWT_U);
+ ADD_NDS32_BUILTIN3 ("kmmawb", integer, integer, integer, unsigned, KMMAWB);
+ ADD_NDS32_BUILTIN3 ("v_kmmawb", integer, integer, integer, v2hi, V_KMMAWB);
+ ADD_NDS32_BUILTIN3 ("kmmawb_u",
+ integer, integer, integer, unsigned, KMMAWB_U);
+ ADD_NDS32_BUILTIN3 ("v_kmmawb_u",
+ integer, integer, integer, v2hi, V_KMMAWB_U);
+ ADD_NDS32_BUILTIN3 ("kmmawt", integer, integer, integer, unsigned, KMMAWT);
+ ADD_NDS32_BUILTIN3 ("v_kmmawt", integer, integer, integer, v2hi, V_KMMAWT);
+ ADD_NDS32_BUILTIN3 ("kmmawt_u",
+ integer, integer, integer, unsigned, KMMAWT_U);
+ ADD_NDS32_BUILTIN3 ("v_kmmawt_u",
+ integer, integer, integer, v2hi, V_KMMAWT_U);
+
+ /* DSP Extension: Signed 16bit Multiply with ADD/Subtract. */
+ ADD_NDS32_BUILTIN2 ("smbb", integer, unsigned, unsigned, SMBB);
+ ADD_NDS32_BUILTIN2 ("v_smbb", integer, v2hi, v2hi, V_SMBB);
+ ADD_NDS32_BUILTIN2 ("smbt", integer, unsigned, unsigned, SMBT);
+ ADD_NDS32_BUILTIN2 ("v_smbt", integer, v2hi, v2hi, V_SMBT);
+ ADD_NDS32_BUILTIN2 ("smtt", integer, unsigned, unsigned, SMTT);
+ ADD_NDS32_BUILTIN2 ("v_smtt", integer, v2hi, v2hi, V_SMTT);
+ ADD_NDS32_BUILTIN2 ("kmda", integer, unsigned, unsigned, KMDA);
+ ADD_NDS32_BUILTIN2 ("v_kmda", integer, v2hi, v2hi, V_KMDA);
+ ADD_NDS32_BUILTIN2 ("kmxda", integer, unsigned, unsigned, KMXDA);
+ ADD_NDS32_BUILTIN2 ("v_kmxda", integer, v2hi, v2hi, V_KMXDA);
+ ADD_NDS32_BUILTIN2 ("smds", integer, unsigned, unsigned, SMDS);
+ ADD_NDS32_BUILTIN2 ("v_smds", integer, v2hi, v2hi, V_SMDS);
+ ADD_NDS32_BUILTIN2 ("smdrs", integer, unsigned, unsigned, SMDRS);
+ ADD_NDS32_BUILTIN2 ("v_smdrs", integer, v2hi, v2hi, V_SMDRS);
+ ADD_NDS32_BUILTIN2 ("smxds", integer, unsigned, unsigned, SMXDS);
+ ADD_NDS32_BUILTIN2 ("v_smxds", integer, v2hi, v2hi, V_SMXDS);
+ ADD_NDS32_BUILTIN3 ("kmabb", integer, integer, unsigned, unsigned, KMABB);
+ ADD_NDS32_BUILTIN3 ("v_kmabb", integer, integer, v2hi, v2hi, V_KMABB);
+ ADD_NDS32_BUILTIN3 ("kmabt", integer, integer, unsigned, unsigned, KMABT);
+ ADD_NDS32_BUILTIN3 ("v_kmabt", integer, integer, v2hi, v2hi, V_KMABT);
+ ADD_NDS32_BUILTIN3 ("kmatt", integer, integer, unsigned, unsigned, KMATT);
+ ADD_NDS32_BUILTIN3 ("v_kmatt", integer, integer, v2hi, v2hi, V_KMATT);
+ ADD_NDS32_BUILTIN3 ("kmada", integer, integer, unsigned, unsigned, KMADA);
+ ADD_NDS32_BUILTIN3 ("v_kmada", integer, integer, v2hi, v2hi, V_KMADA);
+ ADD_NDS32_BUILTIN3 ("kmaxda", integer, integer, unsigned, unsigned, KMAXDA);
+ ADD_NDS32_BUILTIN3 ("v_kmaxda", integer, integer, v2hi, v2hi, V_KMAXDA);
+ ADD_NDS32_BUILTIN3 ("kmads", integer, integer, unsigned, unsigned, KMADS);
+ ADD_NDS32_BUILTIN3 ("v_kmads", integer, integer, v2hi, v2hi, V_KMADS);
+ ADD_NDS32_BUILTIN3 ("kmadrs", integer, integer, unsigned, unsigned, KMADRS);
+ ADD_NDS32_BUILTIN3 ("v_kmadrs", integer, integer, v2hi, v2hi, V_KMADRS);
+ ADD_NDS32_BUILTIN3 ("kmaxds", integer, integer, unsigned, unsigned, KMAXDS);
+ ADD_NDS32_BUILTIN3 ("v_kmaxds", integer, integer, v2hi, v2hi, V_KMAXDS);
+ ADD_NDS32_BUILTIN3 ("kmsda", integer, integer, unsigned, unsigned, KMSDA);
+ ADD_NDS32_BUILTIN3 ("v_kmsda", integer, integer, v2hi, v2hi, V_KMSDA);
+ ADD_NDS32_BUILTIN3 ("kmsxda", integer, integer, unsigned, unsigned, KMSXDA);
+ ADD_NDS32_BUILTIN3 ("v_kmsxda", integer, integer, v2hi, v2hi, V_KMSXDA);
+
+ /* DSP Extension: Signed 16bit Multiply with 64bit ADD/Subtract. */
+ ADD_NDS32_BUILTIN2 ("smal", long_long_integer,
+ long_long_integer, unsigned, SMAL);
+ ADD_NDS32_BUILTIN2 ("v_smal", long_long_integer,
+ long_long_integer, v2hi, V_SMAL);
+
+ /* DSP Extension: 32bit MISC. */
+ ADD_NDS32_BUILTIN2 ("bitrev", unsigned, unsigned, unsigned, BITREV);
+ ADD_NDS32_BUILTIN2 ("wext", unsigned, long_long_integer, unsigned, WEXT);
+ ADD_NDS32_BUILTIN3 ("bpick", unsigned, unsigned, unsigned, unsigned, BPICK);
+ ADD_NDS32_BUILTIN3 ("insb", unsigned, unsigned, unsigned, unsigned, INSB);
+
+ /* DSP Extension: 64bit Add and Subtract. */
+ ADD_NDS32_BUILTIN2 ("sadd64", long_long_integer,
+ long_long_integer, long_long_integer, SADD64);
+ ADD_NDS32_BUILTIN2 ("uadd64", long_long_unsigned,
+ long_long_unsigned, long_long_unsigned, UADD64);
+ ADD_NDS32_BUILTIN2 ("radd64", long_long_integer,
+ long_long_integer, long_long_integer, RADD64);
+ ADD_NDS32_BUILTIN2 ("uradd64", long_long_unsigned,
+ long_long_unsigned, long_long_unsigned, URADD64);
+ ADD_NDS32_BUILTIN2 ("kadd64", long_long_integer,
+ long_long_integer, long_long_integer, KADD64);
+ ADD_NDS32_BUILTIN2 ("ukadd64", long_long_unsigned,
+ long_long_unsigned, long_long_unsigned, UKADD64);
+ ADD_NDS32_BUILTIN2 ("ssub64", long_long_integer,
+ long_long_integer, long_long_integer, SSUB64);
+ ADD_NDS32_BUILTIN2 ("usub64", long_long_unsigned,
+ long_long_unsigned, long_long_unsigned, USUB64);
+ ADD_NDS32_BUILTIN2 ("rsub64", long_long_integer,
+ long_long_integer, long_long_integer, RSUB64);
+ ADD_NDS32_BUILTIN2 ("ursub64", long_long_unsigned,
+ long_long_unsigned, long_long_unsigned, URSUB64);
+ ADD_NDS32_BUILTIN2 ("ksub64", long_long_integer,
+ long_long_integer, long_long_integer, KSUB64);
+ ADD_NDS32_BUILTIN2 ("uksub64", long_long_unsigned,
+ long_long_unsigned, long_long_unsigned, UKSUB64);
+
+ /* DSP Extension: 32bit Multiply with 64bit Add/Subtract. */
+ ADD_NDS32_BUILTIN3 ("smar64", long_long_integer,
+ long_long_integer, integer, integer, SMAR64);
+ ADD_NDS32_BUILTIN3 ("smsr64", long_long_integer,
+ long_long_integer, integer, integer, SMSR64);
+ ADD_NDS32_BUILTIN3 ("umar64", long_long_unsigned,
+ long_long_unsigned, unsigned, unsigned, UMAR64);
+ ADD_NDS32_BUILTIN3 ("umsr64", long_long_unsigned,
+ long_long_unsigned, unsigned, unsigned, UMSR64);
+ ADD_NDS32_BUILTIN3 ("kmar64", long_long_integer,
+ long_long_integer, integer, integer, KMAR64);
+ ADD_NDS32_BUILTIN3 ("kmsr64", long_long_integer,
+ long_long_integer, integer, integer, KMSR64);
+ ADD_NDS32_BUILTIN3 ("ukmar64", long_long_unsigned,
+ long_long_unsigned, unsigned, unsigned, UKMAR64);
+ ADD_NDS32_BUILTIN3 ("ukmsr64", long_long_unsigned,
+ long_long_unsigned, unsigned, unsigned, UKMSR64);
+
+ /* DSP Extension: Signed 16bit Multiply with 64bit Add/Subtract. */
+ ADD_NDS32_BUILTIN3 ("smalbb", long_long_integer,
+ long_long_integer, unsigned, unsigned, SMALBB);
+ ADD_NDS32_BUILTIN3 ("v_smalbb", long_long_integer,
+ long_long_integer, v2hi, v2hi, V_SMALBB);
+ ADD_NDS32_BUILTIN3 ("smalbt", long_long_integer,
+ long_long_integer, unsigned, unsigned, SMALBT);
+ ADD_NDS32_BUILTIN3 ("v_smalbt", long_long_integer,
+ long_long_integer, v2hi, v2hi, V_SMALBT);
+ ADD_NDS32_BUILTIN3 ("smaltt", long_long_integer,
+ long_long_integer, unsigned, unsigned, SMALTT);
+ ADD_NDS32_BUILTIN3 ("v_smaltt", long_long_integer,
+ long_long_integer, v2hi, v2hi, V_SMALTT);
+ ADD_NDS32_BUILTIN3 ("smalda", long_long_integer,
+ long_long_integer, unsigned, unsigned, SMALDA);
+ ADD_NDS32_BUILTIN3 ("v_smalda", long_long_integer,
+ long_long_integer, v2hi, v2hi, V_SMALDA);
+ ADD_NDS32_BUILTIN3 ("smalxda", long_long_integer,
+ long_long_integer, unsigned, unsigned, SMALXDA);
+ ADD_NDS32_BUILTIN3 ("v_smalxda", long_long_integer,
+ long_long_integer, v2hi, v2hi, V_SMALXDA);
+ ADD_NDS32_BUILTIN3 ("smalds", long_long_integer,
+ long_long_integer, unsigned, unsigned, SMALDS);
+ ADD_NDS32_BUILTIN3 ("v_smalds", long_long_integer,
+ long_long_integer, v2hi, v2hi, V_SMALDS);
+ ADD_NDS32_BUILTIN3 ("smaldrs", long_long_integer,
+ long_long_integer, unsigned, unsigned, SMALDRS);
+ ADD_NDS32_BUILTIN3 ("v_smaldrs", long_long_integer,
+ long_long_integer, v2hi, v2hi, V_SMALDRS);
+ ADD_NDS32_BUILTIN3 ("smalxds", long_long_integer,
+ long_long_integer, unsigned, unsigned, SMALXDS);
+ ADD_NDS32_BUILTIN3 ("v_smalxds", long_long_integer,
+ long_long_integer, v2hi, v2hi, V_SMALXDS);
+ ADD_NDS32_BUILTIN3 ("smslda", long_long_integer,
+ long_long_integer, unsigned, unsigned, SMSLDA);
+ ADD_NDS32_BUILTIN3 ("v_smslda", long_long_integer,
+ long_long_integer, v2hi, v2hi, V_SMSLDA);
+ ADD_NDS32_BUILTIN3 ("smslxda", long_long_integer,
+ long_long_integer, unsigned, unsigned, SMSLXDA);
+ ADD_NDS32_BUILTIN3 ("v_smslxda", long_long_integer,
+ long_long_integer, v2hi, v2hi, V_SMSLXDA);
+
+ /* DSP Extension: augmented baseline. */
+ ADD_NDS32_BUILTIN2 ("uclip32", unsigned, integer, unsigned, UCLIP32);
+ ADD_NDS32_BUILTIN2 ("sclip32", integer, integer, unsigned, SCLIP32);
+ ADD_NDS32_BUILTIN1 ("kabs", integer, integer, KABS);
+
+ /* DSP Extension: vector type unaligned Load/Store */
+ ADD_NDS32_BUILTIN1 ("get_unaligned_u16x2", u_v2hi, ptr_ushort, UALOAD_U16);
+ ADD_NDS32_BUILTIN1 ("get_unaligned_s16x2", v2hi, ptr_short, UALOAD_S16);
+ ADD_NDS32_BUILTIN1 ("get_unaligned_u8x4", u_v4qi, ptr_uchar, UALOAD_U8);
+ ADD_NDS32_BUILTIN1 ("get_unaligned_s8x4", v4qi, ptr_char, UALOAD_S8);
+ ADD_NDS32_BUILTIN2 ("put_unaligned_u16x2", void, ptr_ushort,
+ u_v2hi, UASTORE_U16);
+ ADD_NDS32_BUILTIN2 ("put_unaligned_s16x2", void, ptr_short,
+ v2hi, UASTORE_S16);
+ ADD_NDS32_BUILTIN2 ("put_unaligned_u8x4", void, ptr_uchar,
+ u_v4qi, UASTORE_U8);
+ ADD_NDS32_BUILTIN2 ("put_unaligned_s8x4", void, ptr_char,
+ v4qi, UASTORE_S8);
}
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32_intrinsic.h gcc-8.2.0/gcc/config/nds32/nds32_intrinsic.h
--- gcc-8.2.0.orig/gcc/config/nds32/nds32_intrinsic.h 2018-04-22 09:46:39.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32_intrinsic.h 2019-01-25 15:38:32.833242671 +0100
@@ -26,6 +26,13 @@
#ifndef _NDS32_INTRINSIC_H
#define _NDS32_INTRINSIC_H
+typedef signed char int8x4_t __attribute ((vector_size(4)));
+typedef short int16x2_t __attribute ((vector_size(4)));
+typedef int int32x2_t __attribute__((vector_size(8)));
+typedef unsigned char uint8x4_t __attribute__ ((vector_size (4)));
+typedef unsigned short uint16x2_t __attribute__ ((vector_size (4)));
+typedef unsigned int uint32x2_t __attribute__((vector_size(8)));
+
/* General instrinsic register names. */
enum nds32_intrinsic_registers
{
@@ -691,6 +698,55 @@
#define __nds32__tlbop_flua() \
(__builtin_nds32_tlbop_flua())
+#define __nds32__kaddw(a, b) \
+ (__builtin_nds32_kaddw ((a), (b)))
+#define __nds32__kaddh(a, b) \
+ (__builtin_nds32_kaddh ((a), (b)))
+#define __nds32__ksubw(a, b) \
+ (__builtin_nds32_ksubw ((a), (b)))
+#define __nds32__ksubh(a, b) \
+ (__builtin_nds32_ksubh ((a), (b)))
+#define __nds32__kdmbb(a, b) \
+ (__builtin_nds32_kdmbb ((a), (b)))
+#define __nds32__v_kdmbb(a, b) \
+ (__builtin_nds32_v_kdmbb ((a), (b)))
+#define __nds32__kdmbt(a, b) \
+ (__builtin_nds32_kdmbt ((a), (b)))
+#define __nds32__v_kdmbt(a, b) \
+ (__builtin_nds32_v_kdmbt ((a), (b)))
+#define __nds32__kdmtb(a, b) \
+ (__builtin_nds32_kdmtb ((a), (b)))
+#define __nds32__v_kdmtb(a, b) \
+ (__builtin_nds32_v_kdmtb ((a), (b)))
+#define __nds32__kdmtt(a, b) \
+ (__builtin_nds32_kdmtt ((a), (b)))
+#define __nds32__v_kdmtt(a, b) \
+ (__builtin_nds32_v_kdmtt ((a), (b)))
+#define __nds32__khmbb(a, b) \
+ (__builtin_nds32_khmbb ((a), (b)))
+#define __nds32__v_khmbb(a, b) \
+ (__builtin_nds32_v_khmbb ((a), (b)))
+#define __nds32__khmbt(a, b) \
+ (__builtin_nds32_khmbt ((a), (b)))
+#define __nds32__v_khmbt(a, b) \
+ (__builtin_nds32_v_khmbt ((a), (b)))
+#define __nds32__khmtb(a, b) \
+ (__builtin_nds32_khmtb ((a), (b)))
+#define __nds32__v_khmtb(a, b) \
+ (__builtin_nds32_v_khmtb ((a), (b)))
+#define __nds32__khmtt(a, b) \
+ (__builtin_nds32_khmtt ((a), (b)))
+#define __nds32__v_khmtt(a, b) \
+ (__builtin_nds32_v_khmtt ((a), (b)))
+#define __nds32__kslraw(a, b) \
+ (__builtin_nds32_kslraw ((a), (b)))
+#define __nds32__kslraw_u(a, b) \
+ (__builtin_nds32_kslraw_u ((a), (b)))
+
+#define __nds32__rdov() \
+ (__builtin_nds32_rdov())
+#define __nds32__clrov() \
+ (__builtin_nds32_clrov())
#define __nds32__gie_dis() \
(__builtin_nds32_gie_dis())
#define __nds32__gie_en() \
@@ -720,10 +776,622 @@
#define __nds32__get_trig_type(a) \
(__builtin_nds32_get_trig_type ((a)))
+#define __nds32__get_unaligned_hw(a) \
+ (__builtin_nds32_unaligned_load_hw ((a)))
+#define __nds32__get_unaligned_w(a) \
+ (__builtin_nds32_unaligned_load_w ((a)))
+#define __nds32__get_unaligned_dw(a) \
+ (__builtin_nds32_unaligned_load_dw ((a)))
+#define __nds32__put_unaligned_hw(a, data) \
+ (__builtin_nds32_unaligned_store_hw ((a), (data)))
+#define __nds32__put_unaligned_w(a, data) \
+ (__builtin_nds32_unaligned_store_w ((a), (data)))
+#define __nds32__put_unaligned_dw(a, data) \
+ (__builtin_nds32_unaligned_store_dw ((a), (data)))
+
+#define __nds32__add16(a, b) \
+ (__builtin_nds32_add16 ((a), (b)))
+#define __nds32__v_uadd16(a, b) \
+ (__builtin_nds32_v_uadd16 ((a), (b)))
+#define __nds32__v_sadd16(a, b) \
+ (__builtin_nds32_v_sadd16 ((a), (b)))
+#define __nds32__radd16(a, b) \
+ (__builtin_nds32_radd16 ((a), (b)))
+#define __nds32__v_radd16(a, b) \
+ (__builtin_nds32_v_radd16 ((a), (b)))
+#define __nds32__uradd16(a, b) \
+ (__builtin_nds32_uradd16 ((a), (b)))
+#define __nds32__v_uradd16(a, b) \
+ (__builtin_nds32_v_uradd16 ((a), (b)))
+#define __nds32__kadd16(a, b) \
+ (__builtin_nds32_kadd16 ((a), (b)))
+#define __nds32__v_kadd16(a, b) \
+ (__builtin_nds32_v_kadd16 ((a), (b)))
+#define __nds32__ukadd16(a, b) \
+ (__builtin_nds32_ukadd16 ((a), (b)))
+#define __nds32__v_ukadd16(a, b) \
+ (__builtin_nds32_v_ukadd16 ((a), (b)))
+#define __nds32__sub16(a, b) \
+ (__builtin_nds32_sub16 ((a), (b)))
+#define __nds32__v_usub16(a, b) \
+ (__builtin_nds32_v_usub16 ((a), (b)))
+#define __nds32__v_ssub16(a, b) \
+ (__builtin_nds32_v_ssub16 ((a), (b)))
+#define __nds32__rsub16(a, b) \
+ (__builtin_nds32_rsub16 ((a), (b)))
+#define __nds32__v_rsub16(a, b) \
+ (__builtin_nds32_v_rsub16 ((a), (b)))
+#define __nds32__ursub16(a, b) \
+ (__builtin_nds32_ursub16 ((a), (b)))
+#define __nds32__v_ursub16(a, b) \
+ (__builtin_nds32_v_ursub16 ((a), (b)))
+#define __nds32__ksub16(a, b) \
+ (__builtin_nds32_ksub16 ((a), (b)))
+#define __nds32__v_ksub16(a, b) \
+ (__builtin_nds32_v_ksub16 ((a), (b)))
+#define __nds32__uksub16(a, b) \
+ (__builtin_nds32_uksub16 ((a), (b)))
+#define __nds32__v_uksub16(a, b) \
+ (__builtin_nds32_v_uksub16 ((a), (b)))
+#define __nds32__cras16(a, b) \
+ (__builtin_nds32_cras16 ((a), (b)))
+#define __nds32__v_ucras16(a, b) \
+ (__builtin_nds32_v_ucras16 ((a), (b)))
+#define __nds32__v_scras16(a, b) \
+ (__builtin_nds32_v_scras16 ((a), (b)))
+#define __nds32__rcras16(a, b) \
+ (__builtin_nds32_rcras16 ((a), (b)))
+#define __nds32__v_rcras16(a, b) \
+ (__builtin_nds32_v_rcras16 ((a), (b)))
+#define __nds32__urcras16(a, b) \
+ (__builtin_nds32_urcras16 ((a), (b)))
+#define __nds32__v_urcras16(a, b) \
+ (__builtin_nds32_v_urcras16 ((a), (b)))
+#define __nds32__kcras16(a, b) \
+ (__builtin_nds32_kcras16 ((a), (b)))
+#define __nds32__v_kcras16(a, b) \
+ (__builtin_nds32_v_kcras16 ((a), (b)))
+#define __nds32__ukcras16(a, b) \
+ (__builtin_nds32_ukcras16 ((a), (b)))
+#define __nds32__v_ukcras16(a, b) \
+ (__builtin_nds32_v_ukcras16 ((a), (b)))
+#define __nds32__crsa16(a, b) \
+ (__builtin_nds32_crsa16 ((a), (b)))
+#define __nds32__v_ucrsa16(a, b) \
+ (__builtin_nds32_v_ucrsa16 ((a), (b)))
+#define __nds32__v_scrsa16(a, b) \
+ (__builtin_nds32_v_scrsa16 ((a), (b)))
+#define __nds32__rcrsa16(a, b) \
+ (__builtin_nds32_rcrsa16 ((a), (b)))
+#define __nds32__v_rcrsa16(a, b) \
+ (__builtin_nds32_v_rcrsa16 ((a), (b)))
+#define __nds32__urcrsa16(a, b) \
+ (__builtin_nds32_urcrsa16 ((a), (b)))
+#define __nds32__v_urcrsa16(a, b) \
+ (__builtin_nds32_v_urcrsa16 ((a), (b)))
+#define __nds32__kcrsa16(a, b) \
+ (__builtin_nds32_kcrsa16 ((a), (b)))
+#define __nds32__v_kcrsa16(a, b) \
+ (__builtin_nds32_v_kcrsa16 ((a), (b)))
+#define __nds32__ukcrsa16(a, b) \
+ (__builtin_nds32_ukcrsa16 ((a), (b)))
+#define __nds32__v_ukcrsa16(a, b) \
+ (__builtin_nds32_v_ukcrsa16 ((a), (b)))
+
+#define __nds32__add8(a, b) \
+ (__builtin_nds32_add8 ((a), (b)))
+#define __nds32__v_uadd8(a, b) \
+ (__builtin_nds32_v_uadd8 ((a), (b)))
+#define __nds32__v_sadd8(a, b) \
+ (__builtin_nds32_v_sadd8 ((a), (b)))
+#define __nds32__radd8(a, b) \
+ (__builtin_nds32_radd8 ((a), (b)))
+#define __nds32__v_radd8(a, b) \
+ (__builtin_nds32_v_radd8 ((a), (b)))
+#define __nds32__uradd8(a, b) \
+ (__builtin_nds32_uradd8 ((a), (b)))
+#define __nds32__v_uradd8(a, b) \
+ (__builtin_nds32_v_uradd8 ((a), (b)))
+#define __nds32__kadd8(a, b) \
+ (__builtin_nds32_kadd8 ((a), (b)))
+#define __nds32__v_kadd8(a, b) \
+ (__builtin_nds32_v_kadd8 ((a), (b)))
+#define __nds32__ukadd8(a, b) \
+ (__builtin_nds32_ukadd8 ((a), (b)))
+#define __nds32__v_ukadd8(a, b) \
+ (__builtin_nds32_v_ukadd8 ((a), (b)))
+#define __nds32__sub8(a, b) \
+ (__builtin_nds32_sub8 ((a), (b)))
+#define __nds32__v_usub8(a, b) \
+ (__builtin_nds32_v_usub8 ((a), (b)))
+#define __nds32__v_ssub8(a, b) \
+ (__builtin_nds32_v_ssub8 ((a), (b)))
+#define __nds32__rsub8(a, b) \
+ (__builtin_nds32_rsub8 ((a), (b)))
+#define __nds32__v_rsub8(a, b) \
+ (__builtin_nds32_v_rsub8 ((a), (b)))
+#define __nds32__ursub8(a, b) \
+ (__builtin_nds32_ursub8 ((a), (b)))
+#define __nds32__v_ursub8(a, b) \
+ (__builtin_nds32_v_ursub8 ((a), (b)))
+#define __nds32__ksub8(a, b) \
+ (__builtin_nds32_ksub8 ((a), (b)))
+#define __nds32__v_ksub8(a, b) \
+ (__builtin_nds32_v_ksub8 ((a), (b)))
+#define __nds32__uksub8(a, b) \
+ (__builtin_nds32_uksub8 ((a), (b)))
+#define __nds32__v_uksub8(a, b) \
+ (__builtin_nds32_v_uksub8 ((a), (b)))
+
+#define __nds32__sra16(a, b) \
+ (__builtin_nds32_sra16 ((a), (b)))
+#define __nds32__v_sra16(a, b) \
+ (__builtin_nds32_v_sra16 ((a), (b)))
+#define __nds32__sra16_u(a, b) \
+ (__builtin_nds32_sra16_u ((a), (b)))
+#define __nds32__v_sra16_u(a, b) \
+ (__builtin_nds32_v_sra16_u ((a), (b)))
+#define __nds32__srl16(a, b) \
+ (__builtin_nds32_srl16 ((a), (b)))
+#define __nds32__v_srl16(a, b) \
+ (__builtin_nds32_v_srl16 ((a), (b)))
+#define __nds32__srl16_u(a, b) \
+ (__builtin_nds32_srl16_u ((a), (b)))
+#define __nds32__v_srl16_u(a, b) \
+ (__builtin_nds32_v_srl16_u ((a), (b)))
+#define __nds32__sll16(a, b) \
+ (__builtin_nds32_sll16 ((a), (b)))
+#define __nds32__v_sll16(a, b) \
+ (__builtin_nds32_v_sll16 ((a), (b)))
+#define __nds32__ksll16(a, b) \
+ (__builtin_nds32_ksll16 ((a), (b)))
+#define __nds32__v_ksll16(a, b) \
+ (__builtin_nds32_v_ksll16 ((a), (b)))
+#define __nds32__kslra16(a, b) \
+ (__builtin_nds32_kslra16 ((a), (b)))
+#define __nds32__v_kslra16(a, b) \
+ (__builtin_nds32_v_kslra16 ((a), (b)))
+#define __nds32__kslra16_u(a, b) \
+ (__builtin_nds32_kslra16_u ((a), (b)))
+#define __nds32__v_kslra16_u(a, b) \
+ (__builtin_nds32_v_kslra16_u ((a), (b)))
+
+#define __nds32__cmpeq16(a, b) \
+ (__builtin_nds32_cmpeq16 ((a), (b)))
+#define __nds32__v_scmpeq16(a, b) \
+ (__builtin_nds32_v_scmpeq16 ((a), (b)))
+#define __nds32__v_ucmpeq16(a, b) \
+ (__builtin_nds32_v_ucmpeq16 ((a), (b)))
+#define __nds32__scmplt16(a, b) \
+ (__builtin_nds32_scmplt16 ((a), (b)))
+#define __nds32__v_scmplt16(a, b) \
+ (__builtin_nds32_v_scmplt16 ((a), (b)))
+#define __nds32__scmple16(a, b) \
+ (__builtin_nds32_scmple16 ((a), (b)))
+#define __nds32__v_scmple16(a, b) \
+ (__builtin_nds32_v_scmple16 ((a), (b)))
+#define __nds32__ucmplt16(a, b) \
+ (__builtin_nds32_ucmplt16 ((a), (b)))
+#define __nds32__v_ucmplt16(a, b) \
+ (__builtin_nds32_v_ucmplt16 ((a), (b)))
+#define __nds32__ucmple16(a, b) \
+ (__builtin_nds32_ucmple16 ((a), (b)))
+#define __nds32__v_ucmple16(a, b) \
+ (__builtin_nds32_v_ucmple16 ((a), (b)))
+
+#define __nds32__cmpeq8(a, b) \
+ (__builtin_nds32_cmpeq8 ((a), (b)))
+#define __nds32__v_scmpeq8(a, b) \
+ (__builtin_nds32_v_scmpeq8 ((a), (b)))
+#define __nds32__v_ucmpeq8(a, b) \
+ (__builtin_nds32_v_ucmpeq8 ((a), (b)))
+#define __nds32__scmplt8(a, b) \
+ (__builtin_nds32_scmplt8 ((a), (b)))
+#define __nds32__v_scmplt8(a, b) \
+ (__builtin_nds32_v_scmplt8 ((a), (b)))
+#define __nds32__scmple8(a, b) \
+ (__builtin_nds32_scmple8 ((a), (b)))
+#define __nds32__v_scmple8(a, b) \
+ (__builtin_nds32_v_scmple8 ((a), (b)))
+#define __nds32__ucmplt8(a, b) \
+ (__builtin_nds32_ucmplt8 ((a), (b)))
+#define __nds32__v_ucmplt8(a, b) \
+ (__builtin_nds32_v_ucmplt8 ((a), (b)))
+#define __nds32__ucmple8(a, b) \
+ (__builtin_nds32_ucmple8 ((a), (b)))
+#define __nds32__v_ucmple8(a, b) \
+ (__builtin_nds32_v_ucmple8 ((a), (b)))
+
+#define __nds32__smin16(a, b) \
+ (__builtin_nds32_smin16 ((a), (b)))
+#define __nds32__v_smin16(a, b) \
+ (__builtin_nds32_v_smin16 ((a), (b)))
+#define __nds32__umin16(a, b) \
+ (__builtin_nds32_umin16 ((a), (b)))
+#define __nds32__v_umin16(a, b) \
+ (__builtin_nds32_v_umin16 ((a), (b)))
+#define __nds32__smax16(a, b) \
+ (__builtin_nds32_smax16 ((a), (b)))
+#define __nds32__v_smax16(a, b) \
+ (__builtin_nds32_v_smax16 ((a), (b)))
+#define __nds32__umax16(a, b) \
+ (__builtin_nds32_umax16 ((a), (b)))
+#define __nds32__v_umax16(a, b) \
+ (__builtin_nds32_v_umax16 ((a), (b)))
+#define __nds32__sclip16(a, b) \
+ (__builtin_nds32_sclip16 ((a), (b)))
+#define __nds32__v_sclip16(a, b) \
+ (__builtin_nds32_v_sclip16 ((a), (b)))
+#define __nds32__uclip16(a, b) \
+ (__builtin_nds32_uclip16 ((a), (b)))
+#define __nds32__v_uclip16(a, b) \
+ (__builtin_nds32_v_uclip16 ((a), (b)))
+#define __nds32__khm16(a, b) \
+ (__builtin_nds32_khm16 ((a), (b)))
+#define __nds32__v_khm16(a, b) \
+ (__builtin_nds32_v_khm16 ((a), (b)))
+#define __nds32__khmx16(a, b) \
+ (__builtin_nds32_khmx16 ((a), (b)))
+#define __nds32__v_khmx16(a, b) \
+ (__builtin_nds32_v_khmx16 ((a), (b)))
+#define __nds32__kabs16(a) \
+ (__builtin_nds32_kabs16 ((a)))
+#define __nds32__v_kabs16(a) \
+ (__builtin_nds32_v_kabs16 ((a)))
+
+#define __nds32__smin8(a, b) \
+ (__builtin_nds32_smin8 ((a), (b)))
+#define __nds32__v_smin8(a, b) \
+ (__builtin_nds32_v_smin8 ((a), (b)))
+#define __nds32__umin8(a, b) \
+ (__builtin_nds32_umin8 ((a), (b)))
+#define __nds32__v_umin8(a, b) \
+ (__builtin_nds32_v_umin8 ((a), (b)))
+#define __nds32__smax8(a, b) \
+ (__builtin_nds32_smax8 ((a), (b)))
+#define __nds32__v_smax8(a, b) \
+ (__builtin_nds32_v_smax8 ((a), (b)))
+#define __nds32__umax8(a, b) \
+ (__builtin_nds32_umax8 ((a), (b)))
+#define __nds32__v_umax8(a, b) \
+ (__builtin_nds32_v_umax8 ((a), (b)))
+#define __nds32__kabs8(a) \
+ (__builtin_nds32_kabs8 ((a)))
+#define __nds32__v_kabs8(a) \
+ (__builtin_nds32_v_kabs8 ((a)))
+
+#define __nds32__sunpkd810(a) \
+ (__builtin_nds32_sunpkd810 ((a)))
+#define __nds32__v_sunpkd810(a) \
+ (__builtin_nds32_v_sunpkd810 ((a)))
+#define __nds32__sunpkd820(a) \
+ (__builtin_nds32_sunpkd820 ((a)))
+#define __nds32__v_sunpkd820(a) \
+ (__builtin_nds32_v_sunpkd820 ((a)))
+#define __nds32__sunpkd830(a) \
+ (__builtin_nds32_sunpkd830 ((a)))
+#define __nds32__v_sunpkd830(a) \
+ (__builtin_nds32_v_sunpkd830 ((a)))
+#define __nds32__sunpkd831(a) \
+ (__builtin_nds32_sunpkd831 ((a)))
+#define __nds32__v_sunpkd831(a) \
+ (__builtin_nds32_v_sunpkd831 ((a)))
+#define __nds32__zunpkd810(a) \
+ (__builtin_nds32_zunpkd810 ((a)))
+#define __nds32__v_zunpkd810(a) \
+ (__builtin_nds32_v_zunpkd810 ((a)))
+#define __nds32__zunpkd820(a) \
+ (__builtin_nds32_zunpkd820 ((a)))
+#define __nds32__v_zunpkd820(a) \
+ (__builtin_nds32_v_zunpkd820 ((a)))
+#define __nds32__zunpkd830(a) \
+ (__builtin_nds32_zunpkd830 ((a)))
+#define __nds32__v_zunpkd830(a) \
+ (__builtin_nds32_v_zunpkd830 ((a)))
+#define __nds32__zunpkd831(a) \
+ (__builtin_nds32_zunpkd831 ((a)))
+#define __nds32__v_zunpkd831(a) \
+ (__builtin_nds32_v_zunpkd831 ((a)))
+
+#define __nds32__raddw(a, b) \
+ (__builtin_nds32_raddw ((a), (b)))
+#define __nds32__uraddw(a, b) \
+ (__builtin_nds32_uraddw ((a), (b)))
+#define __nds32__rsubw(a, b) \
+ (__builtin_nds32_rsubw ((a), (b)))
+#define __nds32__ursubw(a, b) \
+ (__builtin_nds32_ursubw ((a), (b)))
+
+#define __nds32__sra_u(a, b) \
+ (__builtin_nds32_sra_u ((a), (b)))
+#define __nds32__ksll(a, b) \
+ (__builtin_nds32_ksll ((a), (b)))
+#define __nds32__pkbb16(a, b) \
+ (__builtin_nds32_pkbb16 ((a), (b)))
+#define __nds32__v_pkbb16(a, b) \
+ (__builtin_nds32_v_pkbb16 ((a), (b)))
+#define __nds32__pkbt16(a, b) \
+ (__builtin_nds32_pkbt16 ((a), (b)))
+#define __nds32__v_pkbt16(a, b) \
+ (__builtin_nds32_v_pkbt16 ((a), (b)))
+#define __nds32__pktb16(a, b) \
+ (__builtin_nds32_pktb16 ((a), (b)))
+#define __nds32__v_pktb16(a, b) \
+ (__builtin_nds32_v_pktb16 ((a), (b)))
+#define __nds32__pktt16(a, b) \
+ (__builtin_nds32_pktt16 ((a), (b)))
+#define __nds32__v_pktt16(a, b) \
+ (__builtin_nds32_v_pktt16 ((a), (b)))
+
+#define __nds32__smmul(a, b) \
+ (__builtin_nds32_smmul ((a), (b)))
+#define __nds32__smmul_u(a, b) \
+ (__builtin_nds32_smmul_u ((a), (b)))
+#define __nds32__kmmac(r, a, b) \
+ (__builtin_nds32_kmmac ((r), (a), (b)))
+#define __nds32__kmmac_u(r, a, b) \
+ (__builtin_nds32_kmmac_u ((r), (a), (b)))
+#define __nds32__kmmsb(r, a, b) \
+ (__builtin_nds32_kmmsb ((r), (a), (b)))
+#define __nds32__kmmsb_u(r, a, b) \
+ (__builtin_nds32_kmmsb_u ((r), (a), (b)))
+#define __nds32__kwmmul(a, b) \
+ (__builtin_nds32_kwmmul ((a), (b)))
+#define __nds32__kwmmul_u(a, b) \
+ (__builtin_nds32_kwmmul_u ((a), (b)))
+
+#define __nds32__smmwb(a, b) \
+ (__builtin_nds32_smmwb ((a), (b)))
+#define __nds32__v_smmwb(a, b) \
+ (__builtin_nds32_v_smmwb ((a), (b)))
+#define __nds32__smmwb_u(a, b) \
+ (__builtin_nds32_smmwb_u ((a), (b)))
+#define __nds32__v_smmwb_u(a, b) \
+ (__builtin_nds32_v_smmwb_u ((a), (b)))
+#define __nds32__smmwt(a, b) \
+ (__builtin_nds32_smmwt ((a), (b)))
+#define __nds32__v_smmwt(a, b) \
+ (__builtin_nds32_v_smmwt ((a), (b)))
+#define __nds32__smmwt_u(a, b) \
+ (__builtin_nds32_smmwt_u ((a), (b)))
+#define __nds32__v_smmwt_u(a, b) \
+ (__builtin_nds32_v_smmwt_u ((a), (b)))
+#define __nds32__kmmawb(r, a, b) \
+ (__builtin_nds32_kmmawb ((r), (a), (b)))
+#define __nds32__v_kmmawb(r, a, b) \
+ (__builtin_nds32_v_kmmawb ((r), (a), (b)))
+#define __nds32__kmmawb_u(r, a, b) \
+ (__builtin_nds32_kmmawb_u ((r), (a), (b)))
+#define __nds32__v_kmmawb_u(r, a, b) \
+ (__builtin_nds32_v_kmmawb_u ((r), (a), (b)))
+#define __nds32__kmmawt(r, a, b) \
+ (__builtin_nds32_kmmawt ((r), (a), (b)))
+#define __nds32__v_kmmawt(r, a, b) \
+ (__builtin_nds32_v_kmmawt ((r), (a), (b)))
+#define __nds32__kmmawt_u(r, a, b) \
+ (__builtin_nds32_kmmawt_u ((r), (a), (b)))
+#define __nds32__v_kmmawt_u(r, a, b) \
+ (__builtin_nds32_v_kmmawt_u ((r), (a), (b)))
+
+#define __nds32__smbb(a, b) \
+ (__builtin_nds32_smbb ((a), (b)))
+#define __nds32__v_smbb(a, b) \
+ (__builtin_nds32_v_smbb ((a), (b)))
+#define __nds32__smbt(a, b) \
+ (__builtin_nds32_smbt ((a), (b)))
+#define __nds32__v_smbt(a, b) \
+ (__builtin_nds32_v_smbt ((a), (b)))
+#define __nds32__smtt(a, b) \
+ (__builtin_nds32_smtt ((a), (b)))
+#define __nds32__v_smtt(a, b) \
+ (__builtin_nds32_v_smtt ((a), (b)))
+#define __nds32__kmda(a, b) \
+ (__builtin_nds32_kmda ((a), (b)))
+#define __nds32__v_kmda(a, b) \
+ (__builtin_nds32_v_kmda ((a), (b)))
+#define __nds32__kmxda(a, b) \
+ (__builtin_nds32_kmxda ((a), (b)))
+#define __nds32__v_kmxda(a, b) \
+ (__builtin_nds32_v_kmxda ((a), (b)))
+#define __nds32__smds(a, b) \
+ (__builtin_nds32_smds ((a), (b)))
+#define __nds32__v_smds(a, b) \
+ (__builtin_nds32_v_smds ((a), (b)))
+#define __nds32__smdrs(a, b) \
+ (__builtin_nds32_smdrs ((a), (b)))
+#define __nds32__v_smdrs(a, b) \
+ (__builtin_nds32_v_smdrs ((a), (b)))
+#define __nds32__smxds(a, b) \
+ (__builtin_nds32_smxds ((a), (b)))
+#define __nds32__v_smxds(a, b) \
+ (__builtin_nds32_v_smxds ((a), (b)))
+#define __nds32__kmabb(r, a, b) \
+ (__builtin_nds32_kmabb ((r), (a), (b)))
+#define __nds32__v_kmabb(r, a, b) \
+ (__builtin_nds32_v_kmabb ((r), (a), (b)))
+#define __nds32__kmabt(r, a, b) \
+ (__builtin_nds32_kmabt ((r), (a), (b)))
+#define __nds32__v_kmabt(r, a, b) \
+ (__builtin_nds32_v_kmabt ((r), (a), (b)))
+#define __nds32__kmatt(r, a, b) \
+ (__builtin_nds32_kmatt ((r), (a), (b)))
+#define __nds32__v_kmatt(r, a, b) \
+ (__builtin_nds32_v_kmatt ((r), (a), (b)))
+#define __nds32__kmada(r, a, b) \
+ (__builtin_nds32_kmada ((r), (a), (b)))
+#define __nds32__v_kmada(r, a, b) \
+ (__builtin_nds32_v_kmada ((r), (a), (b)))
+#define __nds32__kmaxda(r, a, b) \
+ (__builtin_nds32_kmaxda ((r), (a), (b)))
+#define __nds32__v_kmaxda(r, a, b) \
+ (__builtin_nds32_v_kmaxda ((r), (a), (b)))
+#define __nds32__kmads(r, a, b) \
+ (__builtin_nds32_kmads ((r), (a), (b)))
+#define __nds32__v_kmads(r, a, b) \
+ (__builtin_nds32_v_kmads ((r), (a), (b)))
+#define __nds32__kmadrs(r, a, b) \
+ (__builtin_nds32_kmadrs ((r), (a), (b)))
+#define __nds32__v_kmadrs(r, a, b) \
+ (__builtin_nds32_v_kmadrs ((r), (a), (b)))
+#define __nds32__kmaxds(r, a, b) \
+ (__builtin_nds32_kmaxds ((r), (a), (b)))
+#define __nds32__v_kmaxds(r, a, b) \
+ (__builtin_nds32_v_kmaxds ((r), (a), (b)))
+#define __nds32__kmsda(r, a, b) \
+ (__builtin_nds32_kmsda ((r), (a), (b)))
+#define __nds32__v_kmsda(r, a, b) \
+ (__builtin_nds32_v_kmsda ((r), (a), (b)))
+#define __nds32__kmsxda(r, a, b) \
+ (__builtin_nds32_kmsxda ((r), (a), (b)))
+#define __nds32__v_kmsxda(r, a, b) \
+ (__builtin_nds32_v_kmsxda ((r), (a), (b)))
+
+#define __nds32__smal(a, b) \
+ (__builtin_nds32_smal ((a), (b)))
+#define __nds32__v_smal(a, b) \
+ (__builtin_nds32_v_smal ((a), (b)))
+
+#define __nds32__bitrev(a, b) \
+ (__builtin_nds32_bitrev ((a), (b)))
+#define __nds32__wext(a, b) \
+ (__builtin_nds32_wext ((a), (b)))
+#define __nds32__bpick(r, a, b) \
+ (__builtin_nds32_bpick ((r), (a), (b)))
+#define __nds32__insb(r, a, b) \
+ (__builtin_nds32_insb ((r), (a), (b)))
+
+#define __nds32__sadd64(a, b) \
+ (__builtin_nds32_sadd64 ((a), (b)))
+#define __nds32__uadd64(a, b) \
+ (__builtin_nds32_uadd64 ((a), (b)))
+#define __nds32__radd64(a, b) \
+ (__builtin_nds32_radd64 ((a), (b)))
+#define __nds32__uradd64(a, b) \
+ (__builtin_nds32_uradd64 ((a), (b)))
+#define __nds32__kadd64(a, b) \
+ (__builtin_nds32_kadd64 ((a), (b)))
+#define __nds32__ukadd64(a, b) \
+ (__builtin_nds32_ukadd64 ((a), (b)))
+#define __nds32__ssub64(a, b) \
+ (__builtin_nds32_ssub64 ((a), (b)))
+#define __nds32__usub64(a, b) \
+ (__builtin_nds32_usub64 ((a), (b)))
+#define __nds32__rsub64(a, b) \
+ (__builtin_nds32_rsub64 ((a), (b)))
+#define __nds32__ursub64(a, b) \
+ (__builtin_nds32_ursub64 ((a), (b)))
+#define __nds32__ksub64(a, b) \
+ (__builtin_nds32_ksub64 ((a), (b)))
+#define __nds32__uksub64(a, b) \
+ (__builtin_nds32_uksub64 ((a), (b)))
+
+#define __nds32__smar64(r, a, b) \
+ (__builtin_nds32_smar64 ((r), (a), (b)))
+#define __nds32__smsr64(r, a, b) \
+ (__builtin_nds32_smsr64 ((r), (a), (b)))
+#define __nds32__umar64(r, a, b) \
+ (__builtin_nds32_umar64 ((r), (a), (b)))
+#define __nds32__umsr64(r, a, b) \
+ (__builtin_nds32_umsr64 ((r), (a), (b)))
+#define __nds32__kmar64(r, a, b) \
+ (__builtin_nds32_kmar64 ((r), (a), (b)))
+#define __nds32__kmsr64(r, a, b) \
+ (__builtin_nds32_kmsr64 ((r), (a), (b)))
+#define __nds32__ukmar64(r, a, b) \
+ (__builtin_nds32_ukmar64 ((r), (a), (b)))
+#define __nds32__ukmsr64(r, a, b) \
+ (__builtin_nds32_ukmsr64 ((r), (a), (b)))
+
+#define __nds32__smalbb(r, a, b) \
+ (__builtin_nds32_smalbb ((r), (a), (b)))
+#define __nds32__v_smalbb(r, a, b) \
+ (__builtin_nds32_v_smalbb ((r), (a), (b)))
+#define __nds32__smalbt(r, a, b) \
+ (__builtin_nds32_smalbt ((r), (a), (b)))
+#define __nds32__v_smalbt(r, a, b) \
+ (__builtin_nds32_v_smalbt ((r), (a), (b)))
+#define __nds32__smaltt(r, a, b) \
+ (__builtin_nds32_smaltt ((r), (a), (b)))
+#define __nds32__v_smaltt(r, a, b) \
+ (__builtin_nds32_v_smaltt ((r), (a), (b)))
+#define __nds32__smalda(r, a, b) \
+ (__builtin_nds32_smalda ((r), (a), (b)))
+#define __nds32__v_smalda(r, a, b) \
+ (__builtin_nds32_v_smalda ((r), (a), (b)))
+#define __nds32__smalxda(r, a, b) \
+ (__builtin_nds32_smalxda ((r), (a), (b)))
+#define __nds32__v_smalxda(r, a, b) \
+ (__builtin_nds32_v_smalxda ((r), (a), (b)))
+#define __nds32__smalds(r, a, b) \
+ (__builtin_nds32_smalds ((r), (a), (b)))
+#define __nds32__v_smalds(r, a, b) \
+ (__builtin_nds32_v_smalds ((r), (a), (b)))
+#define __nds32__smaldrs(r, a, b) \
+ (__builtin_nds32_smaldrs ((r), (a), (b)))
+#define __nds32__v_smaldrs(r, a, b) \
+ (__builtin_nds32_v_smaldrs ((r), (a), (b)))
+#define __nds32__smalxds(r, a, b) \
+ (__builtin_nds32_smalxds ((r), (a), (b)))
+#define __nds32__v_smalxds(r, a, b) \
+ (__builtin_nds32_v_smalxds ((r), (a), (b)))
+#define __nds32__smslda(r, a, b) \
+ (__builtin_nds32_smslda ((r), (a), (b)))
+#define __nds32__v_smslda(r, a, b) \
+ (__builtin_nds32_v_smslda ((r), (a), (b)))
+#define __nds32__smslxda(r, a, b) \
+ (__builtin_nds32_smslxda ((r), (a), (b)))
+#define __nds32__v_smslxda(r, a, b) \
+ (__builtin_nds32_v_smslxda ((r), (a), (b)))
+
+#define __nds32__smul16(a, b) \
+ (__builtin_nds32_smul16 ((a), (b)))
+#define __nds32__v_smul16(a, b) \
+ (__builtin_nds32_v_smul16 ((a), (b)))
+#define __nds32__smulx16(a, b) \
+ (__builtin_nds32_smulx16 ((a), (b)))
+#define __nds32__v_smulx16(a, b) \
+ (__builtin_nds32_v_smulx16 ((a), (b)))
+#define __nds32__umul16(a, b) \
+ (__builtin_nds32_umul16 ((a), (b)))
+#define __nds32__v_umul16(a, b) \
+ (__builtin_nds32_v_umul16 ((a), (b)))
+#define __nds32__umulx16(a, b) \
+ (__builtin_nds32_umulx16 ((a), (b)))
+#define __nds32__v_umulx16(a, b) \
+ (__builtin_nds32_v_umulx16 ((a), (b)))
+
+#define __nds32__uclip32(a, imm) \
+ (__builtin_nds32_uclip32 ((a), (imm)))
+#define __nds32__sclip32(a, imm) \
+ (__builtin_nds32_sclip32 ((a), (imm)))
+#define __nds32__kabs(a) \
+ (__builtin_nds32_kabs ((a)))
+
#define __nds32__unaligned_feature() \
(__builtin_nds32_unaligned_feature())
#define __nds32__enable_unaligned() \
(__builtin_nds32_enable_unaligned())
#define __nds32__disable_unaligned() \
(__builtin_nds32_disable_unaligned())
+
+#define __nds32__get_unaligned_u16x2(a) \
+ (__builtin_nds32_get_unaligned_u16x2 ((a)))
+#define __nds32__get_unaligned_s16x2(a) \
+ (__builtin_nds32_get_unaligned_s16x2 ((a)))
+#define __nds32__get_unaligned_u8x4(a) \
+ (__builtin_nds32_get_unaligned_u8x4 ((a)))
+#define __nds32__get_unaligned_s8x4(a) \
+ (__builtin_nds32_get_unaligned_s8x4 ((a)))
+
+#define __nds32__put_unaligned_u16x2(a, data) \
+ (__builtin_nds32_put_unaligned_u16x2 ((a), (data)))
+#define __nds32__put_unaligned_s16x2(a, data) \
+ (__builtin_nds32_put_unaligned_s16x2 ((a), (data)))
+#define __nds32__put_unaligned_u8x4(a, data) \
+ (__builtin_nds32_put_unaligned_u8x4 ((a), (data)))
+#define __nds32__put_unaligned_s8x4(a, data) \
+ (__builtin_nds32_put_unaligned_s8x4 ((a), (data)))
+
+#define NDS32ATTR_SIGNATURE __attribute__((signature))
+
#endif /* nds32_intrinsic.h */
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-intrinsic.md gcc-8.2.0/gcc/config/nds32/nds32-intrinsic.md
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-intrinsic.md 2018-04-22 09:46:39.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-intrinsic.md 2019-01-25 15:38:32.825242648 +0100
@@ -1037,6 +1037,187 @@
(set_attr "length" "4")]
)
+;; SATURATION
+
+(define_insn "unspec_kaddw"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "kaddw\t%0, %1, %2"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_ksubw"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_minus:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "ksubw\t%0, %1, %2"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_kaddh"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_KADDH))]
+ ""
+ "kaddh\t%0, %1, %2"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_ksubh"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSUBH))]
+ ""
+ "ksubh\t%0, %1, %2"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_kaddh_dsp"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r"))
+ (const_int 15)] UNSPEC_CLIPS))]
+ "NDS32_EXT_DSP_P ()"
+ "kaddh\t%0, %1, %2"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_ksubh_dsp"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(minus:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r"))
+ (const_int 15)] UNSPEC_CLIPS))]
+ "NDS32_EXT_DSP_P ()"
+ "ksubh\t%0, %1, %2"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_kdmbb"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBB))]
+ ""
+ "kdmbb\t%0, %1, %2"
+ [(set_attr "type" "mul")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_kdmbt"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBT))]
+ ""
+ "kdmbt\t%0, %1, %2"
+ [(set_attr "type" "mul")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_kdmtb"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTB))]
+ ""
+ "kdmtb\t%0, %1, %2"
+ [(set_attr "type" "mul")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_kdmtt"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTT))]
+ ""
+ "kdmtt\t%0, %1, %2"
+ [(set_attr "type" "mul")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_khmbb"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBB))]
+ ""
+ "khmbb\t%0, %1, %2"
+ [(set_attr "type" "mul")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_khmbt"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBT))]
+ ""
+ "khmbt\t%0, %1, %2"
+ [(set_attr "type" "mul")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_khmtb"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTB))]
+ ""
+ "khmtb\t%0, %1, %2"
+ [(set_attr "type" "mul")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_khmtt"
+ [(set (match_operand:V2HI 0 "register_operand" "=r")
+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTT))]
+ ""
+ "khmtt\t%0, %1, %2"
+ [(set_attr "type" "mul")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_kslraw"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSLRAW))]
+ ""
+ "kslraw\t%0, %1, %2"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_kslrawu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSLRAWU))]
+ ""
+ "kslraw.u\t%0, %1, %2"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_volatile_rdov"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_RDOV))]
+ ""
+ "rdov\t%0"
+ [(set_attr "type" "misc")
+ (set_attr "length" "4")]
+)
+
+(define_insn "unspec_volatile_clrov"
+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLROV)]
+ ""
+ "clrov"
+ [(set_attr "type" "misc")
+ (set_attr "length" "4")]
+)
+
;; System
(define_insn "unspec_sva"
@@ -1415,22 +1596,17 @@
if (TARGET_ISA_V3M)
nds32_expand_unaligned_store (operands, DImode);
else
- emit_insn (gen_unaligned_store_dw (operands[0], operands[1]));
+ emit_insn (gen_unaligned_store_dw (gen_rtx_MEM (DImode, operands[0]),
+ operands[1]));
DONE;
})
(define_insn "unaligned_store_dw"
- [(set (mem:DI (match_operand:SI 0 "register_operand" "r"))
- (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_UASTORE_DW))]
+ [(set (match_operand:DI 0 "nds32_lmw_smw_base_operand" "=Umw")
+ (unspec:DI [(match_operand:DI 1 "register_operand" " r")] UNSPEC_UASTORE_DW))]
""
{
- rtx otherops[3];
- otherops[0] = gen_rtx_REG (SImode, REGNO (operands[1]));
- otherops[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
- otherops[2] = operands[0];
-
- output_asm_insn ("smw.bi\t%0, [%2], %1, 0", otherops);
- return "";
+ return nds32_output_smw_double_word (operands);
}
[(set_attr "type" "store")
(set_attr "length" "4")]
@@ -1495,4 +1671,15 @@
DONE;
})
+;; abs alias kabs
+
+(define_insn "unspec_kabs"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_KABS))]
+ ""
+ "kabs\t%0, %1"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
;; ------------------------------------------------------------------------
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-isr.c gcc-8.2.0/gcc/config/nds32/nds32-isr.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-isr.c 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-isr.c 2019-01-25 15:38:32.829242659 +0100
@@ -43,7 +43,260 @@
We use an array to record essential information for each vector. */
static struct nds32_isr_info nds32_isr_vectors[NDS32_N_ISR_VECTORS];
-/* ------------------------------------------------------------------------ */
+/* ------------------------------------------------------------- */
+/* FIXME:
+ FOR BACKWARD COMPATIBILITY, we need to support following patterns:
+
+ __attribute__((interrupt("XXX;YYY;id=ZZZ")))
+ __attribute__((exception("XXX;YYY;id=ZZZ")))
+ __attribute__((reset("vectors=XXX;nmi_func=YYY;warm_func=ZZZ")))
+
+ We provide several functions to parse the strings. */
+
+static void
+nds32_interrupt_attribute_parse_string (const char *original_str,
+ const char *func_name,
+ unsigned int s_level)
+{
+ char target_str[100];
+ enum nds32_isr_save_reg save_reg;
+ enum nds32_isr_nested_type nested_type;
+
+ char *save_all_regs_str, *save_caller_regs_str;
+ char *nested_str, *not_nested_str, *ready_nested_str, *critical_str;
+ char *id_str, *value_str;
+
+ /* Copy original string into a character array so that
+ the string APIs can handle it. */
+ strcpy (target_str, original_str);
+
+ /* 1. Detect 'save_all_regs' : NDS32_SAVE_ALL
+ 'save_caller_regs' : NDS32_PARTIAL_SAVE */
+ save_all_regs_str = strstr (target_str, "save_all_regs");
+ save_caller_regs_str = strstr (target_str, "save_caller_regs");
+
+ /* Note that if no argument is found,
+ use NDS32_PARTIAL_SAVE by default. */
+ if (save_all_regs_str)
+ save_reg = NDS32_SAVE_ALL;
+ else if (save_caller_regs_str)
+ save_reg = NDS32_PARTIAL_SAVE;
+ else
+ save_reg = NDS32_PARTIAL_SAVE;
+
+ /* 2. Detect 'nested' : NDS32_NESTED
+ 'not_nested' : NDS32_NOT_NESTED
+ 'ready_nested' : NDS32_NESTED_READY
+ 'critical' : NDS32_CRITICAL */
+ nested_str = strstr (target_str, "nested");
+ not_nested_str = strstr (target_str, "not_nested");
+ ready_nested_str = strstr (target_str, "ready_nested");
+ critical_str = strstr (target_str, "critical");
+
+ /* Note that if no argument is found,
+ use NDS32_NOT_NESTED by default.
+ Also, since 'not_nested' and 'ready_nested' both contains
+ 'nested' string, we check 'nested' with lowest priority. */
+ if (not_nested_str)
+ nested_type = NDS32_NOT_NESTED;
+ else if (ready_nested_str)
+ nested_type = NDS32_NESTED_READY;
+ else if (nested_str)
+ nested_type = NDS32_NESTED;
+ else if (critical_str)
+ nested_type = NDS32_CRITICAL;
+ else
+ nested_type = NDS32_NOT_NESTED;
+
+ /* 3. Traverse each id value and set corresponding information. */
+ id_str = strstr (target_str, "id=");
+
+ /* If user forgets to assign 'id', issue an error message. */
+ if (id_str == NULL)
+ error ("require id argument in the string");
+ /* Extract the value_str first. */
+ id_str = strtok (id_str, "=");
+ value_str = strtok (NULL, ";");
+
+ /* Pick up the first id value token. */
+ value_str = strtok (value_str, ",");
+ while (value_str != NULL)
+ {
+ int i;
+ i = atoi (value_str);
+
+ /* For interrupt(0..63), the actual vector number is (9..72). */
+ i = i + 9;
+ if (i < 9 || i > 72)
+ error ("invalid id value for interrupt attribute");
+
+ /* Setup nds32_isr_vectors[] array. */
+ nds32_isr_vectors[i].category = NDS32_ISR_INTERRUPT;
+ strcpy (nds32_isr_vectors[i].func_name, func_name);
+ nds32_isr_vectors[i].save_reg = save_reg;
+ nds32_isr_vectors[i].nested_type = nested_type;
+ nds32_isr_vectors[i].security_level = s_level;
+
+ /* Fetch next token. */
+ value_str = strtok (NULL, ",");
+ }
+
+ return;
+}
+
+static void
+nds32_exception_attribute_parse_string (const char *original_str,
+ const char *func_name,
+ unsigned int s_level)
+{
+ char target_str[100];
+ enum nds32_isr_save_reg save_reg;
+ enum nds32_isr_nested_type nested_type;
+
+ char *save_all_regs_str, *save_caller_regs_str;
+ char *nested_str, *not_nested_str, *ready_nested_str, *critical_str;
+ char *id_str, *value_str;
+
+ /* Copy original string into a character array so that
+ the string APIs can handle it. */
+ strcpy (target_str, original_str);
+
+ /* 1. Detect 'save_all_regs' : NDS32_SAVE_ALL
+ 'save_caller_regs' : NDS32_PARTIAL_SAVE */
+ save_all_regs_str = strstr (target_str, "save_all_regs");
+ save_caller_regs_str = strstr (target_str, "save_caller_regs");
+
+ /* Note that if no argument is found,
+ use NDS32_PARTIAL_SAVE by default. */
+ if (save_all_regs_str)
+ save_reg = NDS32_SAVE_ALL;
+ else if (save_caller_regs_str)
+ save_reg = NDS32_PARTIAL_SAVE;
+ else
+ save_reg = NDS32_PARTIAL_SAVE;
+
+ /* 2. Detect 'nested' : NDS32_NESTED
+ 'not_nested' : NDS32_NOT_NESTED
+ 'ready_nested' : NDS32_NESTED_READY
+ 'critical' : NDS32_CRITICAL */
+ nested_str = strstr (target_str, "nested");
+ not_nested_str = strstr (target_str, "not_nested");
+ ready_nested_str = strstr (target_str, "ready_nested");
+ critical_str = strstr (target_str, "critical");
+
+ /* Note that if no argument is found,
+ use NDS32_NOT_NESTED by default.
+ Also, since 'not_nested' and 'ready_nested' both contains
+ 'nested' string, we check 'nested' with lowest priority. */
+ if (not_nested_str)
+ nested_type = NDS32_NOT_NESTED;
+ else if (ready_nested_str)
+ nested_type = NDS32_NESTED_READY;
+ else if (nested_str)
+ nested_type = NDS32_NESTED;
+ else if (critical_str)
+ nested_type = NDS32_CRITICAL;
+ else
+ nested_type = NDS32_NOT_NESTED;
+
+ /* 3. Traverse each id value and set corresponding information. */
+ id_str = strstr (target_str, "id=");
+
+ /* If user forgets to assign 'id', issue an error message. */
+ if (id_str == NULL)
+ error ("require id argument in the string");
+ /* Extract the value_str first. */
+ id_str = strtok (id_str, "=");
+ value_str = strtok (NULL, ";");
+
+ /* Pick up the first id value token. */
+ value_str = strtok (value_str, ",");
+ while (value_str != NULL)
+ {
+ int i;
+ i = atoi (value_str);
+
+ /* For exception(1..8), the actual vector number is (1..8). */
+ if (i < 1 || i > 8)
+ error ("invalid id value for exception attribute");
+
+ /* Setup nds32_isr_vectors[] array. */
+ nds32_isr_vectors[i].category = NDS32_ISR_EXCEPTION;
+ strcpy (nds32_isr_vectors[i].func_name, func_name);
+ nds32_isr_vectors[i].save_reg = save_reg;
+ nds32_isr_vectors[i].nested_type = nested_type;
+ nds32_isr_vectors[i].security_level = s_level;
+
+ /* Fetch next token. */
+ value_str = strtok (NULL, ",");
+ }
+
+ return;
+}
+
+static void
+nds32_reset_attribute_parse_string (const char *original_str,
+ const char *func_name)
+{
+ char target_str[100];
+ char *vectors_str, *nmi_str, *warm_str, *value_str;
+
+ /* Deal with reset attribute. Its vector number is always 0. */
+ nds32_isr_vectors[0].category = NDS32_ISR_RESET;
+
+
+ /* 1. Parse 'vectors=XXXX'. */
+
+ /* Copy original string into a character array so that
+ the string APIs can handle it. */
+ strcpy (target_str, original_str);
+ vectors_str = strstr (target_str, "vectors=");
+ /* The total vectors = interrupt + exception numbers + reset.
+ There are 8 exception and 1 reset in nds32 architecture.
+ If user forgets to assign 'vectors', user default 16 interrupts. */
+ if (vectors_str != NULL)
+ {
+ /* Extract the value_str. */
+ vectors_str = strtok (vectors_str, "=");
+ value_str = strtok (NULL, ";");
+ nds32_isr_vectors[0].total_n_vectors = atoi (value_str) + 8 + 1;
+ }
+ else
+ nds32_isr_vectors[0].total_n_vectors = 16 + 8 + 1;
+ strcpy (nds32_isr_vectors[0].func_name, func_name);
+
+
+ /* 2. Parse 'nmi_func=YYYY'. */
+
+ /* Copy original string into a character array so that
+ the string APIs can handle it. */
+ strcpy (target_str, original_str);
+ nmi_str = strstr (target_str, "nmi_func=");
+ if (nmi_str != NULL)
+ {
+ /* Extract the value_str. */
+ nmi_str = strtok (nmi_str, "=");
+ value_str = strtok (NULL, ";");
+ strcpy (nds32_isr_vectors[0].nmi_name, value_str);
+ }
+
+ /* 3. Parse 'warm_func=ZZZZ'. */
+
+ /* Copy original string into a character array so that
+ the string APIs can handle it. */
+ strcpy (target_str, original_str);
+ warm_str = strstr (target_str, "warm_func=");
+ if (warm_str != NULL)
+ {
+ /* Extract the value_str. */
+ warm_str = strtok (warm_str, "=");
+ value_str = strtok (NULL, ";");
+ strcpy (nds32_isr_vectors[0].warm_name, value_str);
+ }
+
+ return;
+}
+/* ------------------------------------------------------------- */
/* A helper function to emit section head template. */
static void
@@ -79,6 +332,15 @@
char section_name[100];
char symbol_name[100];
+ /* A critical isr does not need jump table section because
+ its behavior is not performed by two-level handler. */
+ if (nds32_isr_vectors[vector_id].nested_type == NDS32_CRITICAL)
+ {
+ fprintf (asm_out_file, "\t! The vector %02d is a critical isr !\n",
+ vector_id);
+ return;
+ }
+
/* Prepare jmptbl section and symbol name. */
snprintf (section_name, sizeof (section_name),
".nds32_jmptbl.%02d", vector_id);
@@ -99,7 +361,6 @@
const char *c_str = "CATEGORY";
const char *sr_str = "SR";
const char *nt_str = "NT";
- const char *vs_str = "VS";
char first_level_handler_name[100];
char section_name[100];
char symbol_name[100];
@@ -147,30 +408,47 @@
case NDS32_NESTED_READY:
nt_str = "nr";
break;
+ case NDS32_CRITICAL:
+ /* The critical isr is not performed by two-level handler. */
+ nt_str = "";
+ break;
}
- /* Currently we have 4-byte or 16-byte size for each vector.
- If it is 4-byte, the first level handler name has suffix string "_4b". */
- vs_str = (nds32_isr_vector_size == 4) ? "_4b" : "";
-
/* Now we can create first level handler name. */
- snprintf (first_level_handler_name, sizeof (first_level_handler_name),
- "_nds32_%s_%s_%s%s", c_str, sr_str, nt_str, vs_str);
+ if (nds32_isr_vectors[vector_id].security_level == 0)
+ {
+ /* For security level 0, use normal first level handler name. */
+ snprintf (first_level_handler_name, sizeof (first_level_handler_name),
+ "_nds32_%s_%s_%s", c_str, sr_str, nt_str);
+ }
+ else
+ {
+ /* For security level 1-3, use corresponding spl_1, spl_2, or spl_3. */
+ snprintf (first_level_handler_name, sizeof (first_level_handler_name),
+ "_nds32_spl_%d", nds32_isr_vectors[vector_id].security_level);
+ }
/* Prepare vector section and symbol name. */
snprintf (section_name, sizeof (section_name),
".nds32_vector.%02d", vector_id);
snprintf (symbol_name, sizeof (symbol_name),
- "_nds32_vector_%02d%s", vector_id, vs_str);
+ "_nds32_vector_%02d", vector_id);
/* Everything is ready. We can start emit vector section content. */
nds32_emit_section_head_template (section_name, symbol_name,
floor_log2 (nds32_isr_vector_size), false);
- /* According to the vector size, the instructions in the
- vector section may be different. */
- if (nds32_isr_vector_size == 4)
+ /* First we check if it is a critical isr.
+ If so, jump to user handler directly; otherwise, the instructions
+ in the vector section may be different according to the vector size. */
+ if (nds32_isr_vectors[vector_id].nested_type == NDS32_CRITICAL)
+ {
+ /* This block is for critical isr. Jump to user handler directly. */
+ fprintf (asm_out_file, "\tj\t%s ! jump to user handler directly\n",
+ nds32_isr_vectors[vector_id].func_name);
+ }
+ else if (nds32_isr_vector_size == 4)
{
/* This block is for 4-byte vector size.
Hardware $VID support is necessary and only one instruction
@@ -239,13 +517,11 @@
{
unsigned int i;
unsigned int total_n_vectors;
- const char *vs_str;
char reset_handler_name[100];
char section_name[100];
char symbol_name[100];
total_n_vectors = nds32_isr_vectors[0].total_n_vectors;
- vs_str = (nds32_isr_vector_size == 4) ? "_4b" : "";
fprintf (asm_out_file, "\t! RESET HANDLER CONTENT - BEGIN !\n");
@@ -261,7 +537,7 @@
/* Emit vector references. */
fprintf (asm_out_file, "\t ! references to vector section entries\n");
for (i = 0; i < total_n_vectors; i++)
- fprintf (asm_out_file, "\t.word\t_nds32_vector_%02d%s\n", i, vs_str);
+ fprintf (asm_out_file, "\t.word\t_nds32_vector_%02d\n", i);
/* Emit jmptbl_00 section. */
snprintf (section_name, sizeof (section_name), ".nds32_jmptbl.00");
@@ -275,9 +551,9 @@
/* Emit vector_00 section. */
snprintf (section_name, sizeof (section_name), ".nds32_vector.00");
- snprintf (symbol_name, sizeof (symbol_name), "_nds32_vector_00%s", vs_str);
+ snprintf (symbol_name, sizeof (symbol_name), "_nds32_vector_00");
snprintf (reset_handler_name, sizeof (reset_handler_name),
- "_nds32_reset%s", vs_str);
+ "_nds32_reset");
fprintf (asm_out_file, "\t! ....................................\n");
nds32_emit_section_head_template (section_name, symbol_name,
@@ -323,12 +599,12 @@
nds32_check_isr_attrs_conflict (tree func_decl, tree func_attrs)
{
int save_all_p, partial_save_p;
- int nested_p, not_nested_p, nested_ready_p;
+ int nested_p, not_nested_p, nested_ready_p, critical_p;
int intr_p, excp_p, reset_p;
/* Initialize variables. */
save_all_p = partial_save_p = 0;
- nested_p = not_nested_p = nested_ready_p = 0;
+ nested_p = not_nested_p = nested_ready_p = critical_p = 0;
intr_p = excp_p = reset_p = 0;
/* We must check at MOST one attribute to set save-reg. */
@@ -347,8 +623,10 @@
not_nested_p = 1;
if (lookup_attribute ("nested_ready", func_attrs))
nested_ready_p = 1;
+ if (lookup_attribute ("critical", func_attrs))
+ critical_p = 1;
- if ((nested_p + not_nested_p + nested_ready_p) > 1)
+ if ((nested_p + not_nested_p + nested_ready_p + critical_p) > 1)
error ("multiple nested types attributes to function %qD", func_decl);
/* We must check at MOST one attribute to
@@ -362,6 +640,17 @@
if ((intr_p + excp_p + reset_p) > 1)
error ("multiple interrupt attributes to function %qD", func_decl);
+
+ /* Do not allow isr attributes under linux toolchain. */
+ if (TARGET_LINUX_ABI && intr_p)
+ error ("cannot use interrupt attributes to function %qD "
+ "under linux toolchain", func_decl);
+ if (TARGET_LINUX_ABI && excp_p)
+ error ("cannot use exception attributes to function %qD "
+ "under linux toolchain", func_decl);
+ if (TARGET_LINUX_ABI && reset_p)
+ error ("cannot use reset attributes to function %qD "
+ "under linux toolchain", func_decl);
}
/* Function to construct isr vectors information array.
@@ -373,15 +662,21 @@
const char *func_name)
{
tree save_all, partial_save;
- tree nested, not_nested, nested_ready;
+ tree nested, not_nested, nested_ready, critical;
tree intr, excp, reset;
+ tree secure;
+ tree security_level_list;
+ tree security_level;
+ unsigned int s_level;
+
save_all = lookup_attribute ("save_all", func_attrs);
partial_save = lookup_attribute ("partial_save", func_attrs);
nested = lookup_attribute ("nested", func_attrs);
not_nested = lookup_attribute ("not_nested", func_attrs);
nested_ready = lookup_attribute ("nested_ready", func_attrs);
+ critical = lookup_attribute ("critical", func_attrs);
intr = lookup_attribute ("interrupt", func_attrs);
excp = lookup_attribute ("exception", func_attrs);
@@ -391,6 +686,63 @@
if (!intr && !excp && !reset)
return;
+ /* At first, we need to retrieve security level. */
+ secure = lookup_attribute ("secure", func_attrs);
+ if (secure != NULL)
+ {
+ security_level_list = TREE_VALUE (secure);
+ security_level = TREE_VALUE (security_level_list);
+ s_level = TREE_INT_CST_LOW (security_level);
+ }
+ else
+ {
+ /* If there is no secure attribute, the security level is set by
+ nds32_isr_secure_level, which is controlled by -misr-secure=X option.
+ By default nds32_isr_secure_level should be 0. */
+ s_level = nds32_isr_secure_level;
+ }
+
+ /* ------------------------------------------------------------- */
+ /* FIXME:
+ FOR BACKWARD COMPATIBILITY, we need to support following patterns:
+
+ __attribute__((interrupt("XXX;YYY;id=ZZZ")))
+ __attribute__((exception("XXX;YYY;id=ZZZ")))
+ __attribute__((reset("vectors=XXX;nmi_func=YYY;warm_func=ZZZ")))
+
+ If interrupt/exception/reset appears and its argument is a
+ STRING_CST, we will parse string with some auxiliary functions
+ which set necessary isr information in the nds32_isr_vectors[] array.
+ After that, we can return immediately to avoid new-syntax isr
+ information construction. */
+ if (intr != NULL_TREE
+ && TREE_CODE (TREE_VALUE (TREE_VALUE (intr))) == STRING_CST)
+ {
+ tree string_arg = TREE_VALUE (TREE_VALUE (intr));
+ nds32_interrupt_attribute_parse_string (TREE_STRING_POINTER (string_arg),
+ func_name,
+ s_level);
+ return;
+ }
+ if (excp != NULL_TREE
+ && TREE_CODE (TREE_VALUE (TREE_VALUE (excp))) == STRING_CST)
+ {
+ tree string_arg = TREE_VALUE (TREE_VALUE (excp));
+ nds32_exception_attribute_parse_string (TREE_STRING_POINTER (string_arg),
+ func_name,
+ s_level);
+ return;
+ }
+ if (reset != NULL_TREE
+ && TREE_CODE (TREE_VALUE (TREE_VALUE (reset))) == STRING_CST)
+ {
+ tree string_arg = TREE_VALUE (TREE_VALUE (reset));
+ nds32_reset_attribute_parse_string (TREE_STRING_POINTER (string_arg),
+ func_name);
+ return;
+ }
+ /* ------------------------------------------------------------- */
+
/* If we are here, either we have interrupt/exception,
or reset attribute. */
if (intr || excp)
@@ -417,6 +769,9 @@
/* Add vector_number_offset to get actual vector number. */
vector_id = TREE_INT_CST_LOW (id) + vector_number_offset;
+ /* Set security level. */
+ nds32_isr_vectors[vector_id].security_level = s_level;
+
/* Enable corresponding vector and set function name. */
nds32_isr_vectors[vector_id].category = (intr)
? (NDS32_ISR_INTERRUPT)
@@ -436,6 +791,8 @@
nds32_isr_vectors[vector_id].nested_type = NDS32_NOT_NESTED;
else if (nested_ready)
nds32_isr_vectors[vector_id].nested_type = NDS32_NESTED_READY;
+ else if (critical)
+ nds32_isr_vectors[vector_id].nested_type = NDS32_CRITICAL;
/* Advance to next id. */
id_list = TREE_CHAIN (id_list);
@@ -492,7 +849,6 @@
}
}
-/* A helper function to handle isr stuff at the beginning of asm file. */
void
nds32_asm_file_start_for_isr (void)
{
@@ -505,15 +861,14 @@
strcpy (nds32_isr_vectors[i].func_name, "");
nds32_isr_vectors[i].save_reg = NDS32_PARTIAL_SAVE;
nds32_isr_vectors[i].nested_type = NDS32_NOT_NESTED;
+ nds32_isr_vectors[i].security_level = 0;
nds32_isr_vectors[i].total_n_vectors = 0;
strcpy (nds32_isr_vectors[i].nmi_name, "");
strcpy (nds32_isr_vectors[i].warm_name, "");
}
}
-/* A helper function to handle isr stuff at the end of asm file. */
-void
-nds32_asm_file_end_for_isr (void)
+void nds32_asm_file_end_for_isr (void)
{
int i;
@@ -547,6 +902,8 @@
/* Found one vector which is interupt or exception.
Output its jmptbl and vector section content. */
fprintf (asm_out_file, "\t! interrupt/exception vector %02d\n", i);
+ fprintf (asm_out_file, "\t! security level: %d\n",
+ nds32_isr_vectors[i].security_level);
fprintf (asm_out_file, "\t! ------------------------------------\n");
nds32_emit_isr_jmptbl_section (i);
fprintf (asm_out_file, "\t! ....................................\n");
@@ -580,4 +937,65 @@
|| (t_reset != NULL_TREE));
}
-/* ------------------------------------------------------------------------ */
+/* Return true if FUNC is a isr function with critical attribute. */
+bool
+nds32_isr_function_critical_p (tree func)
+{
+ tree t_intr;
+ tree t_excp;
+ tree t_critical;
+
+ tree attrs;
+
+ if (TREE_CODE (func) != FUNCTION_DECL)
+ abort ();
+
+ attrs = DECL_ATTRIBUTES (func);
+
+ t_intr = lookup_attribute ("interrupt", attrs);
+ t_excp = lookup_attribute ("exception", attrs);
+
+ t_critical = lookup_attribute ("critical", attrs);
+
+ /* If both interrupt and exception attribute does not appear,
+ we can return false immediately. */
+ if ((t_intr == NULL_TREE) && (t_excp == NULL_TREE))
+ return false;
+
+ /* Here we can guarantee either interrupt or ecxception attribute
+ does exist, so further check critical attribute.
+ If it also appears, we can return true. */
+ if (t_critical != NULL_TREE)
+ return true;
+
+ /* ------------------------------------------------------------- */
+ /* FIXME:
+ FOR BACKWARD COMPATIBILITY, we need to handle string type.
+ If the string 'critical' appears in the interrupt/exception
+ string argument, we can return true. */
+ if (t_intr != NULL_TREE || t_excp != NULL_TREE)
+ {
+ char target_str[100];
+ char *critical_str;
+ tree t_check;
+ tree string_arg;
+
+ t_check = t_intr ? t_intr : t_excp;
+ if (TREE_CODE (TREE_VALUE (TREE_VALUE (t_check))) == STRING_CST)
+ {
+ string_arg = TREE_VALUE (TREE_VALUE (t_check));
+ strcpy (target_str, TREE_STRING_POINTER (string_arg));
+ critical_str = strstr (target_str, "critical");
+
+ /* Found 'critical' string, so return true. */
+ if (critical_str)
+ return true;
+ }
+ }
+ /* ------------------------------------------------------------- */
+
+ /* Other cases, this isr function is not critical type. */
+ return false;
+}
+
+/* ------------------------------------------------------------- */
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32_isr.h gcc-8.2.0/gcc/config/nds32/nds32_isr.h
--- gcc-8.2.0.orig/gcc/config/nds32/nds32_isr.h 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32_isr.h 2019-01-25 15:38:32.833242671 +0100
@@ -0,0 +1,526 @@
+/* Intrinsic definitions of Andes NDS32 cpu for GNU compiler
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _NDS32_ISR_H
+#define _NDS32_ISR_H
+
+/* Attribute of a interrupt or exception handler:
+
+ NDS32_READY_NESTED: This handler is interruptible if user re-enable GIE bit.
+ NDS32_NESTED : This handler is interruptible. This is not suitable
+ exception handler.
+ NDS32_NOT_NESTED : This handler is NOT interruptible. Users have to do
+ some work if nested is wanted
+ NDS32_CRITICAL : This handler is critical ISR, which means it is small
+ and efficient. */
+#define NDS32_READY_NESTED 0
+#define NDS32_NESTED 1
+#define NDS32_NOT_NESTED 2
+#define NDS32_CRITICAL 3
+
+/* Attribute of a interrupt or exception handler:
+
+ NDS32_SAVE_ALL_REGS : Save all registers in a table.
+ NDS32_SAVE_PARTIAL_REGS: Save partial registers. */
+#define NDS32_SAVE_CALLER_REGS 0
+#define NDS32_SAVE_ALL_REGS 1
+
+/* There are two version of Register table for interrupt and exception handler,
+ one for 16-register CPU the other for 32-register CPU. These structures are
+ used for context switching or system call handling. The address of this
+ data can be get from the input argument of the handler functions.
+
+ For system call handling, r0 to r5 are used to pass arguments. If more
+ arguments are used they are put into the stack and its starting address is
+ in sp. Return value of system call can be put into r0 and r1 upon exit from
+ system call handler. System call ID is in a system register and it can be
+ fetched via intrinsic function. For more information please read ABI and
+ other related documents.
+
+ For context switching, at least 2 values need to saved in kernel. One is
+ IPC and the other is the stack address of current task. Use intrinsic
+ function to get IPC and the input argument of the handler functions + 8 to
+ get stack address of current task. To do context switching, you replace
+ new_sp with the stack address of new task and replace IPC system register
+ with IPC of new task, then, just return from handler. The context switching
+ will happen. */
+
+/* Register table for exception handler; 32-register version. */
+typedef struct
+{
+ int r0;
+ int r1;
+ int r2;
+ int r3;
+ int r4;
+ int r5;
+ int r6;
+ int r7;
+ int r8;
+ int r9;
+ int r10;
+ int r11;
+ int r12;
+ int r13;
+ int r14;
+ int r15;
+ int r16;
+ int r17;
+ int r18;
+ int r19;
+ int r20;
+ int r21;
+ int r22;
+ int r23;
+ int r24;
+ int r25;
+ int r26;
+ int r27;
+ int fp;
+ int gp;
+ int lp;
+ int sp;
+} NDS32_GPR32;
+
+/* Register table for exception handler; 16-register version. */
+typedef struct
+{
+ int r0;
+ int r1;
+ int r2;
+ int r3;
+ int r4;
+ int r5;
+ int r6;
+ int r7;
+ int r8;
+ int r9;
+ int r10;
+ int r15;
+ int fp;
+ int gp;
+ int lp;
+ int sp;
+} NDS32_GPR16;
+
+
+/* Use NDS32_REG32_TAB or NDS32_REG16_TAB in your program to
+ access register table. */
+typedef struct
+{
+ union
+ {
+ int reg_a[32] ;
+ NDS32_GPR32 reg_s ;
+ } u ;
+} NDS32_REG32_TAB;
+
+typedef struct
+{
+ union
+ {
+ int reg_a[16] ;
+ NDS32_GPR16 reg_s ;
+ } u ;
+} NDS32_REG16_TAB;
+
+typedef struct
+{
+ int d0lo;
+ int d0hi;
+ int d1lo;
+ int d1hi;
+} NDS32_DX_TAB;
+
+typedef struct
+{
+#ifdef __NDS32_EB__
+ float fsr0;
+ float fsr1;
+ float fsr2;
+ float fsr3;
+ float fsr4;
+ float fsr5;
+ float fsr6;
+ float fsr7;
+#else
+ float fsr1;
+ float fsr0;
+ float fsr3;
+ float fsr2;
+ float fsr5;
+ float fsr4;
+ float fsr7;
+ float fsr6;
+#endif
+} NDS32_FSR8;
+
+typedef struct
+{
+ double dsr0;
+ double dsr1;
+ double dsr2;
+ double dsr3;
+} NDS32_DSR4;
+
+typedef struct
+{
+#ifdef __NDS32_EB__
+ float fsr0;
+ float fsr1;
+ float fsr2;
+ float fsr3;
+ float fsr4;
+ float fsr5;
+ float fsr6;
+ float fsr7;
+ float fsr8;
+ float fsr9;
+ float fsr10;
+ float fsr11;
+ float fsr12;
+ float fsr13;
+ float fsr14;
+ float fsr15;
+#else
+ float fsr1;
+ float fsr0;
+ float fsr3;
+ float fsr2;
+ float fsr5;
+ float fsr4;
+ float fsr7;
+ float fsr6;
+ float fsr9;
+ float fsr8;
+ float fsr11;
+ float fsr10;
+ float fsr13;
+ float fsr12;
+ float fsr15;
+ float fsr14;
+#endif
+} NDS32_FSR16;
+
+typedef struct
+{
+ double dsr0;
+ double dsr1;
+ double dsr2;
+ double dsr3;
+ double dsr4;
+ double dsr5;
+ double dsr6;
+ double dsr7;
+} NDS32_DSR8;
+
+typedef struct
+{
+#ifdef __NDS32_EB__
+ float fsr0;
+ float fsr1;
+ float fsr2;
+ float fsr3;
+ float fsr4;
+ float fsr5;
+ float fsr6;
+ float fsr7;
+ float fsr8;
+ float fsr9;
+ float fsr10;
+ float fsr11;
+ float fsr12;
+ float fsr13;
+ float fsr14;
+ float fsr15;
+ float fsr16;
+ float fsr17;
+ float fsr18;
+ float fsr19;
+ float fsr20;
+ float fsr21;
+ float fsr22;
+ float fsr23;
+ float fsr24;
+ float fsr25;
+ float fsr26;
+ float fsr27;
+ float fsr28;
+ float fsr29;
+ float fsr30;
+ float fsr31;
+#else
+ float fsr1;
+ float fsr0;
+ float fsr3;
+ float fsr2;
+ float fsr5;
+ float fsr4;
+ float fsr7;
+ float fsr6;
+ float fsr9;
+ float fsr8;
+ float fsr11;
+ float fsr10;
+ float fsr13;
+ float fsr12;
+ float fsr15;
+ float fsr14;
+ float fsr17;
+ float fsr16;
+ float fsr19;
+ float fsr18;
+ float fsr21;
+ float fsr20;
+ float fsr23;
+ float fsr22;
+ float fsr25;
+ float fsr24;
+ float fsr27;
+ float fsr26;
+ float fsr29;
+ float fsr28;
+ float fsr31;
+ float fsr30;
+#endif
+} NDS32_FSR32;
+
+typedef struct
+{
+ double dsr0;
+ double dsr1;
+ double dsr2;
+ double dsr3;
+ double dsr4;
+ double dsr5;
+ double dsr6;
+ double dsr7;
+ double dsr8;
+ double dsr9;
+ double dsr10;
+ double dsr11;
+ double dsr12;
+ double dsr13;
+ double dsr14;
+ double dsr15;
+} NDS32_DSR16;
+
+typedef struct
+{
+ double dsr0;
+ double dsr1;
+ double dsr2;
+ double dsr3;
+ double dsr4;
+ double dsr5;
+ double dsr6;
+ double dsr7;
+ double dsr8;
+ double dsr9;
+ double dsr10;
+ double dsr11;
+ double dsr12;
+ double dsr13;
+ double dsr14;
+ double dsr15;
+ double dsr16;
+ double dsr17;
+ double dsr18;
+ double dsr19;
+ double dsr20;
+ double dsr21;
+ double dsr22;
+ double dsr23;
+ double dsr24;
+ double dsr25;
+ double dsr26;
+ double dsr27;
+ double dsr28;
+ double dsr29;
+ double dsr30;
+ double dsr31;
+} NDS32_DSR32;
+
+typedef struct
+{
+ union
+ {
+ NDS32_FSR8 fsr_s ;
+ NDS32_DSR4 dsr_s ;
+ } u ;
+} NDS32_FPU8_TAB;
+
+typedef struct
+{
+ union
+ {
+ NDS32_FSR16 fsr_s ;
+ NDS32_DSR8 dsr_s ;
+ } u ;
+} NDS32_FPU16_TAB;
+
+typedef struct
+{
+ union
+ {
+ NDS32_FSR32 fsr_s ;
+ NDS32_DSR16 dsr_s ;
+ } u ;
+} NDS32_FPU32_TAB;
+
+typedef struct
+{
+ union
+ {
+ NDS32_FSR32 fsr_s ;
+ NDS32_DSR32 dsr_s ;
+ } u ;
+} NDS32_FPU64_TAB;
+
+typedef struct
+{
+ int ipc;
+ int ipsw;
+#if defined(NDS32_EXT_FPU_CONFIG_0)
+ NDS32_FPU8_TAB fpr;
+#elif defined(NDS32_EXT_FPU_CONFIG_1)
+ NDS32_FPU16_TAB fpr;
+#elif defined(NDS32_EXT_FPU_CONFIG_2)
+ NDS32_FPU32_TAB fpr;
+#elif defined(NDS32_EXT_FPU_CONFIG_3)
+ NDS32_FPU64_TAB fpr;
+#endif
+#if __NDS32_DX_REGS__
+ NDS32_DX_TAB dxr;
+#endif
+#if __NDS32_EXT_IFC__
+ int ifc_lp;
+ int filler;
+#endif
+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS
+ NDS32_REG16_TAB gpr;
+#else
+ NDS32_REG32_TAB gpr;
+#endif
+} NDS32_CONTEXT;
+
+/* Predefined Vector Definition.
+
+ For IVIC Mode: 9 to 14 are for hardware interrupt
+ and 15 is for software interrupt.
+ For EVIC Mode: 9 to 72 are for hardware interrupt
+ and software interrupt can be routed to any one of them.
+
+ You may want to define your hardware interrupts in the following way
+ for easy maintainance.
+
+ IVIC mode:
+ #define MY_HW_IVIC_TIMER NDS32_VECTOR_INTERRUPT_HW0 + 1
+ #define MY_HW_IVIC_USB NDS32_VECTOR_INTERRUPT_HW0 + 3
+ EVIC mode:
+ #define MY_HW_EVIC_DMA NDS32_VECTOR_INTERRUPT_HW0 + 2
+ #define MY_HW_EVIC_SWI NDS32_VECTOR_INTERRUPT_HW0 + 10 */
+#define NDS32_VECTOR_RESET 0
+#define NDS32_VECTOR_TLB_FILL 1
+#define NDS32_VECTOR_PTE_NOT_PRESENT 2
+#define NDS32_VECTOR_TLB_MISC 3
+#define NDS32_VECTOR_TLB_VLPT_MISS 4
+#define NDS32_VECTOR_MACHINE_ERROR 5
+#define NDS32_VECTOR_DEBUG_RELATED 6
+#define NDS32_VECTOR_GENERAL_EXCEPTION 7
+#define NDS32_VECTOR_SYSCALL 8
+#define NDS32_VECTOR_INTERRUPT_HW0 9
+#define NDS32_VECTOR_INTERRUPT_HW1 10
+#define NDS32_VECTOR_INTERRUPT_HW2 11
+#define NDS32_VECTOR_INTERRUPT_HW3 12
+#define NDS32_VECTOR_INTERRUPT_HW4 13
+#define NDS32_VECTOR_INTERRUPT_HW5 14
+#define NDS32_VECTOR_INTERRUPT_HW6 15
+#define NDS32_VECTOR_SWI 15 /* THIS IS FOR IVIC MODE ONLY */
+#define NDS32_VECTOR_INTERRUPT_HW7 16
+#define NDS32_VECTOR_INTERRUPT_HW8 17
+#define NDS32_VECTOR_INTERRUPT_HW9 18
+#define NDS32_VECTOR_INTERRUPT_HW10 19
+#define NDS32_VECTOR_INTERRUPT_HW11 20
+#define NDS32_VECTOR_INTERRUPT_HW12 21
+#define NDS32_VECTOR_INTERRUPT_HW13 22
+#define NDS32_VECTOR_INTERRUPT_HW14 23
+#define NDS32_VECTOR_INTERRUPT_HW15 24
+#define NDS32_VECTOR_INTERRUPT_HW16 25
+#define NDS32_VECTOR_INTERRUPT_HW17 26
+#define NDS32_VECTOR_INTERRUPT_HW18 27
+#define NDS32_VECTOR_INTERRUPT_HW19 28
+#define NDS32_VECTOR_INTERRUPT_HW20 29
+#define NDS32_VECTOR_INTERRUPT_HW21 30
+#define NDS32_VECTOR_INTERRUPT_HW22 31
+#define NDS32_VECTOR_INTERRUPT_HW23 32
+#define NDS32_VECTOR_INTERRUPT_HW24 33
+#define NDS32_VECTOR_INTERRUPT_HW25 34
+#define NDS32_VECTOR_INTERRUPT_HW26 35
+#define NDS32_VECTOR_INTERRUPT_HW27 36
+#define NDS32_VECTOR_INTERRUPT_HW28 37
+#define NDS32_VECTOR_INTERRUPT_HW29 38
+#define NDS32_VECTOR_INTERRUPT_HW30 39
+#define NDS32_VECTOR_INTERRUPT_HW31 40
+#define NDS32_VECTOR_INTERRUPT_HW32 41
+#define NDS32_VECTOR_INTERRUPT_HW33 42
+#define NDS32_VECTOR_INTERRUPT_HW34 43
+#define NDS32_VECTOR_INTERRUPT_HW35 44
+#define NDS32_VECTOR_INTERRUPT_HW36 45
+#define NDS32_VECTOR_INTERRUPT_HW37 46
+#define NDS32_VECTOR_INTERRUPT_HW38 47
+#define NDS32_VECTOR_INTERRUPT_HW39 48
+#define NDS32_VECTOR_INTERRUPT_HW40 49
+#define NDS32_VECTOR_INTERRUPT_HW41 50
+#define NDS32_VECTOR_INTERRUPT_HW42 51
+#define NDS32_VECTOR_INTERRUPT_HW43 52
+#define NDS32_VECTOR_INTERRUPT_HW44 53
+#define NDS32_VECTOR_INTERRUPT_HW45 54
+#define NDS32_VECTOR_INTERRUPT_HW46 55
+#define NDS32_VECTOR_INTERRUPT_HW47 56
+#define NDS32_VECTOR_INTERRUPT_HW48 57
+#define NDS32_VECTOR_INTERRUPT_HW49 58
+#define NDS32_VECTOR_INTERRUPT_HW50 59
+#define NDS32_VECTOR_INTERRUPT_HW51 60
+#define NDS32_VECTOR_INTERRUPT_HW52 61
+#define NDS32_VECTOR_INTERRUPT_HW53 62
+#define NDS32_VECTOR_INTERRUPT_HW54 63
+#define NDS32_VECTOR_INTERRUPT_HW55 64
+#define NDS32_VECTOR_INTERRUPT_HW56 65
+#define NDS32_VECTOR_INTERRUPT_HW57 66
+#define NDS32_VECTOR_INTERRUPT_HW58 67
+#define NDS32_VECTOR_INTERRUPT_HW59 68
+#define NDS32_VECTOR_INTERRUPT_HW60 69
+#define NDS32_VECTOR_INTERRUPT_HW61 70
+#define NDS32_VECTOR_INTERRUPT_HW62 71
+#define NDS32_VECTOR_INTERRUPT_HW63 72
+
+#define NDS32ATTR_RESET(option) __attribute__((reset(option)))
+#define NDS32ATTR_EXCEPT(type) __attribute__((exception(type)))
+#define NDS32ATTR_EXCEPTION(type) __attribute__((exception(type)))
+#define NDS32ATTR_INTERRUPT(type) __attribute__((interrupt(type)))
+#define NDS32ATTR_ISR(type) __attribute__((interrupt(type)))
+
+#endif /* nds32_isr.h */
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-linux.opt gcc-8.2.0/gcc/config/nds32/nds32-linux.opt
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-linux.opt 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-linux.opt 2019-01-25 15:38:32.829242659 +0100
@@ -0,0 +1,16 @@
+mcmodel=
+Target RejectNegative Joined Enum(nds32_cmodel_type) Var(nds32_cmodel_option) Init(CMODEL_LARGE)
+Specify the address generation strategy for code model.
+
+Enum
+Name(nds32_cmodel_type) Type(enum nds32_cmodel_type)
+Known cmodel types (for use with the -mcmodel= option):
+
+EnumValue
+Enum(nds32_cmodel_type) String(small) Value(CMODEL_SMALL)
+
+EnumValue
+Enum(nds32_cmodel_type) String(medium) Value(CMODEL_MEDIUM)
+
+EnumValue
+Enum(nds32_cmodel_type) String(large) Value(CMODEL_LARGE)
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32.md gcc-8.2.0/gcc/config/nds32/nds32.md
--- gcc-8.2.0.orig/gcc/config/nds32/nds32.md 2018-04-08 11:21:30.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32.md 2019-01-25 15:38:32.833242671 +0100
@@ -56,24 +56,29 @@
;; ------------------------------------------------------------------------
;; CPU pipeline model.
-(define_attr "pipeline_model" "n7,n8,e8,n9,simple"
+(define_attr "pipeline_model" "n7,n8,e8,n9,n10,graywolf,n13,simple"
(const
(cond [(match_test "nds32_cpu_option == CPU_N7") (const_string "n7")
(match_test "nds32_cpu_option == CPU_E8") (const_string "e8")
(match_test "nds32_cpu_option == CPU_N6 || nds32_cpu_option == CPU_N8") (const_string "n8")
(match_test "nds32_cpu_option == CPU_N9") (const_string "n9")
+ (match_test "nds32_cpu_option == CPU_N10") (const_string "n10")
+ (match_test "nds32_cpu_option == CPU_GRAYWOLF") (const_string "graywolf")
+ (match_test "nds32_cpu_option == CPU_N12") (const_string "n13")
+ (match_test "nds32_cpu_option == CPU_N13") (const_string "n13")
(match_test "nds32_cpu_option == CPU_SIMPLE") (const_string "simple")]
(const_string "n9"))))
;; Insn type, it is used to default other attribute values.
(define_attr "type"
"unknown,load,store,load_multiple,store_multiple,alu,alu_shift,pbsad,pbsada,mul,mac,div,branch,mmu,misc,\
- falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore"
+ falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore,\
+ dalu,dalu64,daluround,dcmp,dclip,dmul,dmac,dinsb,dpack,dbpick,dwext"
(const_string "unknown"))
;; Insn sub-type
(define_attr "subtype"
- "simple,shift"
+ "simple,shift,saturation"
(const_string "simple"))
;; Length, in bytes, default is 4-bytes.
@@ -133,6 +138,7 @@
;; ----------------------------------------------------------------------------
+(include "nds32-dspext.md")
;; Move instructions.
@@ -209,6 +215,27 @@
low12_int));
DONE;
}
+
+ if ((REG_P (operands[0]) || GET_CODE (operands[0]) == SUBREG)
+ && SYMBOLIC_CONST_P (operands[1]))
+ {
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (operands[1]))
+ {
+ nds32_expand_ict_move (operands);
+ DONE;
+ }
+ else if (nds32_tls_referenced_p (operands [1]))
+ {
+ nds32_expand_tls_move (operands);
+ DONE;
+ }
+ else if (flag_pic)
+ {
+ nds32_expand_pic_move (operands);
+ DONE;
+ }
+ }
})
(define_insn "*mov<mode>"
@@ -271,8 +298,8 @@
;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
;; are able to match such instruction template.
(define_insn "move_addr"
- [(set (match_operand:SI 0 "register_operand" "=l, r")
- (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
+ [(set (match_operand:SI 0 "nds32_general_register_operand" "=l, r")
+ (match_operand:SI 1 "nds32_nonunspec_symbolic_operand" " i, i"))]
""
"la\t%0, %1"
[(set_attr "type" "alu")
@@ -351,13 +378,58 @@
;; ----------------------------------------------------------------------------
+(define_expand "extv"
+ [(set (match_operand 0 "register_operand" "")
+ (sign_extract (match_operand 1 "nonimmediate_operand" "")
+ (match_operand 2 "const_int_operand" "")
+ (match_operand 3 "const_int_operand" "")))]
+ ""
+{
+ enum nds32_expand_result_type result = nds32_expand_extv (operands);
+ switch (result)
+ {
+ case EXPAND_DONE:
+ DONE;
+ break;
+ case EXPAND_FAIL:
+ FAIL;
+ break;
+ case EXPAND_CREATE_TEMPLATE:
+ break;
+ default:
+ gcc_unreachable ();
+ }
+})
+
+(define_expand "insv"
+ [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
+ (match_operand 1 "const_int_operand" "")
+ (match_operand 2 "const_int_operand" ""))
+ (match_operand 3 "register_operand" ""))]
+ ""
+{
+ enum nds32_expand_result_type result = nds32_expand_insv (operands);
+ switch (result)
+ {
+ case EXPAND_DONE:
+ DONE;
+ break;
+ case EXPAND_FAIL:
+ FAIL;
+ break;
+ case EXPAND_CREATE_TEMPLATE:
+ break;
+ default:
+ gcc_unreachable ();
+ }
+})
;; Arithmetic instructions.
(define_insn "addsi3"
[(set (match_operand:SI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
(plus:SI (match_operand:SI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
- (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,Iu06, Is15, r")))]
+ (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,IU06, Is15, r")))]
""
{
switch (which_alternative)
@@ -1428,11 +1500,30 @@
(clobber (reg:SI LP_REGNUM))
(clobber (reg:SI TA_REGNUM))])]
""
- ""
+ {
+ rtx insn;
+ rtx sym = XEXP (operands[0], 0);
+
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (sym))
+ {
+ rtx reg = gen_reg_rtx (Pmode);
+ emit_move_insn (reg, sym);
+ operands[0] = gen_const_mem (Pmode, reg);
+ }
+
+ if (flag_pic)
+ {
+ insn = emit_call_insn (gen_call_internal
+ (XEXP (operands[0], 0), GEN_INT (0)));
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+ DONE;
+ }
+ }
)
(define_insn "call_internal"
- [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
+ [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, S"))
(match_operand 1))
(clobber (reg:SI LP_REGNUM))
(clobber (reg:SI TA_REGNUM))])]
@@ -1474,9 +1565,11 @@
(const_int 2)
(const_int 4))
;; Alternative 1
- (if_then_else (match_test "nds32_long_call_p (operands[0])")
- (const_int 12)
- (const_int 4))
+ (if_then_else (match_test "flag_pic")
+ (const_int 16)
+ (if_then_else (match_test "nds32_long_call_p (operands[0])")
+ (const_int 12)
+ (const_int 4)))
])]
)
@@ -1492,11 +1585,33 @@
(match_operand 2)))
(clobber (reg:SI LP_REGNUM))
(clobber (reg:SI TA_REGNUM))])]
- "")
+ ""
+ {
+ rtx insn;
+ rtx sym = XEXP (operands[1], 0);
+
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (sym))
+ {
+ rtx reg = gen_reg_rtx (Pmode);
+ emit_move_insn (reg, sym);
+ operands[1] = gen_const_mem (Pmode, reg);
+ }
+
+ if (flag_pic)
+ {
+ insn =
+ emit_call_insn (gen_call_value_internal
+ (operands[0], XEXP (operands[1], 0), GEN_INT (0)));
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+ DONE;
+ }
+ }
+)
(define_insn "call_value_internal"
[(parallel [(set (match_operand 0)
- (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i"))
+ (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, S"))
(match_operand 2)))
(clobber (reg:SI LP_REGNUM))
(clobber (reg:SI TA_REGNUM))])]
@@ -1538,9 +1653,11 @@
(const_int 2)
(const_int 4))
;; Alternative 1
- (if_then_else (match_test "nds32_long_call_p (operands[1])")
- (const_int 12)
- (const_int 4))
+ (if_then_else (match_test "flag_pic")
+ (const_int 16)
+ (if_then_else (match_test "nds32_long_call_p (operands[1])")
+ (const_int 12)
+ (const_int 4)))
])]
)
@@ -1583,10 +1700,21 @@
(const_int 0))
(clobber (reg:SI TA_REGNUM))
(return)])]
- "")
+ ""
+{
+ rtx sym = XEXP (operands[0], 0);
+
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (sym))
+ {
+ rtx reg = gen_reg_rtx (Pmode);
+ emit_move_insn (reg, sym);
+ operands[0] = gen_const_mem (Pmode, reg);
+ }
+})
(define_insn "sibcall_internal"
- [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
+ [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, S"))
(match_operand 1))
(clobber (reg:SI TA_REGNUM))
(return)])]
@@ -1617,9 +1745,11 @@
(const_int 2)
(const_int 4))
;; Alternative 1
- (if_then_else (match_test "nds32_long_call_p (operands[0])")
- (const_int 12)
- (const_int 4))
+ (if_then_else (match_test "flag_pic")
+ (const_int 16)
+ (if_then_else (match_test "nds32_long_call_p (operands[0])")
+ (const_int 12)
+ (const_int 4)))
])]
)
@@ -1633,11 +1763,22 @@
(const_int 0)))
(clobber (reg:SI TA_REGNUM))
(return)])]
- "")
+ ""
+{
+ rtx sym = XEXP (operands[1], 0);
+
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (sym))
+ {
+ rtx reg = gen_reg_rtx (Pmode);
+ emit_move_insn (reg, sym);
+ operands[1] = gen_const_mem (Pmode, reg);
+ }
+})
(define_insn "sibcall_value_internal"
[(parallel [(set (match_operand 0)
- (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i"))
+ (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, S"))
(match_operand 2)))
(clobber (reg:SI TA_REGNUM))
(return)])]
@@ -1668,9 +1809,11 @@
(const_int 2)
(const_int 4))
;; Alternative 1
- (if_then_else (match_test "nds32_long_call_p (operands[1])")
- (const_int 12)
- (const_int 4))
+ (if_then_else (match_test "flag_pic")
+ (const_int 16)
+ (if_then_else (match_test "nds32_long_call_p (operands[1])")
+ (const_int 12)
+ (const_int 4)))
])]
)
@@ -1687,12 +1830,33 @@
nds32_expand_prologue_v3push ();
else
nds32_expand_prologue ();
+
+ /* If cfun->machine->fp_as_gp_p is true, we can generate special
+ directive to guide linker doing fp-as-gp optimization.
+ However, for a naked function, which means
+ it should not have prologue/epilogue,
+ using fp-as-gp still requires saving $fp by push/pop behavior and
+ there is no benefit to use fp-as-gp on such small function.
+ So we need to make sure this function is NOT naked as well. */
+ if (cfun->machine->fp_as_gp_p && !cfun->machine->naked_p)
+ emit_insn (gen_omit_fp_begin (gen_rtx_REG (SImode, FP_REGNUM)));
+
DONE;
})
(define_expand "epilogue" [(const_int 0)]
""
{
+ /* If cfun->machine->fp_as_gp_p is true, we can generate special
+ directive to guide linker doing fp-as-gp optimization.
+ However, for a naked function, which means
+ it should not have prologue/epilogue,
+ using fp-as-gp still requires saving $fp by push/pop behavior and
+ there is no benefit to use fp-as-gp on such small function.
+ So we need to make sure this function is NOT naked as well. */
+ if (cfun->machine->fp_as_gp_p && !cfun->machine->naked_p)
+ emit_insn (gen_omit_fp_end (gen_rtx_REG (SImode, FP_REGNUM)));
+
/* Note that only under V3/V3M ISA, we could use v3pop epilogue.
In addition, we need to check if v3push is indeed available. */
if (NDS32_V3PUSH_AVAILABLE_P)
@@ -1792,7 +1956,8 @@
"nds32_can_use_return_insn ()"
{
/* Emit as the simple return. */
- if (cfun->machine->naked_p
+ if (!cfun->machine->fp_as_gp_p
+ && cfun->machine->naked_p
&& (cfun->machine->va_args_size == 0))
{
emit_jump_insn (gen_return_internal ());
@@ -1802,9 +1967,14 @@
;; This pattern is expanded only by the shrink-wrapping optimization
;; on paths where the function prologue has not been executed.
+;; However, such optimization may reorder the prologue/epilogue blocks
+;; together with basic blocks within function body.
+;; So we must disable this pattern if we have already decided
+;; to perform fp_as_gp optimization, which requires prologue to be
+;; first block and epilogue to be last block.
(define_expand "simple_return"
[(simple_return)]
- ""
+ "!cfun->machine->fp_as_gp_p"
""
)
@@ -1823,6 +1993,9 @@
[(simple_return)]
""
{
+ if (nds32_isr_function_critical_p (current_function_decl))
+ return "iret";
+
if (TARGET_16_BIT)
return "ret5";
else
@@ -1831,9 +2004,11 @@
[(set_attr "type" "branch")
(set_attr "enabled" "yes")
(set (attr "length")
- (if_then_else (match_test "TARGET_16_BIT")
- (const_int 2)
- (const_int 4)))])
+ (if_then_else (match_test "nds32_isr_function_critical_p (current_function_decl)")
+ (const_int 4)
+ (if_then_else (match_test "TARGET_16_BIT")
+ (const_int 2)
+ (const_int 4))))])
;; ----------------------------------------------------------------------------
@@ -1868,6 +2043,7 @@
{
rtx add_tmp;
rtx reg, test;
+ rtx tmp_reg;
/* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */
if (operands[1] != const0_rtx)
@@ -1889,9 +2065,14 @@
emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
operands[4]));
- /* Step C, D, E, and F, using another temporary register. */
- rtx tmp = gen_reg_rtx (SImode);
- emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp));
+ tmp_reg = gen_reg_rtx (SImode);
+ /* Step C, D, E, and F, using another temporary register tmp_reg. */
+ if (flag_pic)
+ emit_use (pic_offset_table_rtx);
+
+ emit_jump_insn (gen_casesi_internal (operands[0],
+ operands[3],
+ tmp_reg));
DONE;
})
@@ -1927,13 +2108,30 @@
else
return nds32_output_casesi (operands);
}
- [(set_attr "length" "20")
- (set_attr "type" "branch")])
+ [(set_attr "type" "branch")
+ (set (attr "length")
+ (if_then_else (match_test "flag_pic")
+ (const_int 28)
+ (const_int 20)))])
;; ----------------------------------------------------------------------------
;; Performance Extension
+; If -fwrapv option is issued, GCC expects there will be
+; signed overflow situation. So the ABS(INT_MIN) is still INT_MIN
+; (e.g. ABS(0x80000000)=0x80000000).
+; However, the hardware ABS instruction of nds32 target
+; always performs saturation: abs 0x80000000 -> 0x7fffffff.
+; So that we can only enable abssi2 pattern if flag_wrapv is NOT presented.
+(define_insn "abssi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (abs:SI (match_operand:SI 1 "register_operand" " r")))]
+ "TARGET_EXT_PERF && TARGET_HW_ABS && !flag_wrapv"
+ "abs\t%0, %1"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")])
+
(define_insn "clzsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(clz:SI (match_operand:SI 1 "register_operand" " r")))]
@@ -1996,6 +2194,25 @@
[(set_attr "length" "0")]
)
+;; Output .omit_fp_begin for fp-as-gp optimization.
+;; Also we have to set $fp register.
+(define_insn "omit_fp_begin"
+ [(set (match_operand:SI 0 "register_operand" "=x")
+ (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_OMIT_FP_BEGIN))]
+ ""
+ "! -----\;.omit_fp_begin\;la\t$fp,_FP_BASE_\;! -----"
+ [(set_attr "length" "8")]
+)
+
+;; Output .omit_fp_end for fp-as-gp optimization.
+;; Claim that we have to use $fp register.
+(define_insn "omit_fp_end"
+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "x")] UNSPEC_VOLATILE_OMIT_FP_END)]
+ ""
+ "! -----\;.omit_fp_end\;! -----"
+ [(set_attr "length" "0")]
+)
+
(define_insn "pop25return"
[(return)
(unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
@@ -2004,6 +2221,36 @@
[(set_attr "length" "0")]
)
+;; Add pc
+(define_insn "add_pc"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "0")
+ (pc)))]
+ "TARGET_LINUX_ABI || flag_pic"
+ "add5.pc\t%0"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
+(define_expand "bswapsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
+ ""
+{
+ emit_insn (gen_unspec_wsbh (operands[0], operands[1]));
+ emit_insn (gen_rotrsi3 (operands[0], operands[0], GEN_INT (16)));
+ DONE;
+})
+
+(define_insn "bswaphi2"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
+ ""
+ "wsbh\t%0, %1"
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")]
+)
+
;; ----------------------------------------------------------------------------
;; Patterns for exception handling
@@ -2068,3 +2315,57 @@
})
;; ----------------------------------------------------------------------------
+
+;; Patterns for TLS.
+;; The following two tls patterns don't be expanded directly because the
+;; intermediate value may be spilled into the stack. As a result, it is
+;; hard to analyze the define-use chain in the relax_opt pass.
+
+
+;; There is a unspec operand to record RELAX_GROUP number because each
+;; emitted instruction need a relax_hint above it.
+(define_insn "tls_desc"
+ [(set (reg:SI 0)
+ (call (unspec_volatile:SI [(match_operand:SI 0 "nds32_symbolic_operand" "i")] UNSPEC_TLS_DESC)
+ (const_int 1)))
+ (use (unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))
+ (use (reg:SI GP_REGNUM))
+ (clobber (reg:SI LP_REGNUM))
+ (clobber (reg:SI TA_REGNUM))]
+ ""
+ {
+ return nds32_output_tls_desc (operands);
+ }
+ [(set_attr "length" "20")
+ (set_attr "type" "branch")]
+)
+
+;; There is a unspec operand to record RELAX_GROUP number because each
+;; emitted instruction need a relax_hint above it.
+(define_insn "tls_ie"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")] UNSPEC_TLS_IE))
+ (use (unspec [(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))
+ (use (reg:SI GP_REGNUM))]
+ ""
+ {
+ return nds32_output_tls_ie (operands);
+ }
+ [(set (attr "length") (if_then_else (match_test "flag_pic")
+ (const_int 12)
+ (const_int 8)))
+ (set_attr "type" "misc")]
+)
+
+;; The pattern is for some relaxation groups that have to keep addsi3 in 32-bit mode.
+(define_insn "addsi3_32bit"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "%r")
+ (match_operand:SI 2 "register_operand" " r")] UNSPEC_ADD32))]
+ ""
+ "add\t%0, %1, %2";
+ [(set_attr "type" "alu")
+ (set_attr "length" "4")
+ (set_attr "feature" "v1")])
+
+;; ----------------------------------------------------------------------------
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-md-auxiliary.c gcc-8.2.0/gcc/config/nds32/nds32-md-auxiliary.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-md-auxiliary.c 2018-04-08 08:00:34.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-md-auxiliary.c 2019-01-25 15:38:32.829242659 +0100
@@ -39,6 +39,9 @@
#include "expr.h"
#include "emit-rtl.h"
#include "explow.h"
+#include "stringpool.h"
+#include "attribs.h"
+
/* ------------------------------------------------------------------------ */
@@ -261,6 +264,118 @@
output_asm_insn (pattern, operands);
}
+static void
+nds32_split_shiftrtdi3 (rtx dst, rtx src, rtx shiftamount, bool logic_shift_p)
+{
+ rtx src_high_part;
+ rtx dst_high_part, dst_low_part;
+
+ dst_high_part = nds32_di_high_part_subreg (dst);
+ src_high_part = nds32_di_high_part_subreg (src);
+ dst_low_part = nds32_di_low_part_subreg (dst);
+
+ if (CONST_INT_P (shiftamount))
+ {
+ if (INTVAL (shiftamount) < 32)
+ {
+ if (logic_shift_p)
+ {
+ emit_insn (gen_uwext (dst_low_part, src,
+ shiftamount));
+ emit_insn (gen_lshrsi3 (dst_high_part, src_high_part,
+ shiftamount));
+ }
+ else
+ {
+ emit_insn (gen_wext (dst_low_part, src,
+ shiftamount));
+ emit_insn (gen_ashrsi3 (dst_high_part, src_high_part,
+ shiftamount));
+ }
+ }
+ else
+ {
+ rtx new_shift_amout = gen_int_mode(INTVAL (shiftamount) - 32, SImode);
+
+ if (logic_shift_p)
+ {
+ emit_insn (gen_lshrsi3 (dst_low_part, src_high_part,
+ new_shift_amout));
+ emit_move_insn (dst_high_part, const0_rtx);
+ }
+ else
+ {
+ emit_insn (gen_ashrsi3 (dst_low_part, src_high_part,
+ new_shift_amout));
+ emit_insn (gen_ashrsi3 (dst_high_part, src_high_part,
+ GEN_INT (31)));
+ }
+ }
+ }
+ else
+ {
+ rtx dst_low_part_l32, dst_high_part_l32;
+ rtx dst_low_part_g32, dst_high_part_g32;
+ rtx new_shift_amout, select_reg;
+ dst_low_part_l32 = gen_reg_rtx (SImode);
+ dst_high_part_l32 = gen_reg_rtx (SImode);
+ dst_low_part_g32 = gen_reg_rtx (SImode);
+ dst_high_part_g32 = gen_reg_rtx (SImode);
+ new_shift_amout = gen_reg_rtx (SImode);
+ select_reg = gen_reg_rtx (SImode);
+
+ emit_insn (gen_andsi3 (shiftamount, shiftamount, GEN_INT (0x3f)));
+
+ if (logic_shift_p)
+ {
+ /*
+ if (shiftamount < 32)
+ dst_low_part = wext (src, shiftamount)
+ dst_high_part = src_high_part >> shiftamount
+ else
+ dst_low_part = src_high_part >> (shiftamount & 0x1f)
+ dst_high_part = 0
+ */
+ emit_insn (gen_uwext (dst_low_part_l32, src, shiftamount));
+ emit_insn (gen_lshrsi3 (dst_high_part_l32, src_high_part,
+ shiftamount));
+
+ emit_insn (gen_andsi3 (new_shift_amout, shiftamount, GEN_INT (0x1f)));
+ emit_insn (gen_lshrsi3 (dst_low_part_g32, src_high_part,
+ new_shift_amout));
+ emit_move_insn (dst_high_part_g32, const0_rtx);
+ }
+ else
+ {
+ /*
+ if (shiftamount < 32)
+ dst_low_part = wext (src, shiftamount)
+ dst_high_part = src_high_part >> shiftamount
+ else
+ dst_low_part = src_high_part >> (shiftamount & 0x1f)
+ # shift 31 for sign extend
+ dst_high_part = src_high_part >> 31
+ */
+ emit_insn (gen_wext (dst_low_part_l32, src, shiftamount));
+ emit_insn (gen_ashrsi3 (dst_high_part_l32, src_high_part,
+ shiftamount));
+
+ emit_insn (gen_andsi3 (new_shift_amout, shiftamount, GEN_INT (0x1f)));
+ emit_insn (gen_ashrsi3 (dst_low_part_g32, src_high_part,
+ new_shift_amout));
+ emit_insn (gen_ashrsi3 (dst_high_part_g32, src_high_part,
+ GEN_INT (31)));
+ }
+
+ emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32)));
+
+ emit_insn (gen_cmovnsi (dst_low_part, select_reg,
+ dst_low_part_l32, dst_low_part_g32));
+ emit_insn (gen_cmovnsi (dst_high_part, select_reg,
+ dst_high_part_l32, dst_high_part_g32));
+ }
+}
+
/* ------------------------------------------------------------------------ */
/* Auxiliary function for expand RTL pattern. */
@@ -1195,8 +1310,166 @@
}
}
+enum nds32_expand_result_type
+nds32_expand_extv (rtx *operands)
+{
+ gcc_assert (CONST_INT_P (operands[2]) && CONST_INT_P (operands[3]));
+ HOST_WIDE_INT width = INTVAL (operands[2]);
+ HOST_WIDE_INT bitpos = INTVAL (operands[3]);
+ rtx dst = operands[0];
+ rtx src = operands[1];
+
+ if (MEM_P (src)
+ && width == 32
+ && (bitpos % BITS_PER_UNIT) == 0
+ && GET_MODE_BITSIZE (GET_MODE (dst)) == width)
+ {
+ rtx newmem = adjust_address (src, GET_MODE (dst),
+ bitpos / BITS_PER_UNIT);
+
+ rtx base_addr = force_reg (Pmode, XEXP (newmem, 0));
+
+ emit_insn (gen_unaligned_loadsi (dst, base_addr));
+
+ return EXPAND_DONE;
+ }
+ return EXPAND_FAIL;
+}
+
+enum nds32_expand_result_type
+nds32_expand_insv (rtx *operands)
+{
+ gcc_assert (CONST_INT_P (operands[1]) && CONST_INT_P (operands[2]));
+ HOST_WIDE_INT width = INTVAL (operands[1]);
+ HOST_WIDE_INT bitpos = INTVAL (operands[2]);
+ rtx dst = operands[0];
+ rtx src = operands[3];
+
+ if (MEM_P (dst)
+ && width == 32
+ && (bitpos % BITS_PER_UNIT) == 0
+ && GET_MODE_BITSIZE (GET_MODE (src)) == width)
+ {
+ rtx newmem = adjust_address (dst, GET_MODE (src),
+ bitpos / BITS_PER_UNIT);
+
+ rtx base_addr = force_reg (Pmode, XEXP (newmem, 0));
+
+ emit_insn (gen_unaligned_storesi (base_addr, src));
+
+ return EXPAND_DONE;
+ }
+ return EXPAND_FAIL;
+}
+
/* ------------------------------------------------------------------------ */
+/* Function to generate PC relative jump table.
+ Refer to nds32.md for more details.
+
+ The following is the sample for the case that diff value
+ can be presented in '.short' size.
+
+ addi $r1, $r1, -(case_lower_bound)
+ slti $ta, $r1, (case_number)
+ beqz $ta, .L_skip_label
+
+ la $ta, .L35 ! get jump table address
+ lh $r1, [$ta + $r1 << 1] ! load symbol diff from jump table entry
+ addi $ta, $r1, $ta
+ jr5 $ta
+
+ ! jump table entry
+ L35:
+ .short .L25-.L35
+ .short .L26-.L35
+ .short .L27-.L35
+ .short .L28-.L35
+ .short .L29-.L35
+ .short .L30-.L35
+ .short .L31-.L35
+ .short .L32-.L35
+ .short .L33-.L35
+ .short .L34-.L35 */
+const char *
+nds32_output_casesi_pc_relative (rtx *operands)
+{
+ machine_mode mode;
+ rtx diff_vec;
+
+ diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[1])));
+
+ gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
+
+ /* Step C: "t <-- operands[1]". */
+ if (flag_pic)
+ {
+ output_asm_insn ("sethi\t$ta, hi20(%l1@GOTOFF)", operands);
+ output_asm_insn ("ori\t$ta, $ta, lo12(%l1@GOTOFF)", operands);
+ output_asm_insn ("add\t$ta, $ta, $gp", operands);
+ }
+ else
+ output_asm_insn ("la\t$ta, %l1", operands);
+
+ /* Get the mode of each element in the difference vector. */
+ mode = GET_MODE (diff_vec);
+
+ /* Step D: "z <-- (mem (plus (operands[0] << m) t))",
+ where m is 0, 1, or 2 to load address-diff value from table. */
+ switch (mode)
+ {
+ case E_QImode:
+ output_asm_insn ("lb\t%2, [$ta + %0 << 0]", operands);
+ break;
+ case E_HImode:
+ output_asm_insn ("lh\t%2, [$ta + %0 << 1]", operands);
+ break;
+ case E_SImode:
+ output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ /* Step E: "t <-- z + t".
+ Add table label_ref with address-diff value to
+ obtain target case address. */
+ output_asm_insn ("add\t$ta, %2, $ta", operands);
+
+ /* Step F: jump to target with register t. */
+ if (TARGET_16_BIT)
+ return "jr5\t$ta";
+ else
+ return "jr\t$ta";
+}
+
+/* Function to generate normal jump table. */
+const char *
+nds32_output_casesi (rtx *operands)
+{
+ /* Step C: "t <-- operands[1]". */
+ if (flag_pic)
+ {
+ output_asm_insn ("sethi\t$ta, hi20(%l1@GOTOFF)", operands);
+ output_asm_insn ("ori\t$ta, $ta, lo12(%l1@GOTOFF)", operands);
+ output_asm_insn ("add\t$ta, $ta, $gp", operands);
+ }
+ else
+ output_asm_insn ("la\t$ta, %l1", operands);
+
+ /* Step D: "z <-- (mem (plus (operands[0] << 2) t))". */
+ output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands);
+
+ /* No need to perform Step E, which is only used for
+ pc relative jump table. */
+
+ /* Step F: jump to target with register z. */
+ if (TARGET_16_BIT)
+ return "jr5\t%2";
+ else
+ return "jr\t%2";
+}
+
/* Function to return memory format. */
enum nds32_16bit_address_type
nds32_mem_format (rtx op)
@@ -1757,11 +2030,8 @@
/* If we step here, we are going to do v3push or multiple push operation. */
- /* The v3push/v3pop instruction should only be applied on
- none-isr and none-variadic function. */
- if (TARGET_V3PUSH
- && !nds32_isr_function_p (current_function_decl)
- && (cfun->machine->va_args_size == 0))
+ /* Refer to nds32.h, where we comment when push25/pop25 are available. */
+ if (NDS32_V3PUSH_AVAILABLE_P)
{
/* For stack v3push:
operands[0]: Re
@@ -1881,11 +2151,8 @@
/* If we step here, we are going to do v3pop or multiple pop operation. */
- /* The v3push/v3pop instruction should only be applied on
- none-isr and none-variadic function. */
- if (TARGET_V3PUSH
- && !nds32_isr_function_p (current_function_decl)
- && (cfun->machine->va_args_size == 0))
+ /* Refer to nds32.h, where we comment when push25/pop25 are available. */
+ if (NDS32_V3PUSH_AVAILABLE_P)
{
/* For stack v3pop:
operands[0]: Re
@@ -2022,77 +2289,6 @@
return "";
}
-/* Function to generate PC relative jump table.
- Refer to nds32.md for more details.
-
- The following is the sample for the case that diff value
- can be presented in '.short' size.
-
- addi $r1, $r1, -(case_lower_bound)
- slti $ta, $r1, (case_number)
- beqz $ta, .L_skip_label
-
- la $ta, .L35 ! get jump table address
- lh $r1, [$ta + $r1 << 1] ! load symbol diff from jump table entry
- addi $ta, $r1, $ta
- jr5 $ta
-
- ! jump table entry
- L35:
- .short .L25-.L35
- .short .L26-.L35
- .short .L27-.L35
- .short .L28-.L35
- .short .L29-.L35
- .short .L30-.L35
- .short .L31-.L35
- .short .L32-.L35
- .short .L33-.L35
- .short .L34-.L35 */
-const char *
-nds32_output_casesi_pc_relative (rtx *operands)
-{
- machine_mode mode;
- rtx diff_vec;
-
- diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[1])));
-
- gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
-
- /* Step C: "t <-- operands[1]". */
- output_asm_insn ("la\t$ta, %l1", operands);
-
- /* Get the mode of each element in the difference vector. */
- mode = GET_MODE (diff_vec);
-
- /* Step D: "z <-- (mem (plus (operands[0] << m) t))",
- where m is 0, 1, or 2 to load address-diff value from table. */
- switch (mode)
- {
- case E_QImode:
- output_asm_insn ("lb\t%2, [$ta + %0 << 0]", operands);
- break;
- case E_HImode:
- output_asm_insn ("lh\t%2, [$ta + %0 << 1]", operands);
- break;
- case E_SImode:
- output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands);
- break;
- default:
- gcc_unreachable ();
- }
-
- /* Step E: "t <-- z + t".
- Add table label_ref with address-diff value to
- obtain target case address. */
- output_asm_insn ("add\t$ta, %2, $ta", operands);
-
- /* Step F: jump to target with register t. */
- if (TARGET_16_BIT)
- return "jr5\t$ta";
- else
- return "jr\t$ta";
-}
/* output a float load instruction */
const char *
@@ -2250,52 +2446,51 @@
return "";
}
-/* Function to generate normal jump table. */
const char *
-nds32_output_casesi (rtx *operands)
+nds32_output_smw_single_word (rtx *operands)
{
- /* Step C: "t <-- operands[1]". */
- output_asm_insn ("la\t$ta, %l1", operands);
-
- /* Step D: "z <-- (mem (plus (operands[0] << 2) t))". */
- output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands);
-
- /* No need to perform Step E, which is only used for
- pc relative jump table. */
+ char buff[100];
+ unsigned regno;
+ int enable4;
+ bool update_base_p;
+ rtx base_addr = operands[0];
+ rtx base_reg;
+ rtx otherops[2];
- /* Step F: jump to target with register z. */
- if (TARGET_16_BIT)
- return "jr5\t%2";
+ if (REG_P (XEXP (base_addr, 0)))
+ {
+ update_base_p = false;
+ base_reg = XEXP (base_addr, 0);
+ }
else
- return "jr\t%2";
-}
+ {
+ update_base_p = true;
+ base_reg = XEXP (XEXP (base_addr, 0), 0);
+ }
-/* Auxiliary functions for lwm/smw. */
-bool
-nds32_valid_smw_lwm_base_p (rtx op)
-{
- rtx base_addr;
+ const char *update_base = update_base_p ? "m" : "";
- if (!MEM_P (op))
- return false;
+ regno = REGNO (operands[1]);
- base_addr = XEXP (op, 0);
+ otherops[0] = base_reg;
+ otherops[1] = operands[1];
- if (REG_P (base_addr))
- return true;
+ if (regno >= 28)
+ {
+ enable4 = nds32_regno_to_enable4 (regno);
+ sprintf (buff, "smw.bi%s\t$sp, [%%0], $sp, %x", update_base, enable4);
+ }
else
{
- if (GET_CODE (base_addr) == POST_INC
- && REG_P (XEXP (base_addr, 0)))
- return true;
+ sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1", update_base);
}
-
- return false;
+ output_asm_insn (buff, otherops);
+ return "";
}
/* ------------------------------------------------------------------------ */
const char *
-nds32_output_smw_single_word (rtx *operands)
+nds32_output_smw_double_word (rtx *operands)
{
char buff[100];
unsigned regno;
@@ -2303,7 +2498,7 @@
bool update_base_p;
rtx base_addr = operands[0];
rtx base_reg;
- rtx otherops[2];
+ rtx otherops[3];
if (REG_P (XEXP (base_addr, 0)))
{
@@ -2322,15 +2517,22 @@
otherops[0] = base_reg;
otherops[1] = operands[1];
+ otherops[2] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);;
if (regno >= 28)
{
- enable4 = nds32_regno_to_enable4 (regno);
+ enable4 = nds32_regno_to_enable4 (regno)
+ | nds32_regno_to_enable4 (regno + 1);
sprintf (buff, "smw.bi%s\t$sp, [%%0], $sp, %x", update_base, enable4);
}
+ else if (regno == 27)
+ {
+ enable4 = nds32_regno_to_enable4 (regno + 1);
+ sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1, %x", update_base, enable4);
+ }
else
{
- sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1", update_base);
+ sprintf (buff, "smw.bi%s\t%%1, [%%0], %%2", update_base);
}
output_asm_insn (buff, otherops);
return "";
@@ -2415,16 +2617,17 @@
if (mode == DImode)
{
/* Load doubleword, we need two registers to access. */
- reg[0] = simplify_gen_subreg (SImode, operands[0],
- GET_MODE (operands[0]), 0);
- reg[1] = simplify_gen_subreg (SImode, operands[0],
- GET_MODE (operands[0]), 4);
+ reg[0] = nds32_di_low_part_subreg (operands[0]);
+ reg[1] = nds32_di_high_part_subreg (operands[0]);
/* A register only store 4 byte. */
width = GET_MODE_SIZE (SImode) - 1;
}
else
{
- reg[0] = operands[0];
+ if (VECTOR_MODE_P (mode))
+ reg[0] = gen_reg_rtx (SImode);
+ else
+ reg[0] = operands[0];
}
for (num_reg = (mode == DImode) ? 2 : 1; num_reg > 0; num_reg--)
@@ -2466,6 +2669,8 @@
offset = offset + offset_adj;
}
}
+ if (VECTOR_MODE_P (mode))
+ convert_move (operands[0], reg[0], false);
}
void
@@ -2499,16 +2704,20 @@
if (mode == DImode)
{
/* Load doubleword, we need two registers to access. */
- reg[0] = simplify_gen_subreg (SImode, operands[1],
- GET_MODE (operands[1]), 0);
- reg[1] = simplify_gen_subreg (SImode, operands[1],
- GET_MODE (operands[1]), 4);
+ reg[0] = nds32_di_low_part_subreg (operands[1]);
+ reg[1] = nds32_di_high_part_subreg (operands[1]);
/* A register only store 4 byte. */
width = GET_MODE_SIZE (SImode) - 1;
}
else
{
- reg[0] = operands[1];
+ if (VECTOR_MODE_P (mode))
+ {
+ reg[0] = gen_reg_rtx (SImode);
+ convert_move (reg[0], operands[1], false);
+ }
+ else
+ reg[0] = operands[1];
}
for (num_reg = (mode == DImode) ? 2 : 1; num_reg > 0; num_reg--)
@@ -2765,6 +2974,36 @@
return "";
}
+const char *
+nds32_output_unpkd8 (rtx output, rtx input,
+ rtx high_idx_rtx, rtx low_idx_rtx,
+ bool signed_p)
+{
+ char pattern[100];
+ rtx output_operands[2];
+ HOST_WIDE_INT high_idx, low_idx;
+ high_idx = INTVAL (high_idx_rtx);
+ low_idx = INTVAL (low_idx_rtx);
+
+ gcc_assert (high_idx >= 0 && high_idx <= 3);
+ gcc_assert (low_idx >= 0 && low_idx <= 3);
+
+ /* We only have 10, 20, 30 and 31. */
+ if ((low_idx != 0 || high_idx == 0) &&
+ !(low_idx == 1 && high_idx == 3))
+ return "#";
+
+ char sign_char = signed_p ? 's' : 'z';
+
+ sprintf (pattern,
+ "%cunpkd8" HOST_WIDE_INT_PRINT_DEC HOST_WIDE_INT_PRINT_DEC "\t%%0, %%1",
+ sign_char, high_idx, low_idx);
+ output_operands[0] = output;
+ output_operands[1] = input;
+ output_asm_insn (pattern, output_operands);
+ return "";
+}
+
/* Return true if SYMBOL_REF X binds locally. */
static bool
@@ -2782,22 +3021,15 @@
char pattern[100];
bool noreturn_p;
- if (GET_CODE (symbol) == CONST)
- {
- symbol= XEXP (symbol, 0);
-
- if (GET_CODE (symbol) == PLUS)
- symbol = XEXP (symbol, 0);
- }
-
- gcc_assert (GET_CODE (symbol) == SYMBOL_REF
- || REG_P (symbol));
-
if (nds32_long_call_p (symbol))
strcpy (pattern, long_call);
else
strcpy (pattern, call);
+ if (flag_pic && CONSTANT_P (symbol)
+ && !nds32_symbol_binds_local_p (symbol))
+ strcat (pattern, "@PLT");
+
if (align_p)
strcat (pattern, "\n\t.align 2");
@@ -2815,6 +3047,91 @@
return "";
}
+bool
+nds32_need_split_sms_p (rtx in0_idx0, rtx in1_idx0,
+ rtx in0_idx1, rtx in1_idx1)
+{
+ /* smds or smdrs. */
+ if (INTVAL (in0_idx0) == INTVAL (in1_idx0)
+ && INTVAL (in0_idx1) == INTVAL (in1_idx1)
+ && INTVAL (in0_idx0) != INTVAL (in0_idx1))
+ return false;
+
+ /* smxds. */
+ if (INTVAL (in0_idx0) != INTVAL (in0_idx1)
+ && INTVAL (in1_idx0) != INTVAL (in1_idx1))
+ return false;
+
+ return true;
+}
+
+const char *
+nds32_output_sms (rtx in0_idx0, rtx in1_idx0,
+ rtx in0_idx1, rtx in1_idx1)
+{
+ if (nds32_need_split_sms_p (in0_idx0, in1_idx0,
+ in0_idx1, in1_idx1))
+ return "#";
+ /* out = in0[in0_idx0] * in1[in1_idx0] - in0[in0_idx1] * in1[in1_idx1] */
+
+ /* smds or smdrs. */
+ if (INTVAL (in0_idx0) == INTVAL (in1_idx0)
+ && INTVAL (in0_idx1) == INTVAL (in1_idx1)
+ && INTVAL (in0_idx0) != INTVAL (in0_idx1))
+ {
+ if (INTVAL (in0_idx0) == 0)
+ {
+ if (TARGET_BIG_ENDIAN)
+ return "smds\t%0, %1, %2";
+ else
+ return "smdrs\t%0, %1, %2";
+ }
+ else
+ {
+ if (TARGET_BIG_ENDIAN)
+ return "smdrs\t%0, %1, %2";
+ else
+ return "smds\t%0, %1, %2";
+ }
+ }
+
+ if (INTVAL (in0_idx0) != INTVAL (in0_idx1)
+ && INTVAL (in1_idx0) != INTVAL (in1_idx1))
+ {
+ if (INTVAL (in0_idx0) == 1)
+ {
+ if (TARGET_BIG_ENDIAN)
+ return "smxds\t%0, %2, %1";
+ else
+ return "smxds\t%0, %1, %2";
+ }
+ else
+ {
+ if (TARGET_BIG_ENDIAN)
+ return "smxds\t%0, %1, %2";
+ else
+ return "smxds\t%0, %2, %1";
+ }
+ }
+
+ gcc_unreachable ();
+ return "";
+}
+
+void
+nds32_split_sms (rtx out, rtx in0, rtx in1,
+ rtx in0_idx0, rtx in1_idx0,
+ rtx in0_idx1, rtx in1_idx1)
+{
+ rtx result0 = gen_reg_rtx (SImode);
+ rtx result1 = gen_reg_rtx (SImode);
+ emit_insn (gen_mulhisi3v (result0, in0, in1,
+ in0_idx0, in1_idx0));
+ emit_insn (gen_mulhisi3v (result1, in0, in1,
+ in0_idx1, in1_idx1));
+ emit_insn (gen_subsi3 (out, result0, result1));
+}
+
/* Spilt a doubleword instrucion to two single word instructions. */
void
nds32_spilt_doubleword (rtx *operands, bool load_p)
@@ -2846,16 +3163,30 @@
/* generate low_part and high_part memory format:
low_part: (post_modify ((reg) (plus (reg) (const 4)))
high_part: (post_modify ((reg) (plus (reg) (const -12))) */
- low_part[mem] = gen_frame_mem (SImode,
- gen_rtx_POST_MODIFY (Pmode, sub_mem,
- gen_rtx_PLUS (Pmode,
- sub_mem,
- GEN_INT (4))));
- high_part[mem] = gen_frame_mem (SImode,
- gen_rtx_POST_MODIFY (Pmode, sub_mem,
- gen_rtx_PLUS (Pmode,
- sub_mem,
- GEN_INT (-12))));
+ low_part[mem] = gen_rtx_MEM (SImode,
+ gen_rtx_POST_MODIFY (Pmode, sub_mem,
+ gen_rtx_PLUS (Pmode,
+ sub_mem,
+ GEN_INT (4))));
+ high_part[mem] = gen_rtx_MEM (SImode,
+ gen_rtx_POST_MODIFY (Pmode, sub_mem,
+ gen_rtx_PLUS (Pmode,
+ sub_mem,
+ GEN_INT (-12))));
+ }
+ else if (GET_CODE (sub_mem) == POST_INC)
+ {
+ /* memory format is (post_inc (reg)),
+ so that extract (reg) from the (post_inc (reg)) pattern. */
+ sub_mem = XEXP (sub_mem, 0);
+
+ /* generate low_part and high_part memory format:
+ low_part: (post_inc (reg))
+ high_part: (post_inc (reg)) */
+ low_part[mem] = gen_rtx_MEM (SImode,
+ gen_rtx_POST_INC (Pmode, sub_mem));
+ high_part[mem] = gen_rtx_MEM (SImode,
+ gen_rtx_POST_INC (Pmode, sub_mem));
}
else if (GET_CODE (sub_mem) == POST_MODIFY)
{
@@ -2872,14 +3203,14 @@
/* Generate low_part and high_part memory format:
low_part: (post_modify ((reg) (plus (reg) (const)))
high_part: ((plus (reg) (const 4))) */
- low_part[mem] = gen_frame_mem (SImode,
- gen_rtx_POST_MODIFY (Pmode, post_mem,
- gen_rtx_PLUS (Pmode,
- post_mem,
- post_val)));
- high_part[mem] = gen_frame_mem (SImode, plus_constant (Pmode,
- post_mem,
- 4));
+ low_part[mem] = gen_rtx_MEM (SImode,
+ gen_rtx_POST_MODIFY (Pmode, post_mem,
+ gen_rtx_PLUS (Pmode,
+ post_mem,
+ post_val)));
+ high_part[mem] = gen_rtx_MEM (SImode, plus_constant (Pmode,
+ post_mem,
+ 4));
}
else
{
@@ -2924,11 +3255,516 @@
}
}
+void
+nds32_split_ashiftdi3 (rtx dst, rtx src, rtx shiftamount)
+{
+ rtx src_high_part, src_low_part;
+ rtx dst_high_part, dst_low_part;
+
+ dst_high_part = nds32_di_high_part_subreg (dst);
+ dst_low_part = nds32_di_low_part_subreg (dst);
+
+ src_high_part = nds32_di_high_part_subreg (src);
+ src_low_part = nds32_di_low_part_subreg (src);
+
+ /* We need to handle shift more than 32 bit!!!! */
+ if (CONST_INT_P (shiftamount))
+ {
+ if (INTVAL (shiftamount) < 32)
+ {
+ rtx ext_start;
+ ext_start = gen_int_mode(32 - INTVAL (shiftamount), SImode);
+
+ emit_insn (gen_wext (dst_high_part, src, ext_start));
+ emit_insn (gen_ashlsi3 (dst_low_part, src_low_part, shiftamount));
+ }
+ else
+ {
+ rtx new_shift_amout = gen_int_mode(INTVAL (shiftamount) - 32, SImode);
+
+ emit_insn (gen_ashlsi3 (dst_high_part, src_low_part,
+ new_shift_amout));
+
+ emit_move_insn (dst_low_part, GEN_INT (0));
+ }
+ }
+ else
+ {
+ rtx dst_low_part_l32, dst_high_part_l32;
+ rtx dst_low_part_g32, dst_high_part_g32;
+ rtx new_shift_amout, select_reg;
+ dst_low_part_l32 = gen_reg_rtx (SImode);
+ dst_high_part_l32 = gen_reg_rtx (SImode);
+ dst_low_part_g32 = gen_reg_rtx (SImode);
+ dst_high_part_g32 = gen_reg_rtx (SImode);
+ new_shift_amout = gen_reg_rtx (SImode);
+ select_reg = gen_reg_rtx (SImode);
+
+ rtx ext_start;
+ ext_start = gen_reg_rtx (SImode);
+
+ /*
+ if (shiftamount < 32)
+ dst_low_part = src_low_part << shiftamout
+ dst_high_part = wext (src, 32 - shiftamount)
+ # wext can't handle wext (src, 32) since it's only take rb[0:4]
+ # for extract.
+ dst_high_part = shiftamount == 0 ? src_high_part : dst_high_part
+ else
+ dst_low_part = 0
+ dst_high_part = src_low_part << shiftamount & 0x1f
+ */
+
+ emit_insn (gen_subsi3 (ext_start,
+ gen_int_mode (32, SImode),
+ shiftamount));
+ emit_insn (gen_wext (dst_high_part_l32, src, ext_start));
+
+ /* Handle for shiftamout == 0. */
+ emit_insn (gen_cmovzsi (dst_high_part_l32, shiftamount,
+ src_high_part, dst_high_part_l32));
+
+ emit_insn (gen_ashlsi3 (dst_low_part_l32, src_low_part, shiftamount));
+
+ emit_move_insn (dst_low_part_g32, const0_rtx);
+ emit_insn (gen_andsi3 (new_shift_amout, shiftamount, GEN_INT (0x1f)));
+ emit_insn (gen_ashlsi3 (dst_high_part_g32, src_low_part,
+ new_shift_amout));
+
+ emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32)));
+
+ emit_insn (gen_cmovnsi (dst_low_part, select_reg,
+ dst_low_part_l32, dst_low_part_g32));
+ emit_insn (gen_cmovnsi (dst_high_part, select_reg,
+ dst_high_part_l32, dst_high_part_g32));
+ }
+}
+
+void
+nds32_split_ashiftrtdi3 (rtx dst, rtx src, rtx shiftamount)
+{
+ nds32_split_shiftrtdi3 (dst, src, shiftamount, false);
+}
+
+void
+nds32_split_lshiftrtdi3 (rtx dst, rtx src, rtx shiftamount)
+{
+ nds32_split_shiftrtdi3 (dst, src, shiftamount, true);
+}
+
+void
+nds32_split_rotatertdi3 (rtx dst, rtx src, rtx shiftamount)
+{
+ rtx dst_low_part_l32, dst_high_part_l32;
+ rtx dst_low_part_g32, dst_high_part_g32;
+ rtx select_reg, low5bit, low5bit_inv, minus32sa;
+ rtx dst_low_part_g32_tmph;
+ rtx dst_low_part_g32_tmpl;
+ rtx dst_high_part_l32_tmph;
+ rtx dst_high_part_l32_tmpl;
+
+ rtx src_low_part, src_high_part;
+ rtx dst_high_part, dst_low_part;
+
+ shiftamount = force_reg (SImode, shiftamount);
+
+ emit_insn (gen_andsi3 (shiftamount,
+ shiftamount,
+ gen_int_mode (0x3f, SImode)));
+
+ dst_high_part = nds32_di_high_part_subreg (dst);
+ dst_low_part = nds32_di_low_part_subreg (dst);
+
+ src_high_part = nds32_di_high_part_subreg (src);
+ src_low_part = nds32_di_low_part_subreg (src);
+
+ dst_low_part_l32 = gen_reg_rtx (SImode);
+ dst_high_part_l32 = gen_reg_rtx (SImode);
+ dst_low_part_g32 = gen_reg_rtx (SImode);
+ dst_high_part_g32 = gen_reg_rtx (SImode);
+ low5bit = gen_reg_rtx (SImode);
+ low5bit_inv = gen_reg_rtx (SImode);
+ minus32sa = gen_reg_rtx (SImode);
+ select_reg = gen_reg_rtx (SImode);
+
+ dst_low_part_g32_tmph = gen_reg_rtx (SImode);
+ dst_low_part_g32_tmpl = gen_reg_rtx (SImode);
+
+ dst_high_part_l32_tmph = gen_reg_rtx (SImode);
+ dst_high_part_l32_tmpl = gen_reg_rtx (SImode);
+
+ emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32)));
+
+ /* if shiftamount < 32
+ dst_low_part = wext(src, shiftamount)
+ else
+ dst_low_part = ((src_high_part >> (shiftamount & 0x1f))
+ | (src_low_part << (32 - (shiftamount & 0x1f))))
+ */
+ emit_insn (gen_andsi3 (low5bit, shiftamount, gen_int_mode (0x1f, SImode)));
+ emit_insn (gen_subsi3 (low5bit_inv, gen_int_mode (32, SImode), low5bit));
+
+ emit_insn (gen_wext (dst_low_part_l32, src, shiftamount));
+
+ emit_insn (gen_lshrsi3 (dst_low_part_g32_tmpl, src_high_part, low5bit));
+ emit_insn (gen_ashlsi3 (dst_low_part_g32_tmph, src_low_part, low5bit_inv));
+
+ emit_insn (gen_iorsi3 (dst_low_part_g32,
+ dst_low_part_g32_tmpl,
+ dst_low_part_g32_tmph));
+
+ emit_insn (gen_cmovnsi (dst_low_part, select_reg,
+ dst_low_part_l32, dst_low_part_g32));
+
+ /* if shiftamount < 32
+ dst_high_part = ((src_high_part >> shiftamount)
+ | (src_low_part << (32 - shiftamount)))
+ dst_high_part = shiftamount == 0 ? src_high_part : dst_high_part
+ else
+ dst_high_part = wext(src, shiftamount & 0x1f)
+ */
+
+ emit_insn (gen_subsi3 (minus32sa, gen_int_mode (32, SImode), shiftamount));
+
+ emit_insn (gen_lshrsi3 (dst_high_part_l32_tmpl, src_high_part, shiftamount));
+ emit_insn (gen_ashlsi3 (dst_high_part_l32_tmph, src_low_part, minus32sa));
+
+ emit_insn (gen_iorsi3 (dst_high_part_l32,
+ dst_high_part_l32_tmpl,
+ dst_high_part_l32_tmph));
+
+ emit_insn (gen_cmovzsi (dst_high_part_l32, shiftamount,
+ src_high_part, dst_high_part_l32));
+
+ emit_insn (gen_wext (dst_high_part_g32, src, low5bit));
+
+ emit_insn (gen_cmovnsi (dst_high_part, select_reg,
+ dst_high_part_l32, dst_high_part_g32));
+}
+
+/* Return true if OP contains a symbol reference. */
+bool
+symbolic_reference_mentioned_p (rtx op)
+{
+ const char *fmt;
+ int i;
+
+ if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
+ return true;
+
+ fmt = GET_RTX_FORMAT (GET_CODE (op));
+ for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'E')
+ {
+ int j;
+
+ for (j = XVECLEN (op, i) - 1; j >= 0; j--)
+ if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
+ return true;
+ }
+
+ else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Expand PIC code for @GOTOFF and @GOT.
+
+ Example for @GOTOFF:
+
+ la $r0, symbol@GOTOFF
+ -> sethi $ta, hi20(symbol@GOTOFF)
+ ori $ta, $ta, lo12(symbol@GOTOFF)
+ add $r0, $ta, $gp
+
+ Example for @GOT:
+
+ la $r0, symbol@GOT
+ -> sethi $ta, hi20(symbol@GOT)
+ ori $ta, $ta, lo12(symbol@GOT)
+ lw $r0, [$ta + $gp]
+*/
+rtx
+nds32_legitimize_pic_address (rtx x)
+{
+ rtx addr = x;
+ rtx reg = gen_reg_rtx (Pmode);
+ rtx pat;
+
+ if (GET_CODE (x) == LABEL_REF
+ || (GET_CODE (x) == SYMBOL_REF
+ && (CONSTANT_POOL_ADDRESS_P (x)
+ || SYMBOL_REF_LOCAL_P (x))))
+ {
+ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOTOFF);
+ addr = gen_rtx_CONST (SImode, addr);
+ emit_insn (gen_sethi (reg, addr));
+ emit_insn (gen_lo_sum (reg, reg, addr));
+ x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx);
+ }
+ else if (GET_CODE (x) == SYMBOL_REF)
+ {
+ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOT);
+ addr = gen_rtx_CONST (SImode, addr);
+ emit_insn (gen_sethi (reg, addr));
+ emit_insn (gen_lo_sum (reg, reg, addr));
+
+ x = gen_const_mem (SImode, gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
+ reg));
+ }
+ else if (GET_CODE (x) == CONST)
+ {
+ /* We don't split constant in expand_pic_move because GOTOFF can combine
+ the addend with the symbol. */
+ addr = XEXP (x, 0);
+ gcc_assert (GET_CODE (addr) == PLUS);
+
+ rtx op0 = XEXP (addr, 0);
+ rtx op1 = XEXP (addr, 1);
+
+ if ((GET_CODE (op0) == LABEL_REF
+ || (GET_CODE (op0) == SYMBOL_REF
+ && (CONSTANT_POOL_ADDRESS_P (op0)
+ || SYMBOL_REF_LOCAL_P (op0))))
+ && GET_CODE (op1) == CONST_INT)
+ {
+ pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), UNSPEC_GOTOFF);
+ pat = gen_rtx_PLUS (Pmode, pat, op1);
+ pat = gen_rtx_CONST (Pmode, pat);
+ emit_insn (gen_sethi (reg, pat));
+ emit_insn (gen_lo_sum (reg, reg, pat));
+ x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx);
+ }
+ else if (GET_CODE (op0) == SYMBOL_REF
+ && GET_CODE (op1) == CONST_INT)
+ {
+ /* This is a constant offset from a @GOT symbol reference. */
+ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), UNSPEC_GOT);
+ addr = gen_rtx_CONST (SImode, addr);
+ emit_insn (gen_sethi (reg, addr));
+ emit_insn (gen_lo_sum (reg, reg, addr));
+ addr = gen_const_mem (SImode, gen_rtx_PLUS (Pmode,
+ pic_offset_table_rtx,
+ reg));
+ emit_move_insn (reg, addr);
+ if (satisfies_constraint_Is15 (op1))
+ x = gen_rtx_PLUS (Pmode, reg, op1);
+ else
+ {
+ rtx tmp_reg = gen_reg_rtx (SImode);
+ emit_insn (gen_movsi (tmp_reg, op1));
+ x = gen_rtx_PLUS (Pmode, reg, tmp_reg);
+ }
+ }
+ else
+ {
+ /* Don't handle this pattern. */
+ debug_rtx (x);
+ gcc_unreachable ();
+ }
+ }
+ return x;
+}
+
+void
+nds32_expand_pic_move (rtx *operands)
+{
+ rtx src;
+
+ src = nds32_legitimize_pic_address (operands[1]);
+ emit_move_insn (operands[0], src);
+}
+
+/* Expand ICT symbol.
+ Example for @ICT and ICT model=large:
+
+ la $r0, symbol@ICT
+ -> sethi $rt, hi20(symbol@ICT)
+ lwi $r0, [$rt + lo12(symbol@ICT)]
+
+*/
+rtx
+nds32_legitimize_ict_address (rtx x)
+{
+ rtx symbol = x;
+ rtx addr = x;
+ rtx reg = gen_reg_rtx (Pmode);
+ gcc_assert (GET_CODE (x) == SYMBOL_REF
+ && nds32_indirect_call_referenced_p (x));
+
+ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, symbol), UNSPEC_ICT);
+ addr = gen_rtx_CONST (SImode, addr);
+ emit_insn (gen_sethi (reg, addr));
+
+ x = gen_const_mem (SImode, gen_rtx_LO_SUM (Pmode, reg, addr));
+
+ return x;
+}
+
+void
+nds32_expand_ict_move (rtx *operands)
+{
+ rtx src = operands[1];
+
+ src = nds32_legitimize_ict_address (src);
+
+ emit_move_insn (operands[0], src);
+}
+
+/* Return true X is a indirect call symbol. */
+bool
+nds32_indirect_call_referenced_p (rtx x)
+{
+ if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_ICT)
+ x = XVECEXP (x, 0, 0);
+
+ if (GET_CODE (x) == SYMBOL_REF)
+ {
+ tree decl = SYMBOL_REF_DECL (x);
+
+ return decl
+ && (lookup_attribute("indirect_call",
+ DECL_ATTRIBUTES(decl))
+ != NULL);
+ }
+
+ return false;
+}
+
/* Return true X is need use long call. */
bool
nds32_long_call_p (rtx symbol)
{
- return TARGET_CMODEL_LARGE;
+ if (nds32_indirect_call_referenced_p (symbol))
+ return TARGET_ICT_MODEL_LARGE;
+ else
+ return TARGET_CMODEL_LARGE;
+}
+
+/* Return true if X contains a thread-local symbol. */
+bool
+nds32_tls_referenced_p (rtx x)
+{
+ if (!targetm.have_tls)
+ return false;
+
+ if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
+ x = XEXP (XEXP (x, 0), 0);
+
+ if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x))
+ return true;
+
+ return false;
+}
+
+/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
+ this (thread-local) address. */
+rtx
+nds32_legitimize_tls_address (rtx x)
+{
+ rtx tmp_reg;
+ rtx tp_reg = gen_rtx_REG (Pmode, TP_REGNUM);
+ rtx pat, insns, reg0;
+
+ if (GET_CODE (x) == SYMBOL_REF)
+ switch (SYMBOL_REF_TLS_MODEL (x))
+ {
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ /* Emit UNSPEC_TLS_DESC rather than expand rtl directly because spill
+ may destroy the define-use chain anylysis to insert relax_hint. */
+ if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_GLOBAL_DYNAMIC)
+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSGD);
+ else
+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLD);
+
+ pat = gen_rtx_CONST (SImode, pat);
+ reg0 = gen_rtx_REG (Pmode, 0);
+ /* If we can confirm all clobber reigsters, it doesn't have to use call
+ instruction. */
+ insns = emit_call_insn (gen_tls_desc (pat, GEN_INT (0)));
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insns), pic_offset_table_rtx);
+ RTL_CONST_CALL_P (insns) = 1;
+ tmp_reg = gen_reg_rtx (SImode);
+ emit_move_insn (tmp_reg, reg0);
+ x = tmp_reg;
+ break;
+
+ case TLS_MODEL_INITIAL_EXEC:
+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSIE);
+ tmp_reg = gen_reg_rtx (SImode);
+ pat = gen_rtx_CONST (SImode, pat);
+ emit_insn (gen_tls_ie (tmp_reg, pat, GEN_INT (0)));
+ if (flag_pic)
+ emit_use (pic_offset_table_rtx);
+ x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
+ break;
+
+ case TLS_MODEL_LOCAL_EXEC:
+ /* Expand symbol_ref@TPOFF':
+ sethi $ta, hi20(symbol_ref@TPOFF)
+ ori $ta, $ta, lo12(symbol_ref@TPOFF)
+ add $r0, $ta, $tp */
+ tmp_reg = gen_reg_rtx (SImode);
+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLE);
+ pat = gen_rtx_CONST (SImode, pat);
+ emit_insn (gen_sethi (tmp_reg, pat));
+ emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat));
+ x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ else if (GET_CODE (x) == CONST)
+ {
+ rtx base, addend;
+ split_const (x, &base, &addend);
+
+ if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC)
+ {
+ /* Expand symbol_ref@TPOFF':
+ sethi $ta, hi20(symbol_ref@TPOFF + addend)
+ ori $ta, $ta, lo12(symbol_ref@TPOFF + addend)
+ add $r0, $ta, $tp */
+ tmp_reg = gen_reg_rtx (SImode);
+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, base), UNSPEC_TLSLE);
+ pat = gen_rtx_PLUS (SImode, pat, addend);
+ pat = gen_rtx_CONST (SImode, pat);
+ emit_insn (gen_sethi (tmp_reg, pat));
+ emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat));
+ x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
+ }
+ }
+
+ return x;
+}
+
+void
+nds32_expand_tls_move (rtx *operands)
+{
+ rtx src = operands[1];
+ rtx base, addend;
+
+ if (CONSTANT_P (src))
+ split_const (src, &base, &addend);
+
+ if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC)
+ src = nds32_legitimize_tls_address (src);
+ else
+ {
+ src = nds32_legitimize_tls_address (base);
+ if (addend != const0_rtx)
+ {
+ src = gen_rtx_PLUS (SImode, src, addend);
+ src = force_operand (src, operands[0]);
+ }
+ }
+
+ emit_move_insn (operands[0], src);
}
void
@@ -2976,3 +3812,105 @@
emit_move_insn (target, gen_rtx_fmt_ee (AND, mode, source, temp));
}
}
+
+/* Auxiliary functions for lwm/smw. */
+bool
+nds32_valid_smw_lwm_base_p (rtx op)
+{
+ rtx base_addr;
+
+ if (!MEM_P (op))
+ return false;
+
+ base_addr = XEXP (op, 0);
+
+ if (REG_P (base_addr))
+ return true;
+ else
+ {
+ if (GET_CODE (base_addr) == POST_INC
+ && REG_P (XEXP (base_addr, 0)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Auxiliary functions for manipulation DI mode. */
+rtx nds32_di_high_part_subreg(rtx reg)
+{
+ unsigned high_part_offset = subreg_highpart_offset (SImode, DImode);
+
+ return simplify_gen_subreg (
+ SImode, reg,
+ DImode, high_part_offset);
+}
+
+rtx nds32_di_low_part_subreg(rtx reg)
+{
+ unsigned low_part_offset = subreg_lowpart_offset (SImode, DImode);
+
+ return simplify_gen_subreg (
+ SImode, reg,
+ DImode, low_part_offset);
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* Auxiliary function for output TLS patterns. */
+
+const char *
+nds32_output_tls_desc (rtx *operands)
+{
+ char pattern[1000];
+
+ if (TARGET_RELAX_HINT)
+ snprintf (pattern, sizeof (pattern),
+ ".relax_hint %%1\n\tsethi $r0, hi20(%%0)\n\t"
+ ".relax_hint %%1\n\tori $r0, $r0, lo12(%%0)\n\t"
+ ".relax_hint %%1\n\tlw $r15, [$r0 + $gp]\n\t"
+ ".relax_hint %%1\n\tadd $r0, $r0, $gp\n\t"
+ ".relax_hint %%1\n\tjral $r15");
+ else
+ snprintf (pattern, sizeof (pattern),
+ "sethi $r0, hi20(%%0)\n\t"
+ "ori $r0, $r0, lo12(%%0)\n\t"
+ "lw $r15, [$r0 + $gp]\n\t"
+ "add $r0, $r0, $gp\n\t"
+ "jral $r15");
+ output_asm_insn (pattern, operands);
+ return "";
+}
+
+const char *
+nds32_output_tls_ie (rtx *operands)
+{
+ char pattern[1000];
+
+ if (flag_pic)
+ {
+ if (TARGET_RELAX_HINT)
+ snprintf (pattern, sizeof (pattern),
+ ".relax_hint %%2\n\tsethi %%0, hi20(%%1)\n\t"
+ ".relax_hint %%2\n\tori %%0, %%0, lo12(%%1)\n\t"
+ ".relax_hint %%2\n\tlw %%0, [%%0 + $gp]");
+ else
+ snprintf (pattern, sizeof (pattern),
+ "sethi %%0, hi20(%%1)\n\t"
+ "ori %%0, %%0, lo12(%%1)\n\t"
+ "lw %%0, [%%0 + $gp]");
+ }
+ else
+ {
+ if (TARGET_RELAX_HINT)
+ snprintf (pattern, sizeof (pattern),
+ ".relax_hint %%2\n\tsethi %%0, hi20(%%1)\n\t"
+ ".relax_hint %%2\n\tlwi %%0, [%%0 + lo12(%%1)]");
+ else
+ snprintf (pattern, sizeof (pattern),
+ "sethi %%0, hi20(%%1)\n\t"
+ "lwi %%0, [%%0 + lo12(%%1)]");
+ }
+ output_asm_insn (pattern, operands);
+ return "";
+}
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-memory-manipulation.c gcc-8.2.0/gcc/config/nds32/nds32-memory-manipulation.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-memory-manipulation.c 2018-03-11 09:24:33.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-memory-manipulation.c 2019-01-25 15:38:32.829242659 +0100
@@ -257,8 +257,124 @@
nds32_expand_movmemsi_loop_known_size (rtx dstmem, rtx srcmem,
rtx size, rtx alignment)
{
- return nds32_expand_movmemsi_loop_unknown_size (dstmem, srcmem,
- size, alignment);
+ rtx dst_base_reg, src_base_reg;
+ rtx dst_itr, src_itr;
+ rtx dstmem_m, srcmem_m, dst_itr_m, src_itr_m;
+ rtx dst_end;
+ rtx double_word_mode_loop, byte_mode_loop;
+ rtx tmp;
+ int start_regno;
+ bool align_to_4_bytes = (INTVAL (alignment) & 3) == 0;
+ unsigned HOST_WIDE_INT total_bytes = UINTVAL (size);
+
+ if (TARGET_ISA_V3M && !align_to_4_bytes)
+ return 0;
+
+ if (TARGET_REDUCED_REGS)
+ start_regno = 2;
+ else
+ start_regno = 16;
+
+ dst_itr = gen_reg_rtx (Pmode);
+ src_itr = gen_reg_rtx (Pmode);
+ dst_end = gen_reg_rtx (Pmode);
+ tmp = gen_reg_rtx (QImode);
+
+ double_word_mode_loop = gen_label_rtx ();
+ byte_mode_loop = gen_label_rtx ();
+
+ dst_base_reg = copy_to_mode_reg (Pmode, XEXP (dstmem, 0));
+ src_base_reg = copy_to_mode_reg (Pmode, XEXP (srcmem, 0));
+
+ if (total_bytes < 8)
+ {
+ /* Emit total_bytes less than 8 loop version of movmem.
+ add $dst_end, $dst, $size
+ move $dst_itr, $dst
+ .Lbyte_mode_loop:
+ lbi.bi $tmp, [$src_itr], #1
+ sbi.bi $tmp, [$dst_itr], #1
+ ! Not readch upper bound. Loop.
+ bne $dst_itr, $dst_end, .Lbyte_mode_loop */
+
+ /* add $dst_end, $dst, $size */
+ dst_end = expand_binop (Pmode, add_optab, dst_base_reg, size,
+ NULL_RTX, 0, OPTAB_WIDEN);
+ /* move $dst_itr, $dst
+ move $src_itr, $src */
+ emit_move_insn (dst_itr, dst_base_reg);
+ emit_move_insn (src_itr, src_base_reg);
+
+ /* .Lbyte_mode_loop: */
+ emit_label (byte_mode_loop);
+
+ /* lbi.bi $tmp, [$src_itr], #1 */
+ nds32_emit_post_inc_load_store (tmp, src_itr, QImode, true);
+
+ /* sbi.bi $tmp, [$dst_itr], #1 */
+ nds32_emit_post_inc_load_store (tmp, dst_itr, QImode, false);
+ /* ! Not readch upper bound. Loop.
+ bne $dst_itr, $dst_end, .Lbyte_mode_loop */
+ emit_cmp_and_jump_insns (dst_itr, dst_end, NE, NULL,
+ SImode, 1, byte_mode_loop);
+ return true;
+ }
+ else if (total_bytes % 8 == 0)
+ {
+ /* Emit multiple of 8 loop version of movmem.
+
+ add $dst_end, $dst, $size
+ move $dst_itr, $dst
+ move $src_itr, $src
+
+ .Ldouble_word_mode_loop:
+ lmw.bim $tmp-begin, [$src_itr], $tmp-end, #0 ! $src_itr' = $src_itr
+ smw.bim $tmp-begin, [$dst_itr], $tmp-end, #0 ! $dst_itr' = $dst_itr
+ ! move will delete after register allocation
+ move $src_itr, $src_itr'
+ move $dst_itr, $dst_itr'
+ ! Not readch upper bound. Loop.
+ bne $double_word_end, $dst_itr, .Ldouble_word_mode_loop */
+
+ /* add $dst_end, $dst, $size */
+ dst_end = expand_binop (Pmode, add_optab, dst_base_reg, size,
+ NULL_RTX, 0, OPTAB_WIDEN);
+
+ /* move $dst_itr, $dst
+ move $src_itr, $src */
+ emit_move_insn (dst_itr, dst_base_reg);
+ emit_move_insn (src_itr, src_base_reg);
+
+ /* .Ldouble_word_mode_loop: */
+ emit_label (double_word_mode_loop);
+ /* lmw.bim $tmp-begin, [$src_itr], $tmp-end, #0 ! $src_itr' = $src_itr
+ smw.bim $tmp-begin, [$dst_itr], $tmp-end, #0 ! $dst_itr' = $dst_itr */
+ src_itr_m = src_itr;
+ dst_itr_m = dst_itr;
+ srcmem_m = srcmem;
+ dstmem_m = dstmem;
+ nds32_emit_mem_move_block (start_regno, 2,
+ &dst_itr_m, &dstmem_m,
+ &src_itr_m, &srcmem_m,
+ true);
+ /* move $src_itr, $src_itr'
+ move $dst_itr, $dst_itr' */
+ emit_move_insn (dst_itr, dst_itr_m);
+ emit_move_insn (src_itr, src_itr_m);
+
+ /* ! Not readch upper bound. Loop.
+ bne $double_word_end, $dst_itr, .Ldouble_word_mode_loop */
+ emit_cmp_and_jump_insns (dst_end, dst_itr, NE, NULL,
+ Pmode, 1, double_word_mode_loop);
+ }
+ else
+ {
+ /* Handle size greater than 8, and not a multiple of 8. */
+ return nds32_expand_movmemsi_loop_unknown_size (dstmem, srcmem,
+ size, alignment);
+ }
+
+ return true;
}
static bool
@@ -433,10 +549,8 @@
/* Auxiliary function for expand setmem pattern. */
static rtx
-nds32_gen_dup_4_byte_to_word_value (rtx value)
+nds32_gen_dup_4_byte_to_word_value_aux (rtx value, rtx value4word)
{
- rtx value4word = gen_reg_rtx (SImode);
-
gcc_assert (GET_MODE (value) == QImode || CONST_INT_P (value));
if (CONST_INT_P (value))
@@ -449,36 +563,74 @@
}
else
{
- /* ! prepare word
- andi $tmp1, $value, 0xff ! $tmp1 <- 0x000000ab
- slli $tmp2, $tmp1, 8 ! $tmp2 <- 0x0000ab00
- or $tmp3, $tmp1, $tmp2 ! $tmp3 <- 0x0000abab
- slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000
- or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab */
-
- rtx tmp1, tmp2, tmp3, tmp4, final_value;
- tmp1 = expand_binop (SImode, and_optab, value,
- gen_int_mode (0xff, SImode),
- NULL_RTX, 0, OPTAB_WIDEN);
- tmp2 = expand_binop (SImode, ashl_optab, tmp1,
- gen_int_mode (8, SImode),
- NULL_RTX, 0, OPTAB_WIDEN);
- tmp3 = expand_binop (SImode, ior_optab, tmp1, tmp2,
- NULL_RTX, 0, OPTAB_WIDEN);
- tmp4 = expand_binop (SImode, ashl_optab, tmp3,
- gen_int_mode (16, SImode),
- NULL_RTX, 0, OPTAB_WIDEN);
-
- final_value = expand_binop (SImode, ior_optab, tmp3, tmp4,
- NULL_RTX, 0, OPTAB_WIDEN);
- emit_move_insn (value4word, final_value);
+ if (NDS32_EXT_DSP_P ())
+ {
+ /* ! prepare word
+ insb $tmp, $value, 1 ! $tmp <- 0x0000abab
+ pkbb16 $tmp6, $tmp2, $tmp2 ! $value4word <- 0xabababab */
+ rtx tmp = gen_reg_rtx (SImode);
+
+ convert_move (tmp, value, true);
+
+ emit_insn (
+ gen_insvsi_internal (tmp, gen_int_mode (0x8, SImode), tmp));
+
+ emit_insn (gen_pkbbsi_1 (value4word, tmp, tmp));
+ }
+ else
+ {
+ /* ! prepare word
+ andi $tmp1, $value, 0xff ! $tmp1 <- 0x000000ab
+ slli $tmp2, $tmp1, 8 ! $tmp2 <- 0x0000ab00
+ or $tmp3, $tmp1, $tmp2 ! $tmp3 <- 0x0000abab
+ slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000
+ or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab */
+
+ rtx tmp1, tmp2, tmp3, tmp4;
+ tmp1 = expand_binop (SImode, and_optab, value,
+ gen_int_mode (0xff, SImode),
+ NULL_RTX, 0, OPTAB_WIDEN);
+ tmp2 = expand_binop (SImode, ashl_optab, tmp1,
+ gen_int_mode (8, SImode),
+ NULL_RTX, 0, OPTAB_WIDEN);
+ tmp3 = expand_binop (SImode, ior_optab, tmp1, tmp2,
+ NULL_RTX, 0, OPTAB_WIDEN);
+ tmp4 = expand_binop (SImode, ashl_optab, tmp3,
+ gen_int_mode (16, SImode),
+ NULL_RTX, 0, OPTAB_WIDEN);
+
+ emit_insn (gen_iorsi3 (value4word, tmp3, tmp4));
+ }
}
return value4word;
}
static rtx
-emit_setmem_word_loop (rtx itr, rtx size, rtx value)
+nds32_gen_dup_4_byte_to_word_value (rtx value)
+{
+ rtx value4word = gen_reg_rtx (SImode);
+ nds32_gen_dup_4_byte_to_word_value_aux (value, value4word);
+
+ return value4word;
+}
+
+static rtx
+nds32_gen_dup_8_byte_to_double_word_value (rtx value)
+{
+ rtx value4doubleword = gen_reg_rtx (DImode);
+
+ nds32_gen_dup_4_byte_to_word_value_aux (
+ value, nds32_di_low_part_subreg(value4doubleword));
+
+ emit_move_insn (nds32_di_high_part_subreg(value4doubleword),
+ nds32_di_low_part_subreg(value4doubleword));
+ return value4doubleword;
+}
+
+
+static rtx
+emit_setmem_doubleword_loop (rtx itr, rtx size, rtx value)
{
rtx word_mode_label = gen_label_rtx ();
rtx word_mode_end_label = gen_label_rtx ();
@@ -487,9 +639,9 @@
rtx word_mode_end = gen_reg_rtx (SImode);
rtx size_for_word = gen_reg_rtx (SImode);
- /* and $size_for_word, $size, #~3 */
+ /* and $size_for_word, $size, #~0x7 */
size_for_word = expand_binop (SImode, and_optab, size,
- gen_int_mode (~3, SImode),
+ gen_int_mode (~0x7, SImode),
NULL_RTX, 0, OPTAB_WIDEN);
emit_move_insn (byte_mode_size, size);
@@ -501,8 +653,8 @@
word_mode_end = expand_binop (Pmode, add_optab, itr, size_for_word,
NULL_RTX, 0, OPTAB_WIDEN);
- /* andi $byte_mode_size, $size, 3 */
- byte_mode_size_tmp = expand_binop (SImode, and_optab, size, GEN_INT (3),
+ /* andi $byte_mode_size, $size, 0x7 */
+ byte_mode_size_tmp = expand_binop (SImode, and_optab, size, GEN_INT (0x7),
NULL_RTX, 0, OPTAB_WIDEN);
emit_move_insn (byte_mode_size, byte_mode_size_tmp);
@@ -512,9 +664,9 @@
/* ! word-mode set loop
smw.bim $value4word, [$dst_itr], $value4word, 0
bne $word_mode_end, $dst_itr, .Lword_mode */
- emit_insn (gen_unaligned_store_update_base_w (itr,
- itr,
- value));
+ emit_insn (gen_unaligned_store_update_base_dw (itr,
+ itr,
+ value));
emit_cmp_and_jump_insns (word_mode_end, itr, NE, NULL,
Pmode, 1, word_mode_label);
@@ -566,7 +718,7 @@
static bool
nds32_expand_setmem_loop (rtx dstmem, rtx size, rtx value)
{
- rtx value4word;
+ rtx value4doubleword;
rtx value4byte;
rtx dst;
rtx byte_mode_size;
@@ -609,7 +761,7 @@
or $tmp3, $tmp1, $tmp2 ! $tmp3 <- 0x0000abab
slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000
or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab */
- value4word = nds32_gen_dup_4_byte_to_word_value (value);
+ value4doubleword = nds32_gen_dup_8_byte_to_double_word_value (value);
/* and $size_for_word, $size, #-4
beqz $size_for_word, .Lword_mode_end
@@ -622,7 +774,7 @@
smw.bim $value4word, [$dst], $value4word, 0
bne $word_mode_end, $dst, .Lword_mode
.Lword_mode_end: */
- byte_mode_size = emit_setmem_word_loop (dst, size, value4word);
+ byte_mode_size = emit_setmem_doubleword_loop (dst, size, value4doubleword);
/* beqz $byte_mode_size, .Lend
add $byte_mode_end, $dst, $byte_mode_size
@@ -633,8 +785,8 @@
bne $byte_mode_end, $dst, .Lbyte_mode
.Lend: */
- value4byte = simplify_gen_subreg (QImode, value4word, SImode,
- subreg_lowpart_offset (QImode, SImode));
+ value4byte = simplify_gen_subreg (QImode, value4doubleword, DImode,
+ subreg_lowpart_offset (QImode, DImode));
emit_setmem_byte_loop (dst, byte_mode_size, value4byte, false);
@@ -651,14 +803,15 @@
rtx byte_loop_size = gen_reg_rtx (SImode);
rtx remain_size = gen_reg_rtx (SImode);
rtx new_base_reg;
- rtx value4byte, value4word;
+ rtx value4byte, value4doubleword;
rtx byte_mode_size;
rtx last_byte_loop_label = gen_label_rtx ();
size = force_reg (SImode, size);
- value4word = nds32_gen_dup_4_byte_to_word_value (value);
- value4byte = simplify_gen_subreg (QImode, value4word, SImode, 0);
+ value4doubleword = nds32_gen_dup_8_byte_to_double_word_value (value);
+ value4byte = simplify_gen_subreg (QImode, value4doubleword, DImode,
+ subreg_lowpart_offset (QImode, DImode));
emit_move_insn (byte_loop_size, size);
emit_move_insn (byte_loop_base, base_reg);
@@ -686,9 +839,9 @@
emit_insn (gen_subsi3 (remain_size, size, need_align_bytes));
/* Set memory word by word. */
- byte_mode_size = emit_setmem_word_loop (new_base_reg,
- remain_size,
- value4word);
+ byte_mode_size = emit_setmem_doubleword_loop (new_base_reg,
+ remain_size,
+ value4doubleword);
emit_move_insn (byte_loop_base, new_base_reg);
emit_move_insn (byte_loop_size, byte_mode_size);
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-multiple.md gcc-8.2.0/gcc/config/nds32/nds32-multiple.md
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-multiple.md 2018-03-11 09:24:33.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-multiple.md 2019-01-25 15:38:32.829242659 +0100
@@ -2854,6 +2854,25 @@
(set_attr "length" "4")]
)
+(define_expand "unaligned_store_update_base_dw"
+ [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "0") (const_int 8)))
+ (set (mem:DI (match_dup 1))
+ (unspec:DI [(match_operand:DI 2 "register_operand" "r")] UNSPEC_UASTORE_DW))])]
+ ""
+{
+ /* DO NOT emit unaligned_store_w_m immediately since web pass don't
+ recognize post_inc, try it again after GCC 5.0.
+ REF: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63156 */
+ emit_insn (gen_unaligned_store_dw (gen_rtx_MEM (DImode, operands[1]), operands[2]));
+ emit_insn (gen_addsi3 (operands[0], operands[1], gen_int_mode (8, Pmode)));
+ DONE;
+}
+ [(set_attr "type" "store_multiple")
+ (set_attr "combo" "2")
+ (set_attr "length" "4")]
+)
+
(define_insn "*stmsi25"
[(match_parallel 0 "nds32_store_multiple_operation"
[(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-n10.md gcc-8.2.0/gcc/config/nds32/nds32-n10.md
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-n10.md 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-n10.md 2019-01-25 15:38:32.829242659 +0100
@@ -0,0 +1,439 @@
+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; 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
+;; <http://www.gnu.org/licenses/>.
+
+
+;; ------------------------------------------------------------------------
+;; Define N10 pipeline settings.
+;; ------------------------------------------------------------------------
+
+(define_automaton "nds32_n10_machine")
+
+;; ------------------------------------------------------------------------
+;; Pipeline Stages
+;; ------------------------------------------------------------------------
+;; IF - Instruction Fetch
+;; II - Instruction Issue / Instruction Decode
+;; EX - Instruction Execution
+;; MM - Memory Execution
+;; WB - Instruction Retire / Result Write-Back
+
+(define_cpu_unit "n10_ii" "nds32_n10_machine")
+(define_cpu_unit "n10_ex" "nds32_n10_machine")
+(define_cpu_unit "n10_mm" "nds32_n10_machine")
+(define_cpu_unit "n10_wb" "nds32_n10_machine")
+(define_cpu_unit "n10f_iq" "nds32_n10_machine")
+(define_cpu_unit "n10f_rf" "nds32_n10_machine")
+(define_cpu_unit "n10f_e1" "nds32_n10_machine")
+(define_cpu_unit "n10f_e2" "nds32_n10_machine")
+(define_cpu_unit "n10f_e3" "nds32_n10_machine")
+(define_cpu_unit "n10f_e4" "nds32_n10_machine")
+
+(define_insn_reservation "nds_n10_unknown" 1
+ (and (eq_attr "type" "unknown")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_misc" 1
+ (and (eq_attr "type" "misc")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_mmu" 1
+ (and (eq_attr "type" "mmu")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_alu" 1
+ (and (eq_attr "type" "alu")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_alu_shift" 1
+ (and (eq_attr "type" "alu_shift")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ii+n10_ex, n10_ex+n10_mm, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_pbsad" 1
+ (and (eq_attr "type" "pbsad")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex*3, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_pbsada" 1
+ (and (eq_attr "type" "pbsada")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex*3, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_load" 1
+ (and (match_test "nds32::load_single_p (insn)")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_store" 1
+ (and (match_test "nds32::store_single_p (insn)")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_load_multiple_1" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "1")))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_load_multiple_2" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (ior (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "2"))
+ (match_test "nds32::load_double_p (insn)")))
+ "n10_ii, n10_ii+n10_ex, n10_ex+n10_mm, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_load_multiple_3" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "3")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_load_multiple_4" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "4")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ii+n10_ex+n10_mm+n10_wb, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_load_multiple_5" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "5")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*2, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_load_multiple_6" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "6")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*3, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_load_multiple_7" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "7")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*4, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_load_multiple_N" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "load_multiple")
+ (match_test "get_attr_combo (insn) >= 8")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*5, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_store_multiple_1" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "1")))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_store_multiple_2" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (ior (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "2"))
+ (match_test "nds32::store_double_p (insn)")))
+ "n10_ii, n10_ii+n10_ex, n10_ex+n10_mm, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_store_multiple_3" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "3")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_store_multiple_4" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "4")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ii+n10_ex+n10_mm+n10_wb, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_store_multiple_5" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "5")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*2, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_store_multiple_6" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "6")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*3, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_store_multiple_7" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "7")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*4, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_store_multiple_N" 1
+ (and (eq_attr "pipeline_model" "n10")
+ (and (eq_attr "type" "store_multiple")
+ (match_test "get_attr_combo (insn) >= 8")))
+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*5, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb")
+
+(define_insn_reservation "nds_n10_mul" 1
+ (and (eq_attr "type" "mul")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_mac" 1
+ (and (eq_attr "type" "mac")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_div" 1
+ (and (eq_attr "type" "div")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex*34, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_branch" 1
+ (and (eq_attr "type" "branch")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_alu" 1
+ (and (eq_attr "type" "dalu")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_alu64" 1
+ (and (eq_attr "type" "dalu64")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_alu_round" 1
+ (and (eq_attr "type" "daluround")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_cmp" 1
+ (and (eq_attr "type" "dcmp")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_clip" 1
+ (and (eq_attr "type" "dclip")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_mul" 1
+ (and (eq_attr "type" "dmul")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_mac" 1
+ (and (eq_attr "type" "dmac")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_insb" 1
+ (and (eq_attr "type" "dinsb")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_pack" 1
+ (and (eq_attr "type" "dpack")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_bpick" 1
+ (and (eq_attr "type" "dbpick")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_dsp_wext" 1
+ (and (eq_attr "type" "dwext")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ex, n10_mm, n10_wb")
+
+(define_insn_reservation "nds_n10_fpu_alu" 4
+ (and (eq_attr "type" "falu")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_muls" 4
+ (and (eq_attr "type" "fmuls")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_muld" 4
+ (and (eq_attr "type" "fmuld")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*2, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_macs" 4
+ (and (eq_attr "type" "fmacs")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*3, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_macd" 4
+ (and (eq_attr "type" "fmacd")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*4, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_divs" 4
+ (and (ior (eq_attr "type" "fdivs")
+ (eq_attr "type" "fsqrts"))
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*14, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_divd" 4
+ (and (ior (eq_attr "type" "fdivd")
+ (eq_attr "type" "fsqrtd"))
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*28, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_fast_alu" 2
+ (and (ior (eq_attr "type" "fcmp")
+ (ior (eq_attr "type" "fabs")
+ (ior (eq_attr "type" "fcpy")
+ (eq_attr "type" "fcmov"))))
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_fmtsr" 4
+ (and (eq_attr "type" "fmtsr")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_fmtdr" 4
+ (and (eq_attr "type" "fmtdr")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ii+n10f_iq, n10f_iq+n10f_rf, n10f_rf+n10f_e1, n10f_e1+n10f_e2, n10f_e2+n10f_e3, n10f_e3+n10f_e4, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_fmfsr" 2
+ (and (eq_attr "type" "fmfsr")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_fmfdr" 2
+ (and (eq_attr "type" "fmfdr")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10_ii+n10f_iq, n10f_iq+n10f_rf, n10f_rf+n10f_e1, n10f_e1+n10f_e2, n10f_e2+n10f_e3, n10f_e3+n10f_e4, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_load" 3
+ (and (eq_attr "type" "fload")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4")
+
+(define_insn_reservation "nds_n10_fpu_store" 1
+ (and (eq_attr "type" "fstore")
+ (eq_attr "pipeline_model" "n10"))
+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4")
+
+;; ------------------------------------------------------------------------
+;; Comment Notations and Bypass Rules
+;; ------------------------------------------------------------------------
+;; Producers (LHS)
+;; LD
+;; Load data from the memory and produce the loaded data. The result is
+;; ready at MM.
+;; LMW(N, M)
+;; There are N micro-operations within an instruction that loads multiple
+;; words. The result produced by the M-th micro-operation is sent to
+;; consumers. The result is ready at MM.
+;; MUL, MAC
+;; Compute data in the multiply-adder and produce the data. The result
+;; is ready at MM.
+;; DIV
+;; Compute data in the divider and produce the data. The result is ready
+;; at MM.
+;;
+;; Consumers (RHS)
+;; ALU, MOVD44, PBSAD, PBSADA_RaRb, MUL, MAC, DIV, MMU
+;; Require operands at EX.
+;; ALU_SHIFT_Rb
+;; An ALU-SHIFT instruction consists of a shift micro-operation followed
+;; by an arithmetic micro-operation. The operand Rb is used by the first
+;; micro-operation, and there are some latencies if data dependency occurs.
+;; MAC_RaRb
+;; A MAC instruction does multiplication at EX and does accumulation at MM,
+;; so the operand Rt is required at MM, and operands Ra and Rb are required
+;; at EX.
+;; ADDR_IN
+;; If an instruction requires an address as its input operand, the address
+;; is required at EX.
+;; ST
+;; A store instruction requires its data at MM.
+;; SMW(N, M)
+;; There are N micro-operations within an instruction that stores multiple
+;; words. Each M-th micro-operation requires its data at MM.
+;; BR
+;; If a branch instruction is conditional, its input data is required at EX.
+
+;; FPU_ADDR_OUT -> FPU_ADDR_IN
+;; Main pipeline rules don't need this because those default latency is 1.
+(define_bypass 1
+ "nds_n10_fpu_load, nds_n10_fpu_store"
+ "nds_n10_fpu_load, nds_n10_fpu_store"
+ "nds32_n10_ex_to_ex_p"
+)
+
+;; LD, MUL, MAC, DIV, DALU64, DMUL, DMAC, DALUROUND, DBPICK, DWEXT
+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU,
+;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb
+(define_bypass 2
+ "nds_n10_load, nds_n10_mul, nds_n10_mac, nds_n10_div,\
+ nds_n10_dsp_alu64, nds_n10_dsp_mul, nds_n10_dsp_mac,\
+ nds_n10_dsp_alu_round, nds_n10_dsp_bpick, nds_n10_dsp_wext"
+ "nds_n10_alu, nds_n10_alu_shift,\
+ nds_n10_pbsad, nds_n10_pbsada,\
+ nds_n10_mul, nds_n10_mac, nds_n10_div,\
+ nds_n10_branch,\
+ nds_n10_load, nds_n10_store,\
+ nds_n10_load_multiple_1, nds_n10_load_multiple_2, nds_n10_load_multiple_3,\
+ nds_n10_load_multiple_4, nds_n10_load_multiple_5, nds_n10_load_multiple_6,\
+ nds_n10_load_multiple_7, nds_n10_load_multiple_N,\
+ nds_n10_store_multiple_1, nds_n10_store_multiple_2, nds_n10_store_multiple_3,\
+ nds_n10_store_multiple_4, nds_n10_store_multiple_5, nds_n10_store_multiple_6,\
+ nds_n10_store_multiple_7, nds_n10_store_multiple_N,\
+ nds_n10_mmu,\
+ nds_n10_dsp_alu, nds_n10_dsp_alu_round,\
+ nds_n10_dsp_mul, nds_n10_dsp_mac, nds_n10_dsp_pack,\
+ nds_n10_dsp_insb, nds_n10_dsp_cmp, nds_n10_dsp_clip,\
+ nds_n10_dsp_wext, nds_n10_dsp_bpick"
+ "nds32_n10_mm_to_ex_p"
+)
+
+;; LMW(N, N)
+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU
+;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb
+(define_bypass 2
+ "nds_n10_load_multiple_1, nds_n10_load_multiple_2, nds_n10_load_multiple_3,\
+ nds_n10_load_multiple_4, nds_n10_load_multiple_5, nds_n10_load_multiple_6,\
+ nds_n10_load_multiple_7, nds_n10_load_multiple_N"
+ "nds_n10_alu, nds_n10_alu_shift,\
+ nds_n10_pbsad, nds_n10_pbsada,\
+ nds_n10_mul, nds_n10_mac, nds_n10_div,\
+ nds_n10_branch,\
+ nds_n10_load, nds_n10_store,\
+ nds_n10_load_multiple_1, nds_n10_load_multiple_2, nds_n10_load_multiple_3,\
+ nds_n10_load_multiple_4, nds_n10_load_multiple_5, nds_n10_load_multiple_6,\
+ nds_n10_load_multiple_7, nds_n10_load_multiple_N,\
+ nds_n10_store_multiple_1, nds_n10_store_multiple_2, nds_n10_store_multiple_3,\
+ nds_n10_store_multiple_4, nds_n10_store_multiple_5, nds_n10_store_multiple_6,\
+ nds_n10_store_multiple_7, nds_n10_store_multiple_N,\
+ nds_n10_mmu,\
+ nds_n10_dsp_alu, nds_n10_dsp_alu_round,\
+ nds_n10_dsp_mul, nds_n10_dsp_mac, nds_n10_dsp_pack,\
+ nds_n10_dsp_insb, nds_n10_dsp_cmp, nds_n10_dsp_clip,\
+ nds_n10_dsp_wext, nds_n10_dsp_bpick"
+ "nds32_n10_last_load_to_ex_p"
+)
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-n13.md gcc-8.2.0/gcc/config/nds32/nds32-n13.md
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-n13.md 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-n13.md 2019-01-25 15:38:32.829242659 +0100
@@ -0,0 +1,401 @@
+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler
+;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
+;; Contributed by Andes Technology Corporation.
+;;
+;; 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
+;; <http://www.gnu.org/licenses/>.
+
+
+;; ------------------------------------------------------------------------
+;; Define N13 pipeline settings.
+;; ------------------------------------------------------------------------
+
+(define_automaton "nds32_n13_machine")
+
+;; ------------------------------------------------------------------------
+;; Pipeline Stages
+;; ------------------------------------------------------------------------
+;; F1 - Instruction Fetch First
+;; Instruction Tag/Data Arrays
+;; ITLB Address Translation
+;; Branch Target Buffer Prediction
+;; F2 - Instruction Fetch Second
+;; Instruction Cache Hit Detection
+;; Cache Way Selection
+;; Inustruction Alignment
+;; I1 - Instruction Issue First / Instruction Decode
+;; Instruction Cache Replay Triggering
+;; 32/16-Bit Instruction Decode
+;; Return Address Stack Prediction
+;; I2 - Instruction Issue Second / Register File Access
+;; Instruction Issue Logic
+;; Register File Access
+;; E1 - Instruction Execute First / Address Generation / MAC First
+;; Data Access Address generation
+;; Multiply Operation
+;; E2 - Instruction Execute Second / Data Access First / MAC Second /
+;; ALU Execute
+;; Skewed ALU
+;; Branch/Jump/Return Resolution
+;; Data Tag/Data arrays
+;; DTLB address translation
+;; Accumulation Operation
+;; E3 - Instruction Execute Third / Data Access Second
+;; Data Cache Hit Detection
+;; Cache Way Selection
+;; Data Alignment
+;; E4 - Instruction Execute Fourth / Write Back
+;; Interruption Resolution
+;; Instruction Retire
+;; Register File Write Back
+
+(define_cpu_unit "n13_i1" "nds32_n13_machine")
+(define_cpu_unit "n13_i2" "nds32_n13_machine")
+(define_cpu_unit "n13_e1" "nds32_n13_machine")
+(define_cpu_unit "n13_e2" "nds32_n13_machine")
+(define_cpu_unit "n13_e3" "nds32_n13_machine")
+(define_cpu_unit "n13_e4" "nds32_n13_machine")
+
+(define_insn_reservation "nds_n13_unknown" 1
+ (and (eq_attr "type" "unknown")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_misc" 1
+ (and (eq_attr "type" "misc")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_mmu" 1
+ (and (eq_attr "type" "mmu")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_alu" 1
+ (and (eq_attr "type" "alu")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_alu_shift" 1
+ (and (eq_attr "type" "alu_shift")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i2+n13_e1, n13_e1+n13_e2, n13_e2+n13_e3, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_pbsad" 1
+ (and (eq_attr "type" "pbsad")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2*2, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_pbsada" 1
+ (and (eq_attr "type" "pbsada")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2*3, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_load" 1
+ (and (match_test "nds32::load_single_p (insn)")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_store" 1
+ (and (match_test "nds32::store_single_p (insn)")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_load_multiple_1" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "1"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_load_multiple_2" 1
+ (and (ior (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "2"))
+ (match_test "nds32::load_double_p (insn)"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i2+n13_e1, n13_e1+n13_e2, n13_e2+n13_e3, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_load_multiple_3" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "3"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2+n13_i2, n13_i1+n13_i2+n13_e1, n13_i2+n13_e1+n13_e2, n13_e1+n13_e2+n13_e3, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_load_multiple_4" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "4"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i2+n13_e1+n13_e2+n13_e3, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_load_multiple_5" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "5"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_load_multiple_6" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "6"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_load_multiple_7" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "7"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*2, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_load_multiple_8" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "8"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_load_multiple_12" 1
+ (and (and (eq_attr "type" "load_multiple")
+ (eq_attr "combo" "12"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*7, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_store_multiple_1" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "1"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_store_multiple_2" 1
+ (and (ior (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "2"))
+ (match_test "nds32::store_double_p (insn)"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i2+n13_e1, n13_e1+n13_e2, n13_e2+n13_e3, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_store_multiple_3" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "3"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2+n13_i2, n13_i1+n13_i2+n13_e1, n13_i2+n13_e1+n13_e2, n13_e1+n13_e2+n13_e3, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_store_multiple_4" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "4"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i2+n13_e1+n13_e2+n13_e3, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_store_multiple_5" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "5"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_store_multiple_6" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "6"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_store_multiple_7" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "7"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*2, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_store_multiple_8" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "8"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+(define_insn_reservation "nds_n13_store_multiple_12" 1
+ (and (and (eq_attr "type" "store_multiple")
+ (eq_attr "combo" "12"))
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*7, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4")
+
+;; The multiplier at E1 takes two cycles.
+(define_insn_reservation "nds_n13_mul" 1
+ (and (eq_attr "type" "mul")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1*2, n13_e2, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_mac" 1
+ (and (eq_attr "type" "mac")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1*2, n13_e2, n13_e3, n13_e4")
+
+;; The cycles consumed at E2 are 32 - CLZ(abs(Ra)) + 2,
+;; so the worst case is 34.
+(define_insn_reservation "nds_n13_div" 1
+ (and (eq_attr "type" "div")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2*34, n13_e3, n13_e4")
+
+(define_insn_reservation "nds_n13_branch" 1
+ (and (eq_attr "type" "branch")
+ (eq_attr "pipeline_model" "n13"))
+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4")
+
+;; ------------------------------------------------------------------------
+;; Comment Notations and Bypass Rules
+;; ------------------------------------------------------------------------
+;; Producers (LHS)
+;; LD
+;; Load data from the memory and produce the loaded data. The result is
+;; ready at E3.
+;; LMW(N, M)
+;; There are N micro-operations within an instruction that loads multiple
+;; words. The result produced by the M-th micro-operation is sent to
+;; consumers. The result is ready at E3.
+;; ADDR_OUT
+;; Most load/store instructions can produce an address output if updating
+;; the base register is required. The result is ready at E2, which is
+;; produced by ALU.
+;; ALU, ALU_SHIFT, SIMD
+;; Compute data in ALU and produce the data. The result is ready at E2.
+;; MUL, MAC
+;; Compute data in the multiply-adder and produce the data. The result
+;; is ready at E2.
+;; DIV
+;; Compute data in the divider and produce the data. The result is ready
+;; at E2.
+;; BR
+;; Branch-with-link instructions produces a result containing the return
+;; address. The result is ready at E2.
+;;
+;; Consumers (RHS)
+;; ALU
+;; General ALU instructions require operands at E2.
+;; ALU_E1
+;; Some special ALU instructions, such as BSE, BSP and MOVD44, require
+;; operand at E1.
+;; MUL, DIV, PBSAD, MMU
+;; Operands are required at E1.
+;; PBSADA_Rt, PBSADA_RaRb
+;; Operands Ra and Rb are required at E1, and the operand Rt is required
+;; at E2.
+;; ALU_SHIFT_Rb
+;; An ALU-SHIFT instruction consists of a shift micro-operation followed
+;; by an arithmetic micro-operation. The operand Rb is used by the first
+;; micro-operation, and there are some latencies if data dependency occurs.
+;; MAC_RaRb
+;; A MAC instruction does multiplication at E1 and does accumulation at E2,
+;; so the operand Rt is required at E2, and operands Ra and Rb are required
+;; at E1.
+;; ADDR_IN
+;; If an instruction requires an address as its input operand, the address
+;; is required at E1.
+;; ST
+;; A store instruction requires its data at E2.
+;; SMW(N, M)
+;; There are N micro-operations within an instruction that stores multiple
+;; words. Each M-th micro-operation requires its data at E2.
+;; BR
+;; If a branch instruction is conditional, its input data is required at E2.
+
+;; LD -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN
+(define_bypass 3
+ "nds_n13_load"
+ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\
+ nds_n13_mul, nds_n13_mac, nds_n13_div,\
+ nds_n13_mmu,\
+ nds_n13_load, nds_n13_store,\
+ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\
+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\
+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\
+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\
+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\
+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12"
+ "nds32_n13_load_to_e1_p"
+)
+
+;; LD -> ALU, ALU_SHIFT_Rb, PBSADA_Rt, BR, ST, SMW(N, 1)
+(define_bypass 2
+ "nds_n13_load"
+ "nds_n13_alu, nds_n13_alu_shift, nds_n13_pbsada, nds_n13_branch, nds_n13_store,\
+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\
+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\
+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12"
+ "nds32_n13_load_to_e2_p"
+)
+
+;; LMW(N, N) -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN
+(define_bypass 3
+ "nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\
+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\
+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12"
+ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\
+ nds_n13_mul, nds_n13_mac, nds_n13_div,\
+ nds_n13_mmu,\
+ nds_n13_load, nds_n13_store,\
+ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\
+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\
+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\
+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\
+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\
+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12"
+ "nds32_n13_last_load_to_e1_p")
+
+;; LMW(N, N) -> ALU, ALU_SHIFT_Rb, PBSADA_Rt, BR, ST, SMW(N, 1)
+(define_bypass 2
+ "nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\
+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\
+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12"
+ "nds_n13_alu, nds_n13_alu_shift, nds_n13_pbsada, nds_n13_branch, nds_n13_store,\
+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\
+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\
+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12"
+ "nds32_n13_last_load_to_e2_p"
+)
+
+;; LMW(N, N - 1) -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN
+(define_bypass 2
+ "nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\
+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\
+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12"
+ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\
+ nds_n13_mul, nds_n13_mac, nds_n13_div,\
+ nds_n13_mmu,\
+ nds_n13_load, nds_n13_store,\
+ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\
+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\
+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\
+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\
+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\
+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12"
+ "nds32_n13_last_two_load_to_e1_p")
+
+;; ALU, ALU_SHIFT, SIMD, BR, MUL, MAC, DIV, ADDR_OUT
+;; -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN
+(define_bypass 2
+ "nds_n13_alu, nds_n13_alu_shift, nds_n13_pbsad, nds_n13_pbsada, nds_n13_branch,\
+ nds_n13_mul, nds_n13_mac, nds_n13_div,\
+ nds_n13_load, nds_n13_store,\
+ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\
+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\
+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\
+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\
+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\
+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12"
+ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\
+ nds_n13_mul, nds_n13_mac, nds_n13_div,\
+ nds_n13_mmu,\
+ nds_n13_load, nds_n13_store,\
+ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\
+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\
+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\
+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\
+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\
+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12"
+ "nds32_n13_e2_to_e1_p")
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32.opt gcc-8.2.0/gcc/config/nds32/nds32.opt
--- gcc-8.2.0.orig/gcc/config/nds32/nds32.opt 2018-04-22 12:10:00.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32.opt 2019-01-25 15:38:32.833242671 +0100
@@ -32,6 +32,13 @@
Target RejectNegative Alias(mlittle-endian)
Generate code in little-endian mode.
+mfp-as-gp
+Target RejectNegative Alias(mforce-fp-as-gp)
+Force performing fp-as-gp optimization.
+
+mno-fp-as-gp
+Target RejectNegative Alias(mforbid-fp-as-gp)
+Forbid performing fp-as-gp optimization.
; ---------------------------------------------------------------
@@ -85,11 +92,36 @@
Target Undocumented RejectNegative Negative(mbig-endian) InverseMask(BIG_ENDIAN)
Generate code in little-endian mode.
+mforce-fp-as-gp
+Target Undocumented Mask(FORCE_FP_AS_GP)
+Prevent $fp being allocated during register allocation so that compiler is able to force performing fp-as-gp optimization.
+
+mforbid-fp-as-gp
+Target Undocumented Mask(FORBID_FP_AS_GP)
+Forbid using $fp to access static and global variables. This option strictly forbids fp-as-gp optimization regardless of '-mforce-fp-as-gp'.
+
+mict-model=
+Target Undocumented RejectNegative Joined Enum(nds32_ict_model_type) Var(nds32_ict_model) Init(ICT_MODEL_SMALL)
+Specify the address generation strategy for ICT call's code model.
+
+Enum
+Name(nds32_ict_model_type) Type(enum nds32_ict_model_type)
+Known cmodel types (for use with the -mict-model= option):
+
+EnumValue
+Enum(nds32_ict_model_type) String(small) Value(ICT_MODEL_SMALL)
+
+EnumValue
+Enum(nds32_ict_model_type) String(large) Value(ICT_MODEL_LARGE)
mcmov
Target Report Mask(CMOV)
Generate conditional move instructions.
+mhw-abs
+Target Report Mask(HW_ABS)
+Generate hardware abs instructions.
+
mext-perf
Target Report Mask(EXT_PERF)
Generate performance extension instructions.
@@ -102,6 +134,10 @@
Target Report Mask(EXT_STRING)
Generate string extension instructions.
+mext-dsp
+Target Report Mask(EXT_DSP)
+Generate DSP extension instructions.
+
mv3push
Target Report Mask(V3PUSH)
Generate v3 push25/pop25 instructions.
@@ -115,13 +151,17 @@
Insert relax hint for linker to do relaxation.
mvh
-Target Report Mask(VH)
+Target Report Mask(VH) Condition(!TARGET_LINUX_ABI)
Enable Virtual Hosting support.
misr-vector-size=
Target RejectNegative Joined UInteger Var(nds32_isr_vector_size) Init(NDS32_DEFAULT_ISR_VECTOR_SIZE)
Specify the size of each interrupt vector, which must be 4 or 16.
+misr-secure=
+Target RejectNegative Joined UInteger Var(nds32_isr_secure_level) Init(0)
+Specify the security level of c-isr for the whole file.
+
mcache-block-size=
Target RejectNegative Joined UInteger Var(nds32_cache_block_size) Init(NDS32_DEFAULT_CACHE_BLOCK_SIZE)
Specify the size of each cache block, which must be a power of 2 between 4 and 512.
@@ -141,6 +181,9 @@
Enum(nds32_arch_type) String(v3) Value(ARCH_V3)
EnumValue
+Enum(nds32_arch_type) String(v3j) Value(ARCH_V3J)
+
+EnumValue
Enum(nds32_arch_type) String(v3m) Value(ARCH_V3M)
EnumValue
@@ -149,23 +192,6 @@
EnumValue
Enum(nds32_arch_type) String(v3s) Value(ARCH_V3S)
-mcmodel=
-Target RejectNegative Joined Enum(nds32_cmodel_type) Var(nds32_cmodel_option) Init(CMODEL_LARGE)
-Specify the address generation strategy for code model.
-
-Enum
-Name(nds32_cmodel_type) Type(enum nds32_cmodel_type)
-Known cmodel types (for use with the -mcmodel= option):
-
-EnumValue
-Enum(nds32_cmodel_type) String(small) Value(CMODEL_SMALL)
-
-EnumValue
-Enum(nds32_cmodel_type) String(medium) Value(CMODEL_MEDIUM)
-
-EnumValue
-Enum(nds32_cmodel_type) String(large) Value(CMODEL_LARGE)
-
mcpu=
Target RejectNegative Joined Enum(nds32_cpu_type) Var(nds32_cpu_option) Init(CPU_N9)
Specify the cpu for pipeline model.
@@ -235,6 +261,99 @@
Enum(nds32_cpu_type) String(n968a) Value(CPU_N9)
EnumValue
+Enum(nds32_cpu_type) String(n10) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1033) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1033a) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1033-fpu) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1033-spu) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1068) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1068a) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1068-fpu) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1068a-fpu) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1068-spu) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1068a-spu) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(d10) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(d1088) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(d1088-fpu) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) String(d1088-spu) Value(CPU_N10)
+
+EnumValue
+Enum(nds32_cpu_type) Undocumented String(graywolf) Value(CPU_GRAYWOLF)
+
+EnumValue
+Enum(nds32_cpu_type) String(n15) Value(CPU_GRAYWOLF)
+
+EnumValue
+Enum(nds32_cpu_type) String(d15) Value(CPU_GRAYWOLF)
+
+EnumValue
+Enum(nds32_cpu_type) String(n15s) Value(CPU_GRAYWOLF)
+
+EnumValue
+Enum(nds32_cpu_type) String(d15s) Value(CPU_GRAYWOLF)
+
+EnumValue
+Enum(nds32_cpu_type) String(n15f) Value(CPU_GRAYWOLF)
+
+EnumValue
+Enum(nds32_cpu_type) String(d15f) Value(CPU_GRAYWOLF)
+
+EnumValue
+Enum(nds32_cpu_type) String(n12) Value(CPU_N12)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1213) Value(CPU_N12)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1233) Value(CPU_N12)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1233-fpu) Value(CPU_N12)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1233-spu) Value(CPU_N12)
+
+EnumValue
+Enum(nds32_cpu_type) String(n13) Value(CPU_N13)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1337) Value(CPU_N13)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1337-fpu) Value(CPU_N13)
+
+EnumValue
+Enum(nds32_cpu_type) String(n1337-spu) Value(CPU_N13)
+
+EnumValue
Enum(nds32_cpu_type) String(simple) Value(CPU_SIMPLE)
mconfig-fpu=
@@ -321,6 +440,18 @@
Target Report Mask(FPU_DOUBLE)
Generate double-precision floating-point instructions.
+mforce-no-ext-dsp
+Target Undocumented Report Mask(FORCE_NO_EXT_DSP)
+Force disable hardware loop, even use -mext-dsp.
+
+msched-prolog-epilog
+Target Var(flag_sched_prolog_epilog) Init(0)
+Permit scheduling of a function's prologue and epilogue sequence.
+
+mret-in-naked-func
+Target Var(flag_ret_in_naked_func) Init(1)
+Generate return instruction in naked function.
+
malways-save-lp
Target Var(flag_always_save_lp) Init(0)
Always save $lp in the stack.
@@ -328,3 +459,7 @@
munaligned-access
Target Report Var(flag_unaligned_access) Init(0)
Enable unaligned word and halfword accesses to packed data.
+
+minline-asm-r15
+Target Report Var(flag_inline_asm_r15) Init(0)
+Allow use r15 for inline ASM.
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-opts.h gcc-8.2.0/gcc/config/nds32/nds32-opts.h
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-opts.h 2018-04-08 11:21:30.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-opts.h 2019-01-25 15:38:32.833242671 +0100
@@ -29,6 +29,7 @@
{
ARCH_V2,
ARCH_V3,
+ ARCH_V3J,
ARCH_V3M,
ARCH_V3F,
ARCH_V3S
@@ -42,6 +43,10 @@
CPU_N8,
CPU_E8,
CPU_N9,
+ CPU_N10,
+ CPU_GRAYWOLF,
+ CPU_N12,
+ CPU_N13,
CPU_SIMPLE
};
@@ -53,6 +58,13 @@
CMODEL_LARGE
};
+/* The code model defines the address generation strategy. */
+enum nds32_ict_model_type
+{
+ ICT_MODEL_SMALL,
+ ICT_MODEL_LARGE
+};
+
/* Multiply instruction configuration. */
enum nds32_mul_type
{
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-peephole2.md gcc-8.2.0/gcc/config/nds32/nds32-peephole2.md
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-peephole2.md 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/nds32-peephole2.md 2019-01-25 15:38:32.833242671 +0100
@@ -22,3 +22,139 @@
;; Use define_peephole2 to handle possible target-specific optimization.
;; ------------------------------------------------------------------------
+;; Try to utilize 16-bit instruction by swap operand if possible.
+;; ------------------------------------------------------------------------
+
+;; Try to make add as add45.
+(define_peephole2
+ [(set (match_operand:QIHISI 0 "register_operand" "")
+ (plus:QIHISI (match_operand:QIHISI 1 "register_operand" "")
+ (match_operand:QIHISI 2 "register_operand" "")))]
+ "reload_completed
+ && TARGET_16_BIT
+ && REGNO (operands[0]) == REGNO (operands[2])
+ && REGNO (operands[0]) != REGNO (operands[1])
+ && TEST_HARD_REG_BIT (reg_class_contents[MIDDLE_REGS], REGNO (operands[0]))"
+ [(set (match_dup 0) (plus:QIHISI (match_dup 2) (match_dup 1)))])
+
+;; Try to make xor/ior/and/mult as xor33/ior33/and33/mult33.
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operator:SI 1 "nds32_have_33_inst_operator"
+ [(match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "register_operand" "")]))]
+ "reload_completed
+ && TARGET_16_BIT
+ && REGNO (operands[0]) == REGNO (operands[3])
+ && REGNO (operands[0]) != REGNO (operands[2])
+ && TEST_HARD_REG_BIT (reg_class_contents[LOW_REGS], REGNO (operands[0]))
+ && TEST_HARD_REG_BIT (reg_class_contents[LOW_REGS], REGNO (operands[2]))"
+ [(set (match_dup 0) (match_op_dup 1 [(match_dup 3) (match_dup 2)]))])
+
+(define_peephole
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" ""))
+ (set (match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "register_operand" ""))]
+ "TARGET_16_BIT
+ && !TARGET_ISA_V2
+ && NDS32_IS_GPR_REGNUM (REGNO (operands[0]))
+ && NDS32_IS_GPR_REGNUM (REGNO (operands[1]))
+ && ((REGNO (operands[0]) & 0x1) == 0)
+ && ((REGNO (operands[1]) & 0x1) == 0)
+ && (REGNO (operands[0]) + 1) == REGNO (operands[2])
+ && (REGNO (operands[1]) + 1) == REGNO (operands[3])"
+ "movd44\t%0, %1"
+ [(set_attr "type" "alu")
+ (set_attr "length" "2")])
+
+;; Merge two fcpyss to fcpysd.
+(define_peephole2
+ [(set (match_operand:SF 0 "float_even_register_operand" "")
+ (match_operand:SF 1 "float_even_register_operand" ""))
+ (set (match_operand:SF 2 "float_odd_register_operand" "")
+ (match_operand:SF 3 "float_odd_register_operand" ""))]
+ "(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
+ && REGNO (operands[0]) == REGNO (operands[2]) - 1
+ && REGNO (operands[1]) == REGNO (operands[3]) - 1"
+ [(set (match_dup 4) (match_dup 5))]
+ {
+ operands[4] = gen_rtx_REG (DFmode, REGNO (operands[0]));
+ operands[5] = gen_rtx_REG (DFmode, REGNO (operands[1]));
+ })
+
+(define_peephole2
+ [(set (match_operand:SF 0 "float_odd_register_operand" "")
+ (match_operand:SF 1 "float_odd_register_operand" ""))
+ (set (match_operand:SF 2 "float_even_register_operand" "")
+ (match_operand:SF 3 "float_even_register_operand" ""))]
+ "(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
+ && REGNO (operands[2]) == REGNO (operands[0]) - 1
+ && REGNO (operands[3]) == REGNO (operands[1]) - 1"
+ [(set (match_dup 4) (match_dup 5))]
+ {
+ operands[4] = gen_rtx_REG (DFmode, REGNO (operands[2]));
+ operands[5] = gen_rtx_REG (DFmode, REGNO (operands[3]));
+ })
+
+;; ------------------------------------------------------------------------
+;; GCC will prefer [u]divmodsi3 rather than [u]divsi3 even remainder is
+;; unused, so we use split to drop mod operation for lower register pressure.
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand")
+ (div:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand")))
+ (set (match_operand:SI 3 "register_operand")
+ (mod:SI (match_dup 1) (match_dup 2)))]
+ "find_regno_note (insn, REG_UNUSED, REGNO (operands[3])) != NULL
+ && can_create_pseudo_p ()"
+ [(set (match_dup 0)
+ (div:SI (match_dup 1)
+ (match_dup 2)))])
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand")
+ (udiv:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand")))
+ (set (match_operand:SI 3 "register_operand")
+ (umod:SI (match_dup 1) (match_dup 2)))]
+ "find_regno_note (insn, REG_UNUSED, REGNO (operands[3])) != NULL
+ && can_create_pseudo_p ()"
+ [(set (match_dup 0)
+ (udiv:SI (match_dup 1)
+ (match_dup 2)))])
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand")
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
+ (sign_extend:DI (match_operand:SI 2 "register_operand"))))]
+ "NDS32_EXT_DSP_P ()
+ && peep2_regno_dead_p (1, WORDS_BIG_ENDIAN ? REGNO (operands[0]) + 1 : REGNO (operands[0]))"
+ [(const_int 1)]
+{
+ rtx highpart = nds32_di_high_part_subreg (operands[0]);
+ emit_insn (gen_smulsi3_highpart (highpart, operands[1], operands[2]));
+ DONE;
+})
+
+(define_split
+ [(set (match_operand:DI 0 "nds32_general_register_operand" "")
+ (match_operand:DI 1 "nds32_general_register_operand" ""))]
+ "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) != NULL
+ || find_regno_note (insn, REG_UNUSED, REGNO (operands[0]) + 1) != NULL"
+ [(set (match_dup 0) (match_dup 1))]
+{
+ rtx dead_note = find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0]));
+ HOST_WIDE_INT offset;
+ if (dead_note == NULL_RTX)
+ offset = 0;
+ else
+ offset = 4;
+ operands[0] = simplify_gen_subreg (
+ SImode, operands[0],
+ DImode, offset);
+ operands[1] = simplify_gen_subreg (
+ SImode, operands[1],
+ DImode, offset);
+})
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-pipelines-auxiliary.c gcc-8.2.0/gcc/config/nds32/nds32-pipelines-auxiliary.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-pipelines-auxiliary.c 2018-04-08 11:21:30.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-pipelines-auxiliary.c 2019-01-25 15:38:32.833242671 +0100
@@ -306,6 +306,19 @@
return false;
}
+/* Determine if the latency is occured when the consumer PBSADA_INSN uses the
+ value of DEF_REG in its Rt field. */
+bool
+pbsada_insn_rt_dep_reg_p (rtx pbsada_insn, rtx def_reg)
+{
+ rtx pbsada_rt = SET_DEST (PATTERN (pbsada_insn));
+
+ if (rtx_equal_p (def_reg, pbsada_rt))
+ return true;
+
+ return false;
+}
+
/* Check if INSN is a movd44 insn consuming DEF_REG. */
bool
movd44_even_dep_p (rtx_insn *insn, rtx def_reg)
@@ -335,6 +348,103 @@
return false;
}
+/* Check if INSN is a wext insn consuming DEF_REG. */
+bool
+wext_odd_dep_p (rtx insn, rtx def_reg)
+{
+ rtx shift_rtx = XEXP (SET_SRC (PATTERN (insn)), 0);
+ rtx use_reg = XEXP (shift_rtx, 0);
+ rtx pos_rtx = XEXP (shift_rtx, 1);
+
+ if (REG_P (pos_rtx) && reg_overlap_p (def_reg, pos_rtx))
+ return true;
+
+ if (GET_MODE (def_reg) == DImode)
+ return reg_overlap_p (def_reg, use_reg);
+
+ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG);
+ gcc_assert (REG_P (use_reg));
+
+ if (REG_P (def_reg))
+ {
+ if (!TARGET_BIG_ENDIAN)
+ return REGNO (def_reg) == REGNO (use_reg) + 1;
+ else
+ return REGNO (def_reg) == REGNO (use_reg);
+ }
+
+ if (GET_CODE (def_reg) == SUBREG)
+ {
+ if (!reg_overlap_p (def_reg, use_reg))
+ return false;
+
+ if (!TARGET_BIG_ENDIAN)
+ return SUBREG_BYTE (def_reg) == 4;
+ else
+ return SUBREG_BYTE (def_reg) == 0;
+ }
+
+ return false;
+}
+
+/* Check if INSN is a bpick insn consuming DEF_REG. */
+bool
+bpick_ra_rb_dep_p (rtx insn, rtx def_reg)
+{
+ rtx ior_rtx = SET_SRC (PATTERN (insn));
+ rtx and1_rtx = XEXP (ior_rtx, 0);
+ rtx and2_rtx = XEXP (ior_rtx, 1);
+ rtx reg1_0 = XEXP (and1_rtx, 0);
+ rtx reg1_1 = XEXP (and1_rtx, 1);
+ rtx reg2_0 = XEXP (and2_rtx, 0);
+ rtx reg2_1 = XEXP (and2_rtx, 1);
+
+ if (GET_CODE (reg1_0) == NOT)
+ {
+ if (rtx_equal_p (reg1_0, reg2_0))
+ return reg_overlap_p (def_reg, reg1_1)
+ || reg_overlap_p (def_reg, reg2_1);
+
+ if (rtx_equal_p (reg1_0, reg2_1))
+ return reg_overlap_p (def_reg, reg1_1)
+ || reg_overlap_p (def_reg, reg2_0);
+ }
+
+ if (GET_CODE (reg1_1) == NOT)
+ {
+ if (rtx_equal_p (reg1_1, reg2_0))
+ return reg_overlap_p (def_reg, reg1_0)
+ || reg_overlap_p (def_reg, reg2_1);
+
+ if (rtx_equal_p (reg1_1, reg2_1))
+ return reg_overlap_p (def_reg, reg1_0)
+ || reg_overlap_p (def_reg, reg2_0);
+ }
+
+ if (GET_CODE (reg2_0) == NOT)
+ {
+ if (rtx_equal_p (reg2_0, reg1_0))
+ return reg_overlap_p (def_reg, reg2_1)
+ || reg_overlap_p (def_reg, reg1_1);
+
+ if (rtx_equal_p (reg2_0, reg1_1))
+ return reg_overlap_p (def_reg, reg2_1)
+ || reg_overlap_p (def_reg, reg1_0);
+ }
+
+ if (GET_CODE (reg2_1) == NOT)
+ {
+ if (rtx_equal_p (reg2_1, reg1_0))
+ return reg_overlap_p (def_reg, reg2_0)
+ || reg_overlap_p (def_reg, reg1_1);
+
+ if (rtx_equal_p (reg2_1, reg1_1))
+ return reg_overlap_p (def_reg, reg2_0)
+ || reg_overlap_p (def_reg, reg1_0);
+ }
+
+ gcc_unreachable ();
+}
} // namespace scheduling
} // namespace nds32
@@ -375,8 +485,7 @@
operations in order to write two registers. We have to check the
dependency from the producer to the first micro-operation. */
case TYPE_DIV:
- if (INSN_CODE (consumer) == CODE_FOR_divmodsi4
- || INSN_CODE (consumer) == CODE_FOR_udivmodsi4)
+ if (divmod_p (consumer))
use_rtx = SET_SRC (parallel_element (consumer, 0));
else
use_rtx = SET_SRC (PATTERN (consumer));
@@ -506,8 +615,7 @@
operations in order to write two registers. We have to check the
dependency from the producer to the first micro-operation. */
case TYPE_DIV:
- if (INSN_CODE (consumer) == CODE_FOR_divmodsi4
- || INSN_CODE (consumer) == CODE_FOR_udivmodsi4)
+ if (divmod_p (consumer))
use_rtx = SET_SRC (parallel_element (consumer, 0));
else
use_rtx = SET_SRC (PATTERN (consumer));
@@ -606,8 +714,7 @@
break;
case TYPE_DIV:
- if (INSN_CODE (consumer) == CODE_FOR_divmodsi4
- || INSN_CODE (consumer) == CODE_FOR_udivmodsi4)
+ if (divmod_p (consumer))
use_rtx = SET_SRC (parallel_element (consumer, 0));
else
use_rtx = SET_SRC (PATTERN (consumer));
@@ -706,13 +813,175 @@
We have to check the dependency from the producer to the first
micro-operation. */
case TYPE_DIV:
- if (INSN_CODE (consumer) == CODE_FOR_divmodsi4
- || INSN_CODE (consumer) == CODE_FOR_udivmodsi4)
+ if (divmod_p (consumer))
+ use_rtx = SET_SRC (parallel_element (consumer, 0));
+ else
+ use_rtx = SET_SRC (PATTERN (consumer));
+ break;
+
+ case TYPE_MMU:
+ if (GET_CODE (PATTERN (consumer)) == SET)
+ use_rtx = SET_SRC (PATTERN (consumer));
+ else
+ return true;
+ break;
+
+ case TYPE_LOAD:
+ case TYPE_STORE:
+ use_rtx = extract_mem_rtx (consumer);
+ break;
+
+ case TYPE_LOAD_MULTIPLE:
+ case TYPE_STORE_MULTIPLE:
+ use_rtx = extract_base_reg (consumer);
+ break;
+
+ case TYPE_BRANCH:
+ use_rtx = PATTERN (consumer);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (reg_overlap_p (def_reg, use_rtx))
+ return true;
+
+ return false;
+}
+
+/* Check the dependency between the producer defining DEF_REG and CONSUMER
+ requiring input operand at EX. */
+bool
+n10_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg)
+{
+ rtx use_rtx;
+
+ switch (get_attr_type (consumer))
+ {
+ case TYPE_ALU:
+ case TYPE_PBSAD:
+ case TYPE_MUL:
+ case TYPE_DALU:
+ case TYPE_DALU64:
+ case TYPE_DMUL:
+ case TYPE_DPACK:
+ case TYPE_DINSB:
+ case TYPE_DCMP:
+ case TYPE_DCLIP:
+ case TYPE_DALUROUND:
+ use_rtx = SET_SRC (PATTERN (consumer));
+ break;
+
+ case TYPE_ALU_SHIFT:
+ use_rtx = extract_shift_reg (consumer);
+ break;
+
+ case TYPE_PBSADA:
+ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg);
+
+ case TYPE_MAC:
+ case TYPE_DMAC:
+ use_rtx = extract_mac_non_acc_rtx (consumer);
+ break;
+
+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two
+ results, the quotient and the remainder. */
+ case TYPE_DIV:
+ if (divmod_p (consumer))
+ use_rtx = SET_SRC (parallel_element (consumer, 0));
+ else
+ use_rtx = SET_SRC (PATTERN (consumer));
+ break;
+
+ case TYPE_DWEXT:
+ return wext_odd_dep_p (consumer, def_reg);
+
+ case TYPE_DBPICK:
+ return bpick_ra_rb_dep_p (consumer, def_reg);
+
+ case TYPE_MMU:
+ if (GET_CODE (PATTERN (consumer)) == SET)
+ use_rtx = SET_SRC (PATTERN (consumer));
+ else
+ return true;
+ break;
+
+ case TYPE_LOAD:
+ case TYPE_STORE:
+ use_rtx = extract_mem_rtx (consumer);
+ break;
+
+ case TYPE_LOAD_MULTIPLE:
+ case TYPE_STORE_MULTIPLE:
+ use_rtx = extract_base_reg (consumer);
+ break;
+
+ case TYPE_BRANCH:
+ use_rtx = PATTERN (consumer);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (reg_overlap_p (def_reg, use_rtx))
+ return true;
+
+ return false;
+}
+
+/* Check the dependency between the producer defining DEF_REG and CONSUMER
+ requiring input operand at EX. */
+bool
+gw_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg)
+{
+ rtx use_rtx;
+
+ switch (get_attr_type (consumer))
+ {
+ case TYPE_ALU:
+ case TYPE_PBSAD:
+ case TYPE_MUL:
+ case TYPE_DALU:
+ case TYPE_DALU64:
+ case TYPE_DMUL:
+ case TYPE_DPACK:
+ case TYPE_DINSB:
+ case TYPE_DCMP:
+ case TYPE_DCLIP:
+ case TYPE_DALUROUND:
+ use_rtx = SET_SRC (PATTERN (consumer));
+ break;
+
+ case TYPE_ALU_SHIFT:
+ use_rtx = extract_shift_reg (consumer);
+ break;
+
+ case TYPE_PBSADA:
+ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg);
+
+ case TYPE_MAC:
+ case TYPE_DMAC:
+ use_rtx = extract_mac_non_acc_rtx (consumer);
+ break;
+
+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two
+ results, the quotient and the remainder. We have to check the
+ dependency from the producer to the first micro-operation. */
+ case TYPE_DIV:
+ if (divmod_p (consumer))
use_rtx = SET_SRC (parallel_element (consumer, 0));
else
use_rtx = SET_SRC (PATTERN (consumer));
break;
+ case TYPE_DWEXT:
+ return wext_odd_dep_p (consumer, def_reg);
+
+ case TYPE_DBPICK:
+ return bpick_ra_rb_dep_p (consumer, def_reg);
+
case TYPE_MMU:
if (GET_CODE (PATTERN (consumer)) == SET)
use_rtx = SET_SRC (PATTERN (consumer));
@@ -744,7 +1013,153 @@
return false;
}
+/* Check dependencies from any stages to ALU_E1 (E1). This is a helper
+ function of n13_consumed_by_e1_dep_p (). */
+bool
+n13_alu_e1_insn_dep_reg_p (rtx_insn *alu_e1_insn, rtx def_reg)
+{
+ rtx unspec_rtx, operand_ra, operand_rb;
+ rtx src_rtx, dst_rtx;
+
+ switch (INSN_CODE (alu_e1_insn))
+ {
+ /* BSP and BSE are supported by built-in functions, the corresponding
+ patterns are formed by UNSPEC RTXs. We have to handle them
+ individually. */
+ case CODE_FOR_unspec_bsp:
+ case CODE_FOR_unspec_bse:
+ unspec_rtx = SET_SRC (parallel_element (alu_e1_insn, 0));
+ gcc_assert (GET_CODE (unspec_rtx) == UNSPEC);
+
+ operand_ra = XVECEXP (unspec_rtx, 0, 0);
+ operand_rb = XVECEXP (unspec_rtx, 0, 1);
+
+ if (rtx_equal_p (def_reg, operand_ra)
+ || rtx_equal_p (def_reg, operand_rb))
+ return true;
+
+ return false;
+
+ /* Unlink general ALU instructions, MOVD44 requires operands at E1. */
+ case CODE_FOR_move_di:
+ case CODE_FOR_move_df:
+ src_rtx = SET_SRC (PATTERN (alu_e1_insn));
+ dst_rtx = SET_DEST (PATTERN (alu_e1_insn));
+
+ if (REG_P (dst_rtx) && REG_P (src_rtx)
+ && rtx_equal_p (src_rtx, def_reg))
+ return true;
+
+ return false;
+
+ default:
+ return false;
+ }
+}
+
+/* Check the dependency between the producer defining DEF_REG and CONSUMER
+ requiring input operand at E1. Because the address generation unti is
+ at E1, the address input should be ready at E1. Note that the branch
+ target is also a kind of addresses, so we have to check it. */
+bool
+n13_consumed_by_e1_dep_p (rtx_insn *consumer, rtx def_reg)
+{
+ rtx use_rtx;
+
+ switch (get_attr_type (consumer))
+ {
+ /* ALU_E1 */
+ case TYPE_ALU:
+ return n13_alu_e1_insn_dep_reg_p (consumer, def_reg);
+
+ case TYPE_PBSADA:
+ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg);
+
+ case TYPE_PBSAD:
+ case TYPE_MUL:
+ use_rtx = SET_SRC (PATTERN (consumer));
+ break;
+
+ case TYPE_MAC:
+ use_rtx = extract_mac_non_acc_rtx (consumer);
+ break;
+
+ case TYPE_DIV:
+ if (divmod_p (consumer))
+ use_rtx = SET_SRC (parallel_element (consumer, 0));
+ else
+ use_rtx = SET_SRC (PATTERN (consumer));
+ break;
+
+ case TYPE_MMU:
+ if (GET_CODE (PATTERN (consumer)) == SET)
+ use_rtx = SET_SRC (PATTERN (consumer));
+ else
+ return true;
+ break;
+
+ case TYPE_BRANCH:
+ use_rtx = extract_branch_target_rtx (consumer);
+ break;
+
+ case TYPE_LOAD:
+ case TYPE_STORE:
+ use_rtx = extract_mem_rtx (consumer);
+ break;
+
+ case TYPE_LOAD_MULTIPLE:
+ case TYPE_STORE_MULTIPLE:
+ use_rtx = extract_base_reg (consumer);
+ break;
+
+ default:
+ return false;
+ }
+
+ if (reg_overlap_p (def_reg, use_rtx))
+ return true;
+
+ return false;
+}
+
+/* Check the dependency between the producer defining DEF_REG and CONSUMER
+ requiring input operand at E2. */
+bool
+n13_consumed_by_e2_dep_p (rtx_insn *consumer, rtx def_reg)
+{
+ rtx use_rtx;
+
+ switch (get_attr_type (consumer))
+ {
+ case TYPE_ALU:
+ case TYPE_STORE:
+ use_rtx = SET_SRC (PATTERN (consumer));
+ break;
+
+ case TYPE_ALU_SHIFT:
+ use_rtx = extract_shift_reg (consumer);
+ break;
+
+ case TYPE_PBSADA:
+ return pbsada_insn_rt_dep_reg_p (consumer, def_reg);
+
+ case TYPE_STORE_MULTIPLE:
+ use_rtx = extract_nth_access_rtx (consumer, 0);
+ break;
+
+ case TYPE_BRANCH:
+ use_rtx = extract_branch_condition_rtx (consumer);
+ break;
+
+ default:
+ gcc_unreachable();
+ }
+
+ if (reg_overlap_p (def_reg, use_rtx))
+ return true;
+ return false;
+}
} // anonymous namespace
/* ------------------------------------------------------------------------ */
@@ -837,8 +1252,7 @@
break;
case TYPE_DIV:
- if (INSN_CODE (producer) == CODE_FOR_divmodsi4
- || INSN_CODE (producer) == CODE_FOR_udivmodsi4)
+ if (divmod_p (producer))
def_reg = SET_DEST (parallel_element (producer, 1));
else
def_reg = SET_DEST (PATTERN (producer));
@@ -969,8 +1383,7 @@
break;
case TYPE_DIV:
- if (INSN_CODE (producer) == CODE_FOR_divmodsi4
- || INSN_CODE (producer) == CODE_FOR_udivmodsi4)
+ if (divmod_p (producer))
{
rtx def_reg1 = SET_DEST (parallel_element (producer, 0));
rtx def_reg2 = SET_DEST (parallel_element (producer, 1));
@@ -1073,8 +1486,7 @@
results, the quotient and the remainder. We have to handle them
individually. */
case TYPE_DIV:
- if (INSN_CODE (producer) == CODE_FOR_divmodsi4
- || INSN_CODE (producer) == CODE_FOR_udivmodsi4)
+ if (divmod_p (producer))
{
rtx def_reg1 = SET_DEST (parallel_element (producer, 0));
rtx def_reg2 = SET_DEST (parallel_element (producer, 1));
@@ -1132,4 +1544,245 @@
return n9_3r2w_consumed_by_ex_dep_p (consumer, last_def_reg);
}
+/* Guard functions for N10 cores. */
+
+/* Check dependencies from EX to EX (ADDR_OUT -> ADDR_IN). */
+bool
+nds32_n10_ex_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ gcc_assert (get_attr_type (producer) == TYPE_FLOAD
+ || get_attr_type (producer) == TYPE_FSTORE);
+ gcc_assert (get_attr_type (consumer) == TYPE_FLOAD
+ || get_attr_type (consumer) == TYPE_FSTORE);
+
+ if (!post_update_insn_p (producer))
+ return false;
+
+ return reg_overlap_p (extract_base_reg (producer),
+ extract_mem_rtx (consumer));
+}
+
+/* Check dependencies from MM to EX. */
+bool
+nds32_n10_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ rtx def_reg;
+
+ switch (get_attr_type (producer))
+ {
+ case TYPE_LOAD:
+ case TYPE_MUL:
+ case TYPE_MAC:
+ case TYPE_DALU64:
+ case TYPE_DMUL:
+ case TYPE_DMAC:
+ case TYPE_DALUROUND:
+ case TYPE_DBPICK:
+ case TYPE_DWEXT:
+ def_reg = SET_DEST (PATTERN (producer));
+ break;
+
+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two
+ results, the quotient and the remainder. We have to handle them
+ individually. */
+ case TYPE_DIV:
+ if (divmod_p (producer))
+ {
+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0));
+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1));
+
+ return (n10_consumed_by_ex_dep_p (consumer, def_reg1)
+ || n10_consumed_by_ex_dep_p (consumer, def_reg2));
+ }
+
+ def_reg = SET_DEST (PATTERN (producer));
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return n10_consumed_by_ex_dep_p (consumer, def_reg);
+}
+
+/* Check dependencies from LMW(N, N) to EX. */
+bool
+nds32_n10_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ rtx last_def_reg = extract_nth_access_reg (producer, -1);
+
+ return n10_consumed_by_ex_dep_p (consumer, last_def_reg);
+}
+
+/* Guard functions for Graywolf cores. */
+
+/* Check dependencies from EX to EX (ADDR_OUT -> ADDR_IN). */
+bool
+nds32_gw_ex_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ return nds32_n10_ex_to_ex_p (producer, consumer);
+}
+
+/* Check dependencies from MM to EX. */
+bool
+nds32_gw_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ rtx def_reg;
+
+ switch (get_attr_type (producer))
+ {
+ case TYPE_LOAD:
+ case TYPE_MUL:
+ case TYPE_MAC:
+ case TYPE_DALU64:
+ case TYPE_DMUL:
+ case TYPE_DMAC:
+ case TYPE_DALUROUND:
+ case TYPE_DBPICK:
+ case TYPE_DWEXT:
+ def_reg = SET_DEST (PATTERN (producer));
+ break;
+
+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two
+ results, the quotient and the remainder. We have to handle them
+ individually. */
+ case TYPE_DIV:
+ if (divmod_p (producer))
+ {
+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0));
+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1));
+
+ return (gw_consumed_by_ex_dep_p (consumer, def_reg1)
+ || gw_consumed_by_ex_dep_p (consumer, def_reg2));
+ }
+
+ def_reg = SET_DEST (PATTERN (producer));
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return gw_consumed_by_ex_dep_p (consumer, def_reg);
+}
+
+/* Check dependencies from LMW(N, N) to EX. */
+bool
+nds32_gw_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ rtx last_def_reg = extract_nth_access_reg (producer, -1);
+
+ return gw_consumed_by_ex_dep_p (consumer, last_def_reg);
+}
+
+/* Guard functions for N12/N13 cores. */
+
+/* Check dependencies from E2 to E1. */
+bool
+nds32_n13_e2_to_e1_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ rtx def_reg;
+
+ switch (get_attr_type (producer))
+ {
+ /* Only post-update load/store instructions are considered. These
+ instructions produces address output at E2. */
+ case TYPE_LOAD:
+ case TYPE_STORE:
+ case TYPE_LOAD_MULTIPLE:
+ case TYPE_STORE_MULTIPLE:
+ if (!post_update_insn_p (producer))
+ return false;
+
+ def_reg = extract_base_reg (producer);
+ break;
+
+ case TYPE_ALU:
+ case TYPE_ALU_SHIFT:
+ case TYPE_PBSAD:
+ case TYPE_PBSADA:
+ case TYPE_MUL:
+ case TYPE_MAC:
+ def_reg = SET_DEST (PATTERN (producer));
+ break;
+
+ case TYPE_BRANCH:
+ return true;
+
+ case TYPE_DIV:
+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two
+ results, the quotient and the remainder. We have to handle them
+ individually. */
+ if (divmod_p (producer))
+ {
+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0));
+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1));
+
+ return (n13_consumed_by_e1_dep_p (consumer, def_reg1)
+ || n13_consumed_by_e1_dep_p (consumer, def_reg2));
+ }
+
+ def_reg = SET_DEST (PATTERN (producer));
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return n13_consumed_by_e1_dep_p (consumer, def_reg);
+}
+
+/* Check dependencies from Load-Store Unit (E3) to E1. */
+bool
+nds32_n13_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ rtx def_reg = SET_DEST (PATTERN (producer));
+
+ gcc_assert (get_attr_type (producer) == TYPE_LOAD);
+ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG);
+
+ return n13_consumed_by_e1_dep_p (consumer, def_reg);
+}
+
+/* Check dependencies from Load-Store Unit (E3) to E2. */
+bool
+nds32_n13_load_to_e2_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ rtx def_reg = SET_DEST (PATTERN (producer));
+
+ gcc_assert (get_attr_type (producer) == TYPE_LOAD);
+ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG);
+
+ return n13_consumed_by_e2_dep_p (consumer, def_reg);
+}
+
+/* Check dependencies from LMW(N, N) to E1. */
+bool
+nds32_n13_last_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ rtx last_def_reg = extract_nth_access_reg (producer, -1);
+
+ return n13_consumed_by_e1_dep_p (consumer, last_def_reg);
+}
+
+/* Check dependencies from LMW(N, N) to E2. */
+bool
+nds32_n13_last_load_to_e2_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ rtx last_def_reg = extract_nth_access_reg (producer, -1);
+
+ return n13_consumed_by_e2_dep_p (consumer, last_def_reg);
+}
+
+/* Check dependencies from LMW(N, N-1) to E2. */
+bool
+nds32_n13_last_two_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer)
+{
+ rtx last_two_def_reg = extract_nth_access_reg (producer, -2);
+
+ if (last_two_def_reg == NULL_RTX)
+ return false;
+
+ return n13_consumed_by_e1_dep_p (consumer, last_two_def_reg);
+}
/* ------------------------------------------------------------------------ */
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-predicates.c gcc-8.2.0/gcc/config/nds32/nds32-predicates.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-predicates.c 2018-05-07 04:22:07.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-predicates.c 2019-01-25 15:41:54.217806220 +0100
@@ -356,8 +356,8 @@
}
/* Function to check if 'bclr' instruction can be used with IVAL. */
-int
-nds32_can_use_bclr_p (int ival)
+bool
+nds32_can_use_bclr_p (HOST_WIDE_INT ival)
{
int one_bit_count;
unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode);
@@ -373,8 +373,8 @@
}
/* Function to check if 'bset' instruction can be used with IVAL. */
-int
-nds32_can_use_bset_p (int ival)
+bool
+nds32_can_use_bset_p (HOST_WIDE_INT ival)
{
int one_bit_count;
unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode);
@@ -389,8 +389,8 @@
}
/* Function to check if 'btgl' instruction can be used with IVAL. */
-int
-nds32_can_use_btgl_p (int ival)
+bool
+nds32_can_use_btgl_p (HOST_WIDE_INT ival)
{
int one_bit_count;
unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode);
@@ -405,8 +405,8 @@
}
/* Function to check if 'bitci' instruction can be used with IVAL. */
-int
-nds32_can_use_bitci_p (int ival)
+bool
+nds32_can_use_bitci_p (HOST_WIDE_INT ival)
{
/* If we are using V3 ISA, we have 'bitci' instruction.
Try to see if we can present 'andi' semantic with
@@ -518,4 +518,117 @@
return val >= lower && val < upper;
}
+
+bool
+nds32_const_unspec_p (rtx x)
+{
+ if (GET_CODE (x) == CONST)
+ {
+ x = XEXP (x, 0);
+
+ if (GET_CODE (x) == PLUS)
+ x = XEXP (x, 0);
+
+ if (GET_CODE (x) == UNSPEC)
+ {
+ switch (XINT (x, 1))
+ {
+ case UNSPEC_GOTINIT:
+ case UNSPEC_GOT:
+ case UNSPEC_GOTOFF:
+ case UNSPEC_PLT:
+ case UNSPEC_TLSGD:
+ case UNSPEC_TLSLD:
+ case UNSPEC_TLSIE:
+ case UNSPEC_TLSLE:
+ return false;
+ default:
+ return true;
+ }
+ }
+ }
+
+ if (GET_CODE (x) == SYMBOL_REF
+ && SYMBOL_REF_TLS_MODEL (x))
+ return false;
+
+ return true;
+}
+
+HOST_WIDE_INT
+const_vector_to_hwint (rtx op)
+{
+ HOST_WIDE_INT hwint = 0;
+ HOST_WIDE_INT mask;
+ int i;
+ int shift_adv;
+ int shift = 0;
+ int nelem;
+
+ switch (GET_MODE (op))
+ {
+ case E_V2HImode:
+ mask = 0xffff;
+ shift_adv = 16;
+ nelem = 2;
+ break;
+ case E_V4QImode:
+ mask = 0xff;
+ shift_adv = 8;
+ nelem = 4;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (TARGET_BIG_ENDIAN)
+ {
+ for (i = 0; i < nelem; ++i)
+ {
+ HOST_WIDE_INT val = XINT (XVECEXP (op, 0, nelem - i - 1), 0);
+ hwint |= (val & mask) << shift;
+ shift = shift + shift_adv;
+ }
+ }
+ else
+ {
+ for (i = 0; i < nelem; ++i)
+ {
+ HOST_WIDE_INT val = XINT (XVECEXP (op, 0, i), 0);
+ hwint |= (val & mask) << shift;
+ shift = shift + shift_adv;
+ }
+ }
+
+ return hwint;
+}
+
+bool
+nds32_valid_CVp5_p (rtx op)
+{
+ HOST_WIDE_INT ival = const_vector_to_hwint (op);
+ return (ival < ((1 << 5) + 16)) && (ival >= (0 + 16));
+}
+
+bool
+nds32_valid_CVs5_p (rtx op)
+{
+ HOST_WIDE_INT ival = const_vector_to_hwint (op);
+ return (ival < (1 << 4)) && (ival >= -(1 << 4));
+}
+
+bool
+nds32_valid_CVs2_p (rtx op)
+{
+ HOST_WIDE_INT ival = const_vector_to_hwint (op);
+ return (ival < (1 << 19)) && (ival >= -(1 << 19));
+}
+
+bool
+nds32_valid_CVhi_p (rtx op)
+{
+ HOST_WIDE_INT ival = const_vector_to_hwint (op);
+ return (ival != 0) && ((ival & 0xfff) == 0);
+}
+
/* ------------------------------------------------------------------------ */
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-protos.h gcc-8.2.0/gcc/config/nds32/nds32-protos.h
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-protos.h 2018-04-22 11:05:10.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-protos.h 2019-01-25 15:38:32.833242671 +0100
@@ -69,9 +69,10 @@
/* ------------------------------------------------------------------------ */
-/* Auxiliary functions for lwm/smw. */
+/* Auxiliary functions for manipulation DI mode. */
-extern bool nds32_valid_smw_lwm_base_p (rtx);
+extern rtx nds32_di_high_part_subreg(rtx);
+extern rtx nds32_di_low_part_subreg(rtx);
/* Auxiliary functions for expanding rtl used in nds32-multiple.md. */
@@ -116,6 +117,20 @@
extern bool nds32_n9_3r2w_mm_to_ex_p (rtx_insn *, rtx_insn *);
extern bool nds32_n9_last_load_to_ex_p (rtx_insn *, rtx_insn *);
+extern bool nds32_n10_ex_to_ex_p (rtx_insn *, rtx_insn *);
+extern bool nds32_n10_mm_to_ex_p (rtx_insn *, rtx_insn *);
+extern bool nds32_n10_last_load_to_ex_p (rtx_insn *, rtx_insn *);
+
+extern bool nds32_gw_ex_to_ex_p (rtx_insn *, rtx_insn *);
+extern bool nds32_gw_mm_to_ex_p (rtx_insn *, rtx_insn *);
+extern bool nds32_gw_last_load_to_ex_p (rtx_insn *, rtx_insn *);
+
+extern bool nds32_n13_e2_to_e1_p (rtx_insn *, rtx_insn *);
+extern bool nds32_n13_load_to_e1_p (rtx_insn *, rtx_insn *);
+extern bool nds32_n13_load_to_e2_p (rtx_insn *, rtx_insn *);
+extern bool nds32_n13_last_load_to_e1_p (rtx_insn *, rtx_insn *);
+extern bool nds32_n13_last_load_to_e2_p (rtx_insn *, rtx_insn *);
+extern bool nds32_n13_last_two_load_to_e1_p (rtx_insn *, rtx_insn *);
/* Auxiliary functions for stack operation predicate checking. */
@@ -123,24 +138,25 @@
/* Auxiliary functions for bit operation detection. */
-extern int nds32_can_use_bclr_p (int);
-extern int nds32_can_use_bset_p (int);
-extern int nds32_can_use_btgl_p (int);
+extern bool nds32_can_use_bclr_p (HOST_WIDE_INT);
+extern bool nds32_can_use_bset_p (HOST_WIDE_INT);
+extern bool nds32_can_use_btgl_p (HOST_WIDE_INT);
-extern int nds32_can_use_bitci_p (int);
+extern bool nds32_can_use_bitci_p (HOST_WIDE_INT);
extern bool nds32_const_double_range_ok_p (rtx, machine_mode,
HOST_WIDE_INT, HOST_WIDE_INT);
+extern bool nds32_const_unspec_p (rtx x);
+
/* Auxiliary function for 'Computing the Length of an Insn'. */
extern int nds32_adjust_insn_length (rtx_insn *, int);
/* Auxiliary functions for FP_AS_GP detection. */
-extern int nds32_fp_as_gp_check_available (void);
-
extern bool nds32_symbol_load_store_p (rtx_insn *);
+extern bool nds32_naked_function_p (tree);
/* Auxiliary functions for jump table generation. */
@@ -159,10 +175,50 @@
extern enum nds32_expand_result_type nds32_expand_movcc (rtx *);
extern void nds32_expand_float_movcc (rtx *);
+/* Auxiliary functions for expand extv/insv instruction. */
+
+extern enum nds32_expand_result_type nds32_expand_extv (rtx *);
+extern enum nds32_expand_result_type nds32_expand_insv (rtx *);
+
+/* Auxiliary functions for expand PIC instruction. */
+
+extern void nds32_expand_pic_move (rtx *);
+
+/* Auxiliary functions to legitimize PIC address. */
+
+extern rtx nds32_legitimize_pic_address (rtx);
+
+/* Auxiliary functions for expand TLS instruction. */
+
+extern void nds32_expand_tls_move (rtx *);
+
+/* Auxiliary functions to legitimize TLS address. */
+
+extern rtx nds32_legitimize_tls_address (rtx);
+
+/* Auxiliary functions to identify thread-local symbol. */
+
+extern bool nds32_tls_referenced_p (rtx);
+
+/* Auxiliary functions for expand ICT instruction. */
+
+extern void nds32_expand_ict_move (rtx *);
+
+/* Auxiliary functions to legitimize address for indirect-call symbol. */
+
+extern rtx nds32_legitimize_ict_address (rtx);
+
+/* Auxiliary functions to identify indirect-call symbol. */
+
+extern bool nds32_indirect_call_referenced_p (rtx);
/* Auxiliary functions to identify long-call symbol. */
extern bool nds32_long_call_p (rtx);
+/* Auxiliary functions to identify SYMBOL_REF and LABEL_REF pattern. */
+
+extern bool symbolic_reference_mentioned_p (rtx);
+
/* Auxiliary functions to identify conditional move comparison operand. */
extern int nds32_cond_move_p (rtx);
@@ -185,6 +241,7 @@
extern const char *nds32_output_float_load(rtx *);
extern const char *nds32_output_float_store(rtx *);
extern const char *nds32_output_smw_single_word (rtx *);
+extern const char *nds32_output_smw_double_word (rtx *);
extern const char *nds32_output_lmw_single_word (rtx *);
extern const char *nds32_output_double (rtx *, bool);
extern const char *nds32_output_cbranchsi4_equality_zero (rtx_insn *, rtx *);
@@ -193,9 +250,12 @@
rtx *);
extern const char *nds32_output_cbranchsi4_greater_less_zero (rtx_insn *, rtx *);
+extern const char *nds32_output_unpkd8 (rtx, rtx, rtx, rtx, bool);
+
extern const char *nds32_output_call (rtx, rtx *, rtx,
const char *, const char *, bool);
-
+extern const char *nds32_output_tls_desc (rtx *);
+extern const char *nds32_output_tls_ie (rtx *);
/* Auxiliary functions to output stack push/pop instruction. */
@@ -203,9 +263,19 @@
extern const char *nds32_output_stack_pop (rtx);
extern const char *nds32_output_return (void);
+
+/* Auxiliary functions to split/output sms pattern. */
+extern bool nds32_need_split_sms_p (rtx, rtx, rtx, rtx);
+extern const char *nds32_output_sms (rtx, rtx, rtx, rtx);
+extern void nds32_split_sms (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+
/* Auxiliary functions to split double word RTX pattern. */
extern void nds32_spilt_doubleword (rtx *, bool);
+extern void nds32_split_ashiftdi3 (rtx, rtx, rtx);
+extern void nds32_split_ashiftrtdi3 (rtx, rtx, rtx);
+extern void nds32_split_lshiftrtdi3 (rtx, rtx, rtx);
+extern void nds32_split_rotatertdi3 (rtx, rtx, rtx);
/* Auxiliary functions to split large constant RTX pattern. */
@@ -237,15 +307,29 @@
extern void nds32_asm_file_start_for_isr (void);
extern void nds32_asm_file_end_for_isr (void);
extern bool nds32_isr_function_p (tree);
+extern bool nds32_isr_function_critical_p (tree);
/* Auxiliary functions for cost calculation. */
+extern void nds32_init_rtx_costs (void);
extern bool nds32_rtx_costs_impl (rtx, machine_mode, int, int, int *, bool);
extern int nds32_address_cost_impl (rtx, machine_mode, addr_space_t, bool);
/* Auxiliary functions for pre-define marco. */
extern void nds32_cpu_cpp_builtins(struct cpp_reader *);
+/* Auxiliary functions for const_vector's constraints. */
+
+extern HOST_WIDE_INT const_vector_to_hwint (rtx);
+extern bool nds32_valid_CVp5_p (rtx);
+extern bool nds32_valid_CVs5_p (rtx);
+extern bool nds32_valid_CVs2_p (rtx);
+extern bool nds32_valid_CVhi_p (rtx);
+
+/* Auxiliary functions for lwm/smw. */
+
+extern bool nds32_valid_smw_lwm_base_p (rtx);
+
extern bool nds32_split_double_word_load_store_p (rtx *,bool);
namespace nds32 {
@@ -258,11 +342,13 @@
bool store_single_p (rtx_insn *);
bool load_double_p (rtx_insn *);
bool store_double_p (rtx_insn *);
+bool store_offset_reg_p (rtx_insn *);
bool post_update_insn_p (rtx_insn *);
bool immed_offset_p (rtx);
int find_post_update_rtx (rtx_insn *);
rtx extract_mem_rtx (rtx_insn *);
rtx extract_base_reg (rtx_insn *);
+rtx extract_offset_rtx (rtx_insn *);
rtx extract_shift_reg (rtx);
@@ -271,6 +357,8 @@
rtx extract_mac_non_acc_rtx (rtx_insn *);
+bool divmod_p (rtx_insn *);
+
rtx extract_branch_target_rtx (rtx_insn *);
rtx extract_branch_condition_rtx (rtx_insn *);
} // namespace nds32
@@ -279,5 +367,6 @@
/* Functions for create nds32 specific optimization pass. */
extern rtl_opt_pass *make_pass_nds32_relax_opt (gcc::context *);
+extern rtl_opt_pass *make_pass_nds32_fp_as_gp (gcc::context *);
/* ------------------------------------------------------------------------ */
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-relax-opt.c gcc-8.2.0/gcc/config/nds32/nds32-relax-opt.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-relax-opt.c 2018-04-01 12:07:40.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-relax-opt.c 2019-01-25 15:38:32.833242671 +0100
@@ -52,6 +52,8 @@
#include "cfgrtl.h"
#include "tree-pass.h"
+using namespace nds32;
+
/* This is used to create unique relax hint id value.
The initial value is 0. */
static int relax_group_id = 0;
@@ -185,6 +187,121 @@
return false;
}
+/* Return true if x is const and the referance is ict symbol. */
+static bool
+nds32_ict_const_p (rtx x)
+{
+ if (GET_CODE (x) == CONST)
+ {
+ x = XEXP (x, 0);
+ return nds32_indirect_call_referenced_p (x);
+ }
+ return FALSE;
+}
+
+/* Group the following pattern as relax candidates:
+
+ GOT:
+ sethi $ra, hi20(sym)
+ ori $ra, $ra, lo12(sym)
+ lw $rb, [$ra + $gp]
+
+ GOTOFF, TLSLE:
+ sethi $ra, hi20(sym)
+ ori $ra, $ra, lo12(sym)
+ LS $rb, [$ra + $gp]
+
+ GOTOFF, TLSLE:
+ sethi $ra, hi20(sym)
+ ori $ra, $ra, lo12(sym)
+ add $rb, $ra, $gp($tp)
+
+ Initial GOT table:
+ sethi $gp,hi20(sym)
+ ori $gp, $gp, lo12(sym)
+ add5.pc $gp */
+
+static auto_vec<rtx_insn *, 32> nds32_group_infos;
+/* Group the PIC and TLS relax candidate instructions for linker. */
+static bool
+nds32_pic_tls_group (rtx_insn *def_insn,
+ enum nds32_relax_insn_type relax_type,
+ int sym_type)
+{
+ df_ref def_record;
+ df_link *link;
+ rtx_insn *use_insn = NULL;
+ rtx pat, new_pat;
+ def_record = DF_INSN_DEFS (def_insn);
+ for (link = DF_REF_CHAIN (def_record); link; link = link->next)
+ {
+ if (!DF_REF_INSN_INFO (link->ref))
+ continue;
+
+ use_insn = DF_REF_INSN (link->ref);
+
+ /* Skip if define insn and use insn not in the same basic block. */
+ if (!dominated_by_p (CDI_DOMINATORS,
+ BLOCK_FOR_INSN (use_insn),
+ BLOCK_FOR_INSN (def_insn)))
+ return FALSE;
+
+ /* Skip if use_insn not active insn. */
+ if (!active_insn_p (use_insn))
+ return FALSE;
+
+ switch (relax_type)
+ {
+ case RELAX_ORI:
+
+ /* GOTOFF, TLSLE:
+ sethi $ra, hi20(sym)
+ ori $ra, $ra, lo12(sym)
+ add $rb, $ra, $gp($tp) */
+ if ((sym_type == UNSPEC_TLSLE
+ || sym_type == UNSPEC_GOTOFF)
+ && (recog_memoized (use_insn) == CODE_FOR_addsi3))
+ {
+ pat = XEXP (PATTERN (use_insn), 1);
+ new_pat =
+ gen_rtx_UNSPEC (SImode,
+ gen_rtvec (2, XEXP (pat, 0), XEXP (pat, 1)),
+ UNSPEC_ADD32);
+ validate_replace_rtx (pat, new_pat, use_insn);
+ nds32_group_infos.safe_push (use_insn);
+ }
+ else if (nds32_plus_reg_load_store_p (use_insn)
+ && !nds32_sp_base_or_plus_load_store_p (use_insn))
+ nds32_group_infos.safe_push (use_insn);
+ else
+ return FALSE;
+ break;
+
+ default:
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static int
+nds32_pic_tls_symbol_type (rtx x)
+{
+ x = XEXP (SET_SRC (PATTERN (x)), 1);
+
+ if (GET_CODE (x) == CONST)
+ {
+ x = XEXP (x, 0);
+
+ if (GET_CODE (x) == PLUS)
+ x = XEXP (x, 0);
+
+ return XINT (x, 1);
+ }
+
+ return XINT (x, 1);
+}
+
/* Group the relax candidates with group id. */
static void
nds32_group_insns (rtx sethi)
@@ -193,6 +310,7 @@
df_link *link;
rtx_insn *use_insn = NULL;
rtx group_id;
+ bool valid;
def_record = DF_INSN_DEFS (sethi);
@@ -242,6 +360,132 @@
/* Insert .relax_* directive. */
if (active_insn_p (use_insn))
emit_insn_before (gen_relax_group (group_id), use_insn);
+
+ /* Find ori ra, ra, unspec(symbol) instruction. */
+ if (use_insn != NULL
+ && recog_memoized (use_insn) == CODE_FOR_lo_sum
+ && !nds32_const_unspec_p (XEXP (SET_SRC (PATTERN (use_insn)), 1)))
+ {
+ int sym_type = nds32_pic_tls_symbol_type (use_insn);
+ valid = nds32_pic_tls_group (use_insn, RELAX_ORI, sym_type);
+
+ /* Insert .relax_* directive. */
+ while (!nds32_group_infos.is_empty ())
+ {
+ use_insn = nds32_group_infos.pop ();
+ if (valid)
+ emit_insn_before (gen_relax_group (group_id), use_insn);
+ }
+ }
+ }
+
+ relax_group_id++;
+}
+
+/* Convert relax group id in rtl. */
+
+static void
+nds32_group_tls_insn (rtx insn)
+{
+ rtx pat = PATTERN (insn);
+ rtx unspec_relax_group = XEXP (XVECEXP (pat, 0, 1), 0);
+
+ while (GET_CODE (pat) != SET && GET_CODE (pat) == PARALLEL)
+ {
+ pat = XVECEXP (pat, 0, 0);
+ }
+
+ if (GET_CODE (unspec_relax_group) == UNSPEC
+ && XINT (unspec_relax_group, 1) == UNSPEC_VOLATILE_RELAX_GROUP)
+ {
+ XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (relax_group_id);
+ }
+
+ relax_group_id++;
+}
+
+static bool
+nds32_float_reg_load_store_p (rtx_insn *insn)
+{
+ rtx pat = PATTERN (insn);
+
+ if (get_attr_type (insn) == TYPE_FLOAD
+ && GET_CODE (pat) == SET
+ && (GET_MODE (XEXP (pat, 0)) == SFmode
+ || GET_MODE (XEXP (pat, 0)) == DFmode)
+ && MEM_P (XEXP (pat, 1)))
+ {
+ rtx addr = XEXP (XEXP (pat, 1), 0);
+
+ /* [$ra] */
+ if (REG_P (addr))
+ return true;
+ /* [$ra + offset] */
+ if (GET_CODE (addr) == PLUS
+ && REG_P (XEXP (addr, 0))
+ && CONST_INT_P (XEXP (addr, 1)))
+ return true;
+ }
+ return false;
+}
+
+
+/* Group float load-store instructions:
+ la $ra, symbol
+ flsi $rt, [$ra + offset] */
+
+static void
+nds32_group_float_insns (rtx insn)
+{
+ df_ref def_record, use_record;
+ df_link *link;
+ rtx_insn *use_insn = NULL;
+ rtx group_id;
+
+ def_record = DF_INSN_DEFS (insn);
+
+ for (link = DF_REF_CHAIN (def_record); link; link = link->next)
+ {
+ if (!DF_REF_INSN_INFO (link->ref))
+ continue;
+
+ use_insn = DF_REF_INSN (link->ref);
+
+ /* Skip if define insn and use insn not in the same basic block. */
+ if (!dominated_by_p (CDI_DOMINATORS,
+ BLOCK_FOR_INSN (use_insn),
+ BLOCK_FOR_INSN (insn)))
+ return;
+
+ /* Skip if the low-part used register is from different high-part
+ instructions. */
+ use_record = DF_INSN_USES (use_insn);
+ if (DF_REF_CHAIN (use_record) && DF_REF_CHAIN (use_record)->next)
+ return;
+
+ /* Skip if use_insn not active insn. */
+ if (!active_insn_p (use_insn))
+ return;
+
+ if (!nds32_float_reg_load_store_p (use_insn)
+ || find_post_update_rtx (use_insn) != -1)
+ return;
+ }
+
+ group_id = GEN_INT (relax_group_id);
+ /* Insert .relax_* directive for insn. */
+ emit_insn_before (gen_relax_group (group_id), insn);
+
+ /* Scan the use insns and insert the directive. */
+ for (link = DF_REF_CHAIN (def_record); link; link = link->next)
+ {
+ if (!DF_REF_INSN_INFO (link->ref))
+ continue;
+
+ use_insn = DF_REF_INSN (link->ref);
+
+ /* Insert .relax_* directive. */
+ emit_insn_before (gen_relax_group (group_id), use_insn);
}
relax_group_id++;
@@ -271,8 +515,21 @@
/* Find sethi ra, symbol instruction. */
if (recog_memoized (insn) == CODE_FOR_sethi
&& nds32_symbolic_operand (XEXP (SET_SRC (PATTERN (insn)), 0),
- SImode))
+ SImode)
+ && !nds32_ict_const_p (XEXP (SET_SRC (PATTERN (insn)), 0)))
nds32_group_insns (insn);
+ else if (recog_memoized (insn) == CODE_FOR_tls_ie)
+ nds32_group_tls_insn (insn);
+ else if (TARGET_FPU_SINGLE
+ && recog_memoized (insn) == CODE_FOR_move_addr
+ && !nds32_ict_const_p (XEXP (SET_SRC (PATTERN (insn)), 0)))
+ {
+ nds32_group_float_insns (insn);
+ }
+ }
+ else if (CALL_P (insn) && recog_memoized (insn) == CODE_FOR_tls_desc)
+ {
+ nds32_group_tls_insn (insn);
}
}
diff -urN gcc-8.2.0.orig/gcc/config/nds32/nds32-utils.c gcc-8.2.0/gcc/config/nds32/nds32-utils.c
--- gcc-8.2.0.orig/gcc/config/nds32/nds32-utils.c 2018-04-08 10:31:52.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/nds32-utils.c 2019-01-25 15:38:32.833242671 +0100
@@ -142,6 +142,23 @@
return true;
}
+bool
+store_offset_reg_p (rtx_insn *insn)
+{
+ if (get_attr_type (insn) != TYPE_STORE)
+ return false;
+
+ rtx offset_rtx = extract_offset_rtx (insn);
+
+ if (offset_rtx == NULL_RTX)
+ return false;
+
+ if (REG_P (offset_rtx))
+ return true;
+
+ return false;
+}
+
/* Determine if INSN is a post update insn. */
bool
post_update_insn_p (rtx_insn *insn)
@@ -316,22 +333,114 @@
if (REG_P (XEXP (mem_rtx, 0)))
return XEXP (mem_rtx, 0);
+ /* (mem (lo_sum (reg) (symbol_ref)) */
+ if (GET_CODE (XEXP (mem_rtx, 0)) == LO_SUM)
+ return XEXP (XEXP (mem_rtx, 0), 0);
+
plus_rtx = XEXP (mem_rtx, 0);
if (GET_CODE (plus_rtx) == SYMBOL_REF
|| GET_CODE (plus_rtx) == CONST)
return NULL_RTX;
- gcc_assert (GET_CODE (plus_rtx) == PLUS
- || GET_CODE (plus_rtx) == POST_INC
- || GET_CODE (plus_rtx) == POST_DEC
- || GET_CODE (plus_rtx) == POST_MODIFY);
- gcc_assert (REG_P (XEXP (plus_rtx, 0)));
/* (mem (plus (reg) (const_int))) or
+ (mem (plus (mult (reg) (const_int 4)) (reg))) or
(mem (post_inc (reg))) or
(mem (post_dec (reg))) or
(mem (post_modify (reg) (plus (reg) (reg)))) */
- return XEXP (plus_rtx, 0);
+ gcc_assert (GET_CODE (plus_rtx) == PLUS
+ || GET_CODE (plus_rtx) == POST_INC
+ || GET_CODE (plus_rtx) == POST_DEC
+ || GET_CODE (plus_rtx) == POST_MODIFY);
+
+ if (REG_P (XEXP (plus_rtx, 0)))
+ return XEXP (plus_rtx, 0);
+
+ gcc_assert (REG_P (XEXP (plus_rtx, 1)));
+ return XEXP (plus_rtx, 1);
+}
+
+/* Extract the offset rtx from load/store insns. The function returns
+ NULL_RTX if offset is absent. */
+rtx
+extract_offset_rtx (rtx_insn *insn)
+{
+ rtx mem_rtx;
+ rtx plus_rtx;
+ rtx offset_rtx;
+
+ /* Find the MEM rtx. The multiple load/store insns doens't have
+ the offset field so we can return NULL_RTX here. */
+ switch (get_attr_type (insn))
+ {
+ case TYPE_LOAD_MULTIPLE:
+ case TYPE_STORE_MULTIPLE:
+ return NULL_RTX;
+
+ case TYPE_LOAD:
+ case TYPE_FLOAD:
+ case TYPE_STORE:
+ case TYPE_FSTORE:
+ mem_rtx = extract_mem_rtx (insn);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ gcc_assert (MEM_P (mem_rtx));
+
+ /* (mem (reg)) */
+ if (REG_P (XEXP (mem_rtx, 0)))
+ return NULL_RTX;
+
+ plus_rtx = XEXP (mem_rtx, 0);
+
+ switch (GET_CODE (plus_rtx))
+ {
+ case SYMBOL_REF:
+ case CONST:
+ case POST_INC:
+ case POST_DEC:
+ return NULL_RTX;
+
+ case PLUS:
+ /* (mem (plus (reg) (const_int))) or
+ (mem (plus (mult (reg) (const_int 4)) (reg))) */
+ if (REG_P (XEXP (plus_rtx, 0)))
+ offset_rtx = XEXP (plus_rtx, 1);
+ else
+ {
+ gcc_assert (REG_P (XEXP (plus_rtx, 1)));
+ offset_rtx = XEXP (plus_rtx, 0);
+ }
+
+ if (ARITHMETIC_P (offset_rtx))
+ {
+ gcc_assert (GET_CODE (offset_rtx) == MULT);
+ gcc_assert (REG_P (XEXP (offset_rtx, 0)));
+ offset_rtx = XEXP (offset_rtx, 0);
+ }
+ break;
+
+ case LO_SUM:
+ /* (mem (lo_sum (reg) (symbol_ref)) */
+ offset_rtx = XEXP (plus_rtx, 1);
+ break;
+
+ case POST_MODIFY:
+ /* (mem (post_modify (reg) (plus (reg) (reg / const_int)))) */
+ gcc_assert (REG_P (XEXP (plus_rtx, 0)));
+ plus_rtx = XEXP (plus_rtx, 1);
+ gcc_assert (GET_CODE (plus_rtx) == PLUS);
+ offset_rtx = XEXP (plus_rtx, 0);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return offset_rtx;
}
/* Extract the register of the shift operand from an ALU_SHIFT rtx. */
@@ -413,6 +522,7 @@
switch (get_attr_type (insn))
{
case TYPE_MAC:
+ case TYPE_DMAC:
if (REG_P (XEXP (exp, 0)))
return XEXP (exp, 1);
else
@@ -423,6 +533,19 @@
}
}
+/* Check if the DIV insn needs two write ports. */
+bool
+divmod_p (rtx_insn *insn)
+{
+ gcc_assert (get_attr_type (insn) == TYPE_DIV);
+
+ if (INSN_CODE (insn) == CODE_FOR_divmodsi4
+ || INSN_CODE (insn) == CODE_FOR_udivmodsi4)
+ return true;
+
+ return false;
+}
+
/* Extract the rtx representing the branch target to help recognize
data hazards. */
rtx
diff -urN gcc-8.2.0.orig/gcc/config/nds32/pipelines.md gcc-8.2.0/gcc/config/nds32/pipelines.md
--- gcc-8.2.0.orig/gcc/config/nds32/pipelines.md 2018-04-08 11:21:30.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/pipelines.md 2019-01-25 15:38:32.833242671 +0100
@@ -44,6 +44,24 @@
;; ------------------------------------------------------------------------
+;; Include N10 pipeline settings.
+;; ------------------------------------------------------------------------
+(include "nds32-n10.md")
+
+
+;; ------------------------------------------------------------------------
+;; Include Graywolf pipeline settings.
+;; ------------------------------------------------------------------------
+(include "nds32-graywolf.md")
+
+
+;; ------------------------------------------------------------------------
+;; Include N12/N13 pipeline settings.
+;; ------------------------------------------------------------------------
+(include "nds32-n13.md")
+
+
+;; ------------------------------------------------------------------------
;; Define simple pipeline settings.
;; ------------------------------------------------------------------------
diff -urN gcc-8.2.0.orig/gcc/config/nds32/predicates.md gcc-8.2.0/gcc/config/nds32/predicates.md
--- gcc-8.2.0.orig/gcc/config/nds32/predicates.md 2018-04-06 07:51:33.000000000 +0200
+++ gcc-8.2.0/gcc/config/nds32/predicates.md 2019-01-25 15:38:32.833242671 +0100
@@ -40,7 +40,15 @@
(match_code "mult,and,ior,xor"))
(define_predicate "nds32_symbolic_operand"
- (match_code "const,symbol_ref,label_ref"))
+ (and (match_code "const,symbol_ref,label_ref")
+ (match_test "!(TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (op))")))
+
+(define_predicate "nds32_nonunspec_symbolic_operand"
+ (and (match_code "const,symbol_ref,label_ref")
+ (match_test "!flag_pic && nds32_const_unspec_p (op)
+ && !(TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (op))")))
(define_predicate "nds32_reg_constant_operand"
(ior (match_operand 0 "register_operand")
@@ -56,14 +64,51 @@
(and (match_operand 0 "const_int_operand")
(match_test "satisfies_constraint_Is11 (op)"))))
+(define_predicate "nds32_imm_0_1_operand"
+ (and (match_operand 0 "const_int_operand")
+ (ior (match_test "satisfies_constraint_Iv00 (op)")
+ (match_test "satisfies_constraint_Iv01 (op)"))))
+
+(define_predicate "nds32_imm_1_2_operand"
+ (and (match_operand 0 "const_int_operand")
+ (ior (match_test "satisfies_constraint_Iv01 (op)")
+ (match_test "satisfies_constraint_Iv02 (op)"))))
+
+(define_predicate "nds32_imm_1_2_4_8_operand"
+ (and (match_operand 0 "const_int_operand")
+ (ior (ior (match_test "satisfies_constraint_Iv01 (op)")
+ (match_test "satisfies_constraint_Iv02 (op)"))
+ (ior (match_test "satisfies_constraint_Iv04 (op)")
+ (match_test "satisfies_constraint_Iv08 (op)")))))
+
+(define_predicate "nds32_imm2u_operand"
+ (and (match_operand 0 "const_int_operand")
+ (match_test "satisfies_constraint_Iu02 (op)")))
+
+(define_predicate "nds32_imm4u_operand"
+ (and (match_operand 0 "const_int_operand")
+ (match_test "satisfies_constraint_Iu04 (op)")))
+
(define_predicate "nds32_imm5u_operand"
(and (match_operand 0 "const_int_operand")
(match_test "satisfies_constraint_Iu05 (op)")))
+(define_predicate "nds32_imm6u_operand"
+ (and (match_operand 0 "const_int_operand")
+ (match_test "satisfies_constraint_Iu06 (op)")))
+
+(define_predicate "nds32_rimm4u_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "nds32_imm4u_operand")))
+
(define_predicate "nds32_rimm5u_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "nds32_imm5u_operand")))
+(define_predicate "nds32_rimm6u_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "nds32_imm6u_operand")))
+
(define_predicate "nds32_move_operand"
(and (match_operand 0 "general_operand")
(not (match_code "high,const,symbol_ref,label_ref")))
@@ -78,6 +123,20 @@
return true;
})
+(define_predicate "nds32_vmove_operand"
+ (and (match_operand 0 "general_operand")
+ (not (match_code "high,const,symbol_ref,label_ref")))
+{
+ /* If the constant op does NOT satisfy Is20 nor Ihig,
+ we can not perform move behavior by a single instruction. */
+ if (GET_CODE (op) == CONST_VECTOR
+ && !satisfies_constraint_CVs2 (op)
+ && !satisfies_constraint_CVhi (op))
+ return false;
+
+ return true;
+})
+
(define_predicate "nds32_and_operand"
(match_operand 0 "nds32_reg_constant_operand")
{
@@ -127,6 +186,15 @@
(ior (match_operand 0 "nds32_symbolic_operand")
(match_operand 0 "nds32_general_register_operand")))
+(define_predicate "nds32_insv_operand"
+ (match_code "const_int")
+{
+ return INTVAL (op) == 0
+ || INTVAL (op) == 8
+ || INTVAL (op) == 16
+ || INTVAL (op) == 24;
+})
+
(define_predicate "nds32_lmw_smw_base_operand"
(and (match_code "mem")
(match_test "nds32_valid_smw_lwm_base_p (op)")))
diff -urN gcc-8.2.0.orig/gcc/config/nds32/t-elf gcc-8.2.0/gcc/config/nds32/t-elf
--- gcc-8.2.0.orig/gcc/config/nds32/t-elf 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/t-elf 2019-01-25 15:38:32.833242671 +0100
@@ -0,0 +1,42 @@
+# The multilib settings of Andes NDS32 cpu for GNU compiler
+# Copyright (C) 2012-2018 Free Software Foundation, Inc.
+# Contributed by Andes Technology Corporation.
+#
+# 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
+# <http://www.gnu.org/licenses/>.
+
+# We also define a macro MULTILIB_DEFAULTS in nds32.h that tells the
+# driver program which options are defaults for this target and thus
+# do not need to be handled specially.
+MULTILIB_OPTIONS += mcmodel=small/mcmodel=medium/mcmodel=large mvh
+
+ifneq ($(filter graywolf,$(TM_MULTILIB_CONFIG)),)
+MULTILIB_OPTIONS += mcpu=graywolf
+endif
+
+ifneq ($(filter dsp,$(TM_MULTILIB_CONFIG)),)
+MULTILIB_OPTIONS += mext-dsp
+endif
+
+ifneq ($(filter zol,$(TM_MULTILIB_CONFIG)),)
+MULTILIB_OPTIONS += mext-zol
+endif
+
+ifneq ($(filter v3m+,$(TM_MULTILIB_CONFIG)),)
+MULTILIB_OPTIONS += march=v3m+
+endif
+
+# ------------------------------------------------------------------------
diff -urN gcc-8.2.0.orig/gcc/config/nds32/t-linux gcc-8.2.0/gcc/config/nds32/t-linux
--- gcc-8.2.0.orig/gcc/config/nds32/t-linux 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/config/nds32/t-linux 2019-01-25 15:38:32.833242671 +0100
@@ -0,0 +1,26 @@
+# The multilib settings of Andes NDS32 cpu for GNU compiler
+# Copyright (C) 2012-2018 Free Software Foundation, Inc.
+# Contributed by Andes Technology Corporation.
+#
+# 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
+# <http://www.gnu.org/licenses/>.
+
+# We also define a macro MULTILIB_DEFAULTS in nds32.h that tells the
+# driver program which options are defaults for this target and thus
+# do not need to be handled specially.
+MULTILIB_OPTIONS +=
+
+# ------------------------------------------------------------------------
diff -urN gcc-8.2.0.orig/gcc/config.gcc gcc-8.2.0/gcc/config.gcc
--- gcc-8.2.0.orig/gcc/config.gcc 2018-06-25 21:34:01.000000000 +0200
+++ gcc-8.2.0/gcc/config.gcc 2019-01-25 15:38:32.821242637 +0100
@@ -445,7 +445,17 @@
;;
nds32*)
cpu_type=nds32
- extra_headers="nds32_intrinsic.h"
+ extra_headers="nds32_intrinsic.h nds32_isr.h nds32_init.inc"
+ case ${target} in
+ nds32*-*-linux*)
+ extra_options="${extra_options} nds32/nds32-linux.opt"
+ ;;
+ nds32*-*-elf*)
+ extra_options="${extra_options} nds32/nds32-elf.opt"
+ ;;
+ *)
+ ;;
+ esac
extra_objs="nds32-cost.o nds32-intrinsic.o nds32-isr.o nds32-md-auxiliary.o nds32-pipelines-auxiliary.o nds32-predicates.o nds32-memory-manipulation.o nds32-fp-as-gp.o nds32-relax-opt.o nds32-utils.o"
;;
nios2-*-*)
@@ -2335,17 +2345,36 @@
tmake_file="${tmake_file} msp430/t-msp430"
extra_gcc_objs="driver-msp430.o"
;;
-nds32le-*-*)
+nds32*-*-*)
target_cpu_default="0"
tm_defines="${tm_defines}"
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} nds32/nds32_intrinsic.h"
- tmake_file="nds32/t-nds32 nds32/t-mlibs"
- ;;
-nds32be-*-*)
- target_cpu_default="0|MASK_BIG_ENDIAN"
- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} nds32/nds32_intrinsic.h"
- tmake_file="nds32/t-nds32 nds32/t-mlibs"
+ case ${target} in
+ nds32le*-*-*)
+ ;;
+ nds32be-*-*)
+ target_cpu_default="${target_cpu_default}|MASK_BIG_ENDIAN"
+ tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+ ;;
+ esac
+ case ${target} in
+ nds32*-*-elf*)
+ tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} nds32/elf.h nds32/nds32_intrinsic.h"
+ tmake_file="nds32/t-nds32 nds32/t-elf"
+ ;;
+ nds32*-*-linux*)
+ tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h glibc-stdint.h nds32/linux.h nds32/nds32_intrinsic.h"
+ tmake_file="${tmake_file} nds32/t-nds32 nds32/t-linux"
+ ;;
+ esac
+
+ # Handle --enable-default-relax setting.
+ if test x${enable_default_relax} = xyes; then
+ tm_defines="${tm_defines} TARGET_DEFAULT_RELAX=1"
+ fi
+ # Handle --with-ext-dsp
+ if test x${with_ext_dsp} = xyes; then
+ tm_defines="${tm_defines} TARGET_DEFAULT_EXT_DSP=1"
+ fi
;;
nios2-*-*)
tm_file="elfos.h ${tm_file}"
@@ -4318,11 +4347,11 @@
"")
with_cpu=n9
;;
- n6 | n7 | n8 | e8 | s8 | n9)
+ n6 | n7 |n8 | e8 | s8 | n9 | n10 | d10 | n12 | n13 | n15)
# OK
;;
*)
- echo "Cannot accept --with-cpu=$with_cpu, available values are: n6 n7 n8 e8 s8 n9" 1>&2
+ echo "Cannot accept --with-cpu=$with_cpu, available values are: n6 n7 n8 e8 s8 n9 n10 d10 n12 n13 n15" 1>&2
exit 1
;;
esac
@@ -4332,15 +4361,30 @@
"")
# the default library is newlib
with_nds32_lib=newlib
+ tm_defines="${tm_defines} TARGET_DEFAULT_CTOR_DTOR=1"
;;
newlib)
# OK
+ tm_defines="${tm_defines} TARGET_DEFAULT_CTOR_DTOR=1"
;;
mculib)
# OK
+ # for the arch=v3f or arch=v3s under mculib toolchain,
+ # we would like to set -fno-math-errno as default
+ case "${with_arch}" in
+ v3f | v3s)
+ tm_defines="${tm_defines} TARGET_DEFAULT_NO_MATH_ERRNO=1"
+ ;;
+ esac
+ ;;
+ glibc)
+ # OK
+ tm_defines="${tm_defines}"
+ ;;
+ uclibc)
;;
*)
- echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: newlib mculib" 1>&2
+ echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: newlib mculib glibc uclibc" 1>&2
exit 1
;;
esac
diff -urN gcc-8.2.0.orig/gcc/configure gcc-8.2.0/gcc/configure
--- gcc-8.2.0.orig/gcc/configure 2018-04-18 11:46:58.000000000 +0200
+++ gcc-8.2.0/gcc/configure 2019-01-25 15:38:32.837242683 +0100
@@ -27784,7 +27784,7 @@
# version to the per-target configury.
case "$cpu_type" in
aarch64 | alpha | arc | arm | avr | bfin | cris | i386 | m32c | m68k \
- | microblaze | mips | nios2 | pa | riscv | rs6000 | score | sparc | spu \
+ | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc | spu \
| tilegx | tilepro | visium | xstormy16 | xtensa)
insn="nop"
;;
diff -urN gcc-8.2.0.orig/gcc/configure.ac gcc-8.2.0/gcc/configure.ac
--- gcc-8.2.0.orig/gcc/configure.ac 2018-04-18 11:46:58.000000000 +0200
+++ gcc-8.2.0/gcc/configure.ac 2019-01-25 15:38:32.837242683 +0100
@@ -4910,7 +4910,7 @@
# version to the per-target configury.
case "$cpu_type" in
aarch64 | alpha | arc | arm | avr | bfin | cris | i386 | m32c | m68k \
- | microblaze | mips | nios2 | pa | riscv | rs6000 | score | sparc | spu \
+ | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc | spu \
| tilegx | tilepro | visium | xstormy16 | xtensa)
insn="nop"
;;
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.c-torture/execute/20010122-1.c gcc-8.2.0/gcc/testsuite/gcc.c-torture/execute/20010122-1.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.c-torture/execute/20010122-1.c 2015-12-10 20:20:14.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.c-torture/execute/20010122-1.c 2019-01-25 15:38:32.837242683 +0100
@@ -1,4 +1,5 @@
/* { dg-skip-if "requires frame pointers" { *-*-* } "-fomit-frame-pointer" "" } */
+/* { dg-additional-options "-malways-save-lp" { target nds32*-*-* } } */
/* { dg-require-effective-target return_address } */
extern void exit (int);
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.dg/lower-subreg-1.c gcc-8.2.0/gcc/testsuite/gcc.dg/lower-subreg-1.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.dg/lower-subreg-1.c 2017-06-17 17:32:28.000000000 +0200
+++ gcc-8.2.0/gcc/testsuite/gcc.dg/lower-subreg-1.c 2019-01-25 15:38:32.837242683 +0100
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */
+/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* nds32*-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */
/* { dg-options "-O -fdump-rtl-subreg1" } */
/* { dg-additional-options "-mno-stv" { target ia32 } } */
/* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } } */
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.dg/stack-usage-1.c gcc-8.2.0/gcc/testsuite/gcc.dg/stack-usage-1.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.dg/stack-usage-1.c 2017-06-17 17:32:28.000000000 +0200
+++ gcc-8.2.0/gcc/testsuite/gcc.dg/stack-usage-1.c 2019-01-25 15:38:32.837242683 +0100
@@ -2,6 +2,7 @@
/* { dg-options "-fstack-usage" } */
/* nvptx doesn't have a reg allocator, and hence no stack usage data. */
/* { dg-skip-if "" { nvptx-*-* } } */
+/* { dg-options "-fstack-usage -fno-omit-frame-pointer" { target { nds32*-*-* } } } */
/* This is aimed at testing basic support for -fstack-usage in the back-ends.
See the SPARC back-end for example (grep flag_stack_usage_info in sparc.c).
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-isb.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-isb.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-isb.c 2013-12-03 11:58:05.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-isb.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,11 +0,0 @@
-/* Verify that we generate isb instruction with builtin function. */
-
-/* { dg-do compile } */
-/* { dg-options "-O0" } */
-/* { dg-final { scan-assembler "\\tisb" } } */
-
-void
-test (void)
-{
- __builtin_nds32_isb ();
-}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-isync.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-isync.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-isync.c 2013-12-03 11:58:05.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-isync.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,12 +0,0 @@
-/* Verify that we generate isync instruction with builtin function. */
-
-/* { dg-do compile } */
-/* { dg-options "-O0" } */
-/* { dg-final { scan-assembler "\\tisync" } } */
-
-void
-test (void)
-{
- int *addr = (int *) 0x53000000;
- __builtin_nds32_isync (addr);
-}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-mfsr-mtsr.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-mfsr-mtsr.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-mfsr-mtsr.c 2013-12-03 11:58:05.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-mfsr-mtsr.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,17 +0,0 @@
-/* Verify that we generate mfsr/mtsr instruction with builtin function. */
-
-/* { dg-do compile } */
-/* { dg-options "-O0" } */
-/* { dg-final { scan-assembler "\\tmfsr" } } */
-/* { dg-final { scan-assembler "\\tmtsr" } } */
-
-#include <nds32_intrinsic.h>
-
-void
-test (void)
-{
- int ipsw_value;
-
- ipsw_value = __builtin_nds32_mfsr (__NDS32_REG_IPSW__);
- __builtin_nds32_mtsr (ipsw_value, __NDS32_REG_IPSW__);
-}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-mfusr-mtusr.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-mfusr-mtusr.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-mfusr-mtusr.c 2013-12-03 11:58:05.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-mfusr-mtusr.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,17 +0,0 @@
-/* Verify that we generate mfusr/mtusr instruction with builtin function. */
-
-/* { dg-do compile } */
-/* { dg-options "-O0" } */
-/* { dg-final { scan-assembler "\\tmfusr" } } */
-/* { dg-final { scan-assembler "\\tmtusr" } } */
-
-#include <nds32_intrinsic.h>
-
-void
-test (void)
-{
- int itype_value;
-
- itype_value = __builtin_nds32_mfusr (__NDS32_REG_ITYPE__);
- __builtin_nds32_mtusr (itype_value, __NDS32_REG_ITYPE__);
-}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-setgie-dis.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-setgie-dis.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-setgie-dis.c 2013-12-03 11:58:05.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-setgie-dis.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,11 +0,0 @@
-/* Verify that we generate setgie.d instruction with builtin function. */
-
-/* { dg-do compile } */
-/* { dg-options "-O0" } */
-/* { dg-final { scan-assembler "\\tsetgie.d" } } */
-
-void
-test (void)
-{
- __builtin_nds32_setgie_dis ();
-}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-setgie-en.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-setgie-en.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-setgie-en.c 2013-12-03 11:58:05.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-setgie-en.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,11 +0,0 @@
-/* Verify that we generate setgie.e instruction with builtin function. */
-
-/* { dg-do compile } */
-/* { dg-options "-O0" } */
-/* { dg-final { scan-assembler "\\tsetgie.e" } } */
-
-void
-test (void)
-{
- __builtin_nds32_setgie_en ();
-}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-setgie_mtsr_mfsr.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-setgie_mtsr_mfsr.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/builtin-setgie_mtsr_mfsr.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/builtin-setgie_mtsr_mfsr.c 2019-01-25 15:38:32.837242683 +0100
@@ -0,0 +1,36 @@
+/* This is a test program for checking gie with
+ mtsr/mfsr instruction. */
+
+/* { dg-do run } */
+/* { dg-options "-O0" } */
+
+#include <nds32_intrinsic.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+ unsigned int psw;
+ unsigned int gie;
+ unsigned int pfm_ctl;
+
+ __nds32__setgie_en ();
+ __nds32__dsb(); /* This is needed for waiting pipeline. */
+ psw = __nds32__mfsr (NDS32_SR_PSW);
+
+ gie = psw & 0x00000001;
+
+ if (gie != 1)
+ abort ();
+
+ psw = psw & 0xFFFFFFFE;
+ __nds32__mtsr (psw,NDS32_SR_PSW);
+ __nds32__dsb(); /* This is needed for waiting pipeline. */
+ psw = __nds32__mfsr (NDS32_SR_PSW);
+ gie = psw & 0x00000001;
+
+ if (gie != 0)
+ abort ();
+ else
+ exit (0);
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending.c 2019-01-25 15:38:32.837242683 +0100
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <nds32_intrinsic.h>
+
+void
+main (void)
+{
+ __nds32__clr_pending_swint ();
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending-hw.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending-hw.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending-hw.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending-hw.c 2019-01-25 15:38:32.837242683 +0100
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <nds32_intrinsic.h>
+
+void
+main (void)
+{
+ __nds32__clr_pending_hwint (NDS32_INT_H0);
+ __nds32__clr_pending_hwint (NDS32_INT_H1);
+ __nds32__clr_pending_hwint (NDS32_INT_H2);
+
+ __nds32__clr_pending_hwint (NDS32_INT_H15);
+ __nds32__clr_pending_hwint (NDS32_INT_H16);
+ __nds32__clr_pending_hwint (NDS32_INT_H31);
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-disable.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-disable.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-disable.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-disable.c 2019-01-25 15:38:32.837242683 +0100
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <nds32_intrinsic.h>
+
+void
+main (void)
+{
+ __nds32__disable_int (NDS32_INT_H15);
+ __nds32__disable_int (NDS32_INT_H16);
+ __nds32__disable_int (NDS32_INT_H31);
+ __nds32__disable_int (NDS32_INT_SWI);
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-enable.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-enable.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-enable.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-enable.c 2019-01-25 15:38:32.837242683 +0100
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <nds32_intrinsic.h>
+
+void
+main (void)
+{
+ __nds32__enable_int (NDS32_INT_H15);
+ __nds32__enable_int (NDS32_INT_H16);
+ __nds32__enable_int (NDS32_INT_H31);
+ __nds32__enable_int (NDS32_INT_SWI);
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-get-pending-int.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-get-pending-int.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-get-pending-int.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-get-pending-int.c 2019-01-25 15:38:32.837242683 +0100
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <nds32_intrinsic.h>
+
+int
+main (void)
+{
+ int a = __nds32__get_pending_int (NDS32_INT_H15);
+ int b = __nds32__get_pending_int (NDS32_INT_SWI);
+ int c = __nds32__get_pending_int (NDS32_INT_H16);
+
+ return a + b + c;
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-get-trig.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-get-trig.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-get-trig.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-get-trig.c 2019-01-25 15:38:32.837242683 +0100
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <nds32_intrinsic.h>
+
+int
+main (void)
+{
+ int a = __nds32__get_trig_type (NDS32_INT_H0);
+ int b = __nds32__get_trig_type (NDS32_INT_H15);
+ int c = __nds32__get_trig_type (NDS32_INT_H16);
+ int d = __nds32__get_trig_type (NDS32_INT_H31);
+ return a + b + c + d;
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-isb.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-isb.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-isb.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-isb.c 2019-01-25 15:38:32.837242683 +0100
@@ -0,0 +1,11 @@
+/* Verify that we generate isb instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tisb" } } */
+
+void
+test (void)
+{
+ __builtin_nds32_isb ();
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-isync.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-isync.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-isync.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-isync.c 2019-01-25 15:38:32.841242694 +0100
@@ -0,0 +1,12 @@
+/* Verify that we generate isync instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tisync" } } */
+
+void
+test (void)
+{
+ int *addr = (int *) 0x53000000;
+ __builtin_nds32_isync (addr);
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-mfsr-mtsr.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-mfsr-mtsr.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-mfsr-mtsr.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-mfsr-mtsr.c 2019-01-25 15:38:32.841242694 +0100
@@ -0,0 +1,17 @@
+/* Verify that we generate mfsr/mtsr instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tmfsr" } } */
+/* { dg-final { scan-assembler "\\tmtsr" } } */
+
+#include <nds32_intrinsic.h>
+
+void
+test (void)
+{
+ int ipsw_value;
+
+ ipsw_value = __builtin_nds32_mfsr (__NDS32_REG_IPSW__);
+ __builtin_nds32_mtsr (ipsw_value, __NDS32_REG_IPSW__);
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-mfusr-mtusr.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-mfusr-mtusr.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-mfusr-mtusr.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-mfusr-mtusr.c 2019-01-25 15:38:32.841242694 +0100
@@ -0,0 +1,17 @@
+/* Verify that we generate mfusr/mtusr instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tmfusr" } } */
+/* { dg-final { scan-assembler "\\tmtusr" } } */
+
+#include <nds32_intrinsic.h>
+
+void
+test (void)
+{
+ int itype_value;
+
+ itype_value = __builtin_nds32_mfusr (__NDS32_REG_ITYPE__);
+ __builtin_nds32_mtusr (itype_value, __NDS32_REG_ITYPE__);
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-dis.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-dis.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-dis.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-dis.c 2019-01-25 15:38:32.841242694 +0100
@@ -0,0 +1,13 @@
+/* Verify that we generate setgie.d instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tsetgie.d" } } */
+
+#include <nds32_intrinsic.h>
+
+void
+test (void)
+{
+ __nds32__setgie_dis ();
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-en.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-en.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-en.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-en.c 2019-01-25 15:38:32.841242694 +0100
@@ -0,0 +1,13 @@
+/* Verify that we generate setgie.e instruction with builtin function. */
+
+/* { dg-do compile */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tsetgie.e" } } */
+
+#include <nds32_intrinsic.h>
+
+void
+test (void)
+{
+ __nds32__setgie_en ();
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-set-pending.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-set-pending.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-set-pending.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-set-pending.c 2019-01-25 15:38:32.841242694 +0100
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <nds32_intrinsic.h>
+
+int
+main (void)
+{
+ __nds32__set_pending_swint ();
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-edge.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-edge.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-edge.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-edge.c 2019-01-25 15:38:32.841242694 +0100
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <nds32_intrinsic.h>
+
+void
+main (void)
+{
+ __nds32__set_trig_type_edge (NDS32_INT_H0);
+ __nds32__set_trig_type_edge (NDS32_INT_H15);
+ __nds32__set_trig_type_edge (NDS32_INT_H16);
+ __nds32__set_trig_type_edge (NDS32_INT_H31);
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-level.c gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-level.c
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-level.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-level.c 2019-01-25 15:38:32.841242694 +0100
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <nds32_intrinsic.h>
+
+void
+main (void)
+{
+ __nds32__set_trig_type_level (NDS32_INT_H0);
+ __nds32__set_trig_type_level (NDS32_INT_H15);
+ __nds32__set_trig_type_level (NDS32_INT_H16);
+ __nds32__set_trig_type_level (NDS32_INT_H31);
+}
diff -urN gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/nds32.exp gcc-8.2.0/gcc/testsuite/gcc.target/nds32/nds32.exp
--- gcc-8.2.0.orig/gcc/testsuite/gcc.target/nds32/nds32.exp 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/gcc/testsuite/gcc.target/nds32/nds32.exp 2019-01-25 15:38:32.841242694 +0100
@@ -38,8 +38,10 @@
dg-init
# Main loop.
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/compile/*.\[cS\]]] \
"" $DEFAULT_CFLAGS
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+ "" ""
# All done.
dg-finish
diff -urN gcc-8.2.0.orig/gcc/testsuite/lib/target-supports.exp gcc-8.2.0/gcc/testsuite/lib/target-supports.exp
--- gcc-8.2.0.orig/gcc/testsuite/lib/target-supports.exp 2018-06-29 00:23:51.000000000 +0200
+++ gcc-8.2.0/gcc/testsuite/lib/target-supports.exp 2019-01-25 15:38:32.841242694 +0100
@@ -8783,6 +8783,7 @@
|| [istarget avr*-*-*]
|| [istarget crisv32-*-*] || [istarget cris-*-*]
|| [istarget mmix-*-*]
+ || [istarget nds32*-*-*]
|| [istarget s390*-*-*]
|| [istarget powerpc*-*-*]
|| [istarget nios2*-*-*]
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/initfini.c gcc-8.2.0/libgcc/config/nds32/initfini.c
--- gcc-8.2.0.orig/libgcc/config/nds32/initfini.c 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/initfini.c 2019-01-25 15:38:32.841242694 +0100
@@ -25,6 +25,10 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
+#include <stddef.h>
+/* Need header file for `struct object' type. */
+#include "../libgcc/unwind-dw2-fde.h"
+
/* Declare a pointer to void function type. */
typedef void (*func_ptr) (void);
@@ -42,11 +46,59 @@
refer to only the __CTOR_END__ symbol in crtfini.o and the __DTOR_LIST__
symbol in crtinit.o, where they are defined. */
-static func_ptr __CTOR_LIST__[1] __attribute__ ((section (".ctors")))
- = { (func_ptr) (-1) };
+static func_ptr __CTOR_LIST__[1] __attribute__ ((section (".ctors"), used))
+ = { (func_ptr) 0 };
+
+static func_ptr __DTOR_LIST__[1] __attribute__ ((section (".dtors"), used))
+ = { (func_ptr) 0 };
+
+
+#ifdef SUPPORT_UNWINDING_DWARF2
+/* Preparation of exception handling with dwar2 mechanism registration. */
+
+asm ("\n\
+ .section .eh_frame,\"aw\",@progbits\n\
+ .global __EH_FRAME_BEGIN__\n\
+ .type __EH_FRAME_BEGIN__, @object\n\
+ .align 2\n\
+__EH_FRAME_BEGIN__:\n\
+ ! Beginning location of eh_frame section\n\
+ .previous\n\
+");
+
+extern func_ptr __EH_FRAME_BEGIN__[];
+
-static func_ptr __DTOR_LIST__[1] __attribute__ ((section (".dtors")))
- = { (func_ptr) (-1) };
+/* Note that the following two functions are going to be chained into
+ constructor and destructor list, repectively. So these two declarations
+ must be placed after __CTOR_LIST__ and __DTOR_LIST. */
+extern void __nds32_register_eh(void) __attribute__((constructor, used));
+extern void __nds32_deregister_eh(void) __attribute__((destructor, used));
+
+/* Register the exception handling table as the first constructor. */
+void
+__nds32_register_eh (void)
+{
+ static struct object object;
+ if (__register_frame_info)
+ __register_frame_info (__EH_FRAME_BEGIN__, &object);
+}
+
+/* Unregister the exception handling table as a deconstructor. */
+void
+__nds32_deregister_eh (void)
+{
+ static int completed = 0;
+
+ if (completed)
+ return;
+
+ if (__deregister_frame_info)
+ __deregister_frame_info (__EH_FRAME_BEGIN__);
+
+ completed = 1;
+}
+#endif
/* Run all the global destructors on exit from the program. */
@@ -63,7 +115,7 @@
same particular root executable or shared library file. */
static void __do_global_dtors (void)
-asm ("__do_global_dtors") __attribute__ ((section (".text")));
+asm ("__do_global_dtors") __attribute__ ((section (".text"), used));
static void
__do_global_dtors (void)
@@ -116,23 +168,37 @@
last, these words naturally end up at the very ends of the two lists
contained in these two sections. */
-static func_ptr __CTOR_END__[1] __attribute__ ((section (".ctors")))
+static func_ptr __CTOR_END__[1] __attribute__ ((section (".ctors"), used))
= { (func_ptr) 0 };
-static func_ptr __DTOR_END__[1] __attribute__ ((section (".dtors")))
+static func_ptr __DTOR_END__[1] __attribute__ ((section (".dtors"), used))
= { (func_ptr) 0 };
+#ifdef SUPPORT_UNWINDING_DWARF2
+/* ZERO terminator in .eh_frame section. */
+asm ("\n\
+ .section .eh_frame,\"aw\",@progbits\n\
+ .global __EH_FRAME_END__\n\
+ .type __EH_FRAME_END__, @object\n\
+ .align 2\n\
+__EH_FRAME_END__:\n\
+ ! End location of eh_frame section with ZERO terminator\n\
+ .word 0\n\
+ .previous\n\
+");
+#endif
+
/* Run all global constructors for the program.
Note that they are run in reverse order. */
static void __do_global_ctors (void)
-asm ("__do_global_ctors") __attribute__ ((section (".text")));
+asm ("__do_global_ctors") __attribute__ ((section (".text"), used));
static void
__do_global_ctors (void)
{
func_ptr *p;
- for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
+ for (p = __CTOR_END__ - 1; *p; p--)
(*p) ();
}
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/adj_intr_lvl.inc gcc-8.2.0/libgcc/config/nds32/isr-library/adj_intr_lvl.inc
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/adj_intr_lvl.inc 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/adj_intr_lvl.inc 2019-01-25 15:38:32.841242694 +0100
@@ -26,13 +26,26 @@
.macro ADJ_INTR_LVL
#if defined(NDS32_NESTED) /* Nested handler. */
mfsr $r3, $PSW
+ /* By substracting 1 from $PSW, we can lower PSW.INTL
+ and enable GIE simultaneously. */
addi $r3, $r3, #-0x1
+ #if __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__
+ ori $r3, $r3, 0x2000 /* Set PSW.AEN(b'13) */
+ #endif
mtsr $r3, $PSW
#elif defined(NDS32_NESTED_READY) /* Nested ready handler. */
/* Save ipc and ipsw and lower INT level. */
mfsr $r3, $PSW
addi $r3, $r3, #-0x2
+ #if __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__
+ ori $r3, $r3, 0x2000 /* Set PSW.AEN(b'13) */
+ #endif
mtsr $r3, $PSW
#else /* Not nested handler. */
+ #if __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__
+ mfsr $r3, $PSW
+ ori $r3, $r3, 0x2000 /* Set PSW.AEN(b'13) */
+ mtsr $r3, $PSW
+ #endif
#endif
.endm
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/excp_isr.S gcc-8.2.0/libgcc/config/nds32/isr-library/excp_isr.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/excp_isr.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/excp_isr.S 2019-01-25 15:38:32.841242694 +0100
@@ -23,6 +23,7 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
+#include "save_usr_regs.inc"
#include "save_mac_regs.inc"
#include "save_fpu_regs.inc"
#include "save_fpu_regs_00.inc"
@@ -32,35 +33,33 @@
#include "save_all.inc"
#include "save_partial.inc"
#include "adj_intr_lvl.inc"
-#include "restore_mac_regs.inc"
#include "restore_fpu_regs_00.inc"
#include "restore_fpu_regs_01.inc"
#include "restore_fpu_regs_02.inc"
#include "restore_fpu_regs_03.inc"
#include "restore_fpu_regs.inc"
+#include "restore_mac_regs.inc"
+#include "restore_usr_regs.inc"
#include "restore_all.inc"
#include "restore_partial.inc"
+
.section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */
.align 1
-/*
- First Level Handlers
- 1. First Level Handlers are invokded in vector section via jump instruction
- with specific names for different configurations.
- 2. Naming Format: _nds32_e_SR_NT for exception handlers.
- _nds32_i_SR_NT for interrupt handlers.
- 2.1 All upper case letters are replaced with specific lower case letters encodings.
- 2.2 SR: Saved Registers
- sa: Save All regs (context)
- ps: Partial Save (all caller-saved regs)
- 2.3 NT: Nested Type
- ns: nested
- nn: not nested
- nr: nested ready
-*/
-
-/*
- This is original 16-byte vector size version.
-*/
+
+/* First Level Handlers
+ 1. First Level Handlers are invokded in vector section via jump instruction
+ with specific names for different configurations.
+ 2. Naming Format: _nds32_e_SR_NT for exception handlers.
+ _nds32_i_SR_NT for interrupt handlers.
+ 2.1 All upper case letters are replaced with specific lower case letters encodings.
+ 2.2 SR -- Saved Registers
+ sa: Save All regs (context)
+ ps: Partial Save (all caller-saved regs)
+ 2.3 NT -- Nested Type
+ ns: nested
+ nn: not nested
+ nr: nested ready */
+
#ifdef NDS32_SAVE_ALL_REGS
#if defined(NDS32_NESTED)
.globl _nds32_e_sa_ns
@@ -91,21 +90,26 @@
#endif /* endif for Nest Type */
#endif /* not NDS32_SAVE_ALL_REGS */
-/*
- This is 16-byte vector size version.
- The vector id was restored into $r0 in vector by compiler.
-*/
+
+/* For 4-byte vector size version, the vector id is
+ extracted from $ITYPE and is set into $r0 by library.
+ For 16-byte vector size version, the vector id
+ is set into $r0 in vector section by compiler. */
+
+/* Save used registers. */
#ifdef NDS32_SAVE_ALL_REGS
SAVE_ALL
#else
SAVE_PARTIAL
#endif
+
/* Prepare to call 2nd level handler. */
la $r2, _nds32_jmptbl_00
lw $r2, [$r2 + $r0 << #2]
ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */
jral $r2
- /* Restore used registers. */
+
+/* Restore used registers. */
#ifdef NDS32_SAVE_ALL_REGS
RESTORE_ALL
#else
@@ -113,6 +117,7 @@
#endif
iret
+
#ifdef NDS32_SAVE_ALL_REGS
#if defined(NDS32_NESTED)
.size _nds32_e_sa_ns, .-_nds32_e_sa_ns
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/intr_isr.S gcc-8.2.0/libgcc/config/nds32/isr-library/intr_isr.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/intr_isr.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/intr_isr.S 2019-01-25 15:38:32.841242694 +0100
@@ -23,6 +23,7 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
+#include "save_usr_regs.inc"
#include "save_mac_regs.inc"
#include "save_fpu_regs.inc"
#include "save_fpu_regs_00.inc"
@@ -32,35 +33,33 @@
#include "save_all.inc"
#include "save_partial.inc"
#include "adj_intr_lvl.inc"
-#include "restore_mac_regs.inc"
#include "restore_fpu_regs_00.inc"
#include "restore_fpu_regs_01.inc"
#include "restore_fpu_regs_02.inc"
#include "restore_fpu_regs_03.inc"
#include "restore_fpu_regs.inc"
+#include "restore_mac_regs.inc"
+#include "restore_usr_regs.inc"
#include "restore_all.inc"
#include "restore_partial.inc"
+
.section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */
.align 1
-/*
- First Level Handlers
- 1. First Level Handlers are invokded in vector section via jump instruction
- with specific names for different configurations.
- 2. Naming Format: _nds32_e_SR_NT for exception handlers.
- _nds32_i_SR_NT for interrupt handlers.
- 2.1 All upper case letters are replaced with specific lower case letters encodings.
- 2.2 SR: Saved Registers
- sa: Save All regs (context)
- ps: Partial Save (all caller-saved regs)
- 2.3 NT: Nested Type
- ns: nested
- nn: not nested
- nr: nested ready
-*/
-
-/*
- This is original 16-byte vector size version.
-*/
+
+/* First Level Handlers
+ 1. First Level Handlers are invokded in vector section via jump instruction
+ with specific names for different configurations.
+ 2. Naming Format: _nds32_e_SR_NT for exception handlers.
+ _nds32_i_SR_NT for interrupt handlers.
+ 2.1 All upper case letters are replaced with specific lower case letters encodings.
+ 2.2 SR -- Saved Registers
+ sa: Save All regs (context)
+ ps: Partial Save (all caller-saved regs)
+ 2.3 NT -- Nested Type
+ ns: nested
+ nn: not nested
+ nr: nested ready */
+
#ifdef NDS32_SAVE_ALL_REGS
#if defined(NDS32_NESTED)
.globl _nds32_i_sa_ns
@@ -91,21 +90,36 @@
#endif /* endif for Nest Type */
#endif /* not NDS32_SAVE_ALL_REGS */
-/*
- This is 16-byte vector size version.
- The vector id was restored into $r0 in vector by compiler.
-*/
+
+/* For 4-byte vector size version, the vector id is
+ extracted from $ITYPE and is set into $r0 by library.
+ For 16-byte vector size version, the vector id
+ is set into $r0 in vector section by compiler. */
+
+/* Save used registers first. */
#ifdef NDS32_SAVE_ALL_REGS
SAVE_ALL
#else
SAVE_PARTIAL
#endif
- /* Prepare to call 2nd level handler. */
+
+/* According to vector size, we need to have different implementation. */
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* Prepare to call 2nd level handler. */
+ la $r2, _nds32_jmptbl_00
+ lw $r2, [$r2 + $r0 << #2]
+ addi $r0, $r0, #-9 /* Make interrput vector id zero-based. */
+ ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */
+ jral $r2
+#else /* not __NDS32_ISR_VECTOR_SIZE_4__ */
+ /* Prepare to call 2nd level handler. */
la $r2, _nds32_jmptbl_09 /* For zero-based vcetor id. */
lw $r2, [$r2 + $r0 << #2]
ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */
jral $r2
- /* Restore used registers. */
+#endif /* not __NDS32_ISR_VECTOR_SIZE_4__ */
+
+/* Restore used registers. */
#ifdef NDS32_SAVE_ALL_REGS
RESTORE_ALL
#else
@@ -113,6 +127,7 @@
#endif
iret
+
#ifdef NDS32_SAVE_ALL_REGS
#if defined(NDS32_NESTED)
.size _nds32_i_sa_ns, .-_nds32_i_sa_ns
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/reset.S gcc-8.2.0/libgcc/config/nds32/isr-library/reset.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/reset.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/reset.S 2019-01-25 15:38:32.841242694 +0100
@@ -26,22 +26,18 @@
.section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */
.align 1
.weak _SDA_BASE_ /* For reset handler only. */
- .weak _FP_BASE_ /* For reset handler only. */
.weak _nds32_init_mem /* User defined memory initialization function. */
.globl _start
.globl _nds32_reset
.type _nds32_reset, @function
_nds32_reset:
_start:
-#ifdef NDS32_EXT_EX9
- .no_ex9_begin
-#endif
/* Handle NMI and warm boot if any of them exists. */
beqz $sp, 1f /* Reset, NMI or warm boot? */
/* Either NMI or warm boot; save all regs. */
/* Preserve registers for context-switching. */
-#ifdef __NDS32_REDUCED_REGS__
+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS
/* For 16-reg mode. */
smw.adm $r0, [$sp], $r10, #0x0
smw.adm $r15, [$sp], $r15, #0xf
@@ -49,10 +45,9 @@
/* For 32-reg mode. */
smw.adm $r0, [$sp], $r27, #0xf
#endif
-#ifdef NDS32_EXT_IFC
+#if __NDS32_EXT_IFC__
mfusr $r1, $IFC_LP
- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep
- stack 8-byte alignment. */
+ smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep stack 8-byte alignment. */
#endif
la $gp, _SDA_BASE_ /* Init GP for small data access. */
@@ -71,12 +66,11 @@
bnez $r0, 1f /* If fail to resume, do cold boot. */
/* Restore registers for context-switching. */
-#ifdef NDS32_EXT_IFC
- lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep
- stack 8-byte alignment. */
+#if __NDS32_EXT_IFC__
+ lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep stack 8-byte alignment. */
mtusr $r1, $IFC_LP
#endif
-#ifdef __NDS32_REDUCED_REGS__
+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS
/* For 16-reg mode. */
lmw.bim $r15, [$sp], $r15, #0xf
lmw.bim $r0, [$sp], $r10, #0x0
@@ -88,6 +82,17 @@
1: /* Cold boot. */
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* With vector ID feature for v3 architecture, default vector size is 4-byte. */
+ /* Set IVB.ESZ = 0 (vector table entry size = 4 bytes) */
+ mfsr $r0, $IVB
+ li $r1, #0xc000
+ or $r0, $r0, $r1
+ xor $r0, $r0, $r1
+ mtsr $r0, $IVB
+ dsb
+#else
+ /* There is no vector ID feature, so the vector size must be 16-byte. */
/* Set IVB.ESZ = 1 (vector table entry size = 16 bytes) */
mfsr $r0, $IVB
li $r1, #0xffff3fff
@@ -95,36 +100,54 @@
ori $r0, $r0, #0x4000
mtsr $r0, $IVB
dsb
+#endif
la $gp, _SDA_BASE_ /* Init $gp. */
- la $fp, _FP_BASE_ /* Init $fp. */
la $sp, _stack /* Init $sp. */
-#ifdef NDS32_EXT_EX9
-/*
- * Initialize the table base of EX9 instruction
- * ex9 generation needs to disable before the ITB is set
- */
- mfsr $r0, $MSC_CFG /* Check if HW support of EX9. */
+
+#if __NDS32_EXT_EX9__
+.L_init_itb:
+ /* Initialization for Instruction Table Base (ITB).
+ The symbol _ITB_BASE_ is determined by Linker.
+ Set $ITB only if MSC_CFG.EIT (cr4.b'24) is set. */
+ mfsr $r0, $MSC_CFG
srli $r0, $r0, 24
andi $r0, $r0, 0x1
- beqz $r0, 4f /* Zero means HW does not support EX9. */
- la $r0, _ITB_BASE_ /* Init $ITB. */
+ beqz $r0, 4f /* Fall through ? */
+ la $r0, _ITB_BASE_
mtusr $r0, $ITB
- .no_ex9_end
4:
#endif
- la $r15, _nds32_init_mem /* Call DRAM init. _nds32_init_mem
- may written by C language. */
+
+#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
+.L_init_fpu:
+ /* Initialize FPU
+ Set FUCOP_CTL.CP0EN (fucpr.b'0). */
+ mfsr $r0, $FUCOP_CTL
+ ori $r0, $r0, 0x1
+ mtsr $r0, $FUCOP_CTL
+ dsb
+ /* According to [bugzilla #9425], set flush-to-zero mode.
+ That is, set $FPCSR.DNZ(b'12) = 1. */
+ FMFCSR $r0
+ ori $r0, $r0, 0x1000
+ FMTCSR $r0
+ dsb
+#endif
+
+ /* Call DRAM init. _nds32_init_mem may written by C language. */
+ la $r15, _nds32_init_mem
beqz $r15, 6f
jral $r15
6:
l.w $r15, _nds32_jmptbl_00 /* Load reset handler. */
jral $r15
-/* Reset handler() should never return in a RTOS or non-OS system.
- In case it does return, an exception will be generated.
- This exception will be caught either by default break handler or by EDM.
- Default break handle may just do an infinite loop.
- EDM will notify GDB and GDB will regain control when the ID is 0x7fff. */
+
+ /* Reset handler() should never return in a RTOS or non-OS system.
+ In case it does return, an exception will be generated.
+ This exception will be caught either by default break handler or by EDM.
+ Default break handle may just do an infinite loop.
+ EDM will notify GDB and GDB will regain control when the ID is 0x7fff. */
5:
break #0x7fff
.size _nds32_reset, .-_nds32_reset
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/restore_all.inc gcc-8.2.0/libgcc/config/nds32/isr-library/restore_all.inc
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/restore_all.inc 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/restore_all.inc 2019-01-25 15:38:32.841242694 +0100
@@ -31,15 +31,11 @@
mtsr $r2, $IPSW
RESTORE_FPU_REGS
RESTORE_MAC_REGS
-#ifdef NDS32_EXT_IFC
- lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep
- stack 8-byte alignment. */
- mtusr $r1, $IFC_LP
-#endif
-#ifdef __NDS32_REDUCED_REGS__
+ RESTORE_USR_REGS
+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS
lmw.bim $r0, [$sp], $r10, #0x0 /* Restore all regs. */
lmw.bim $r15, [$sp], $r15, #0xf
-#else /* not __NDS32_REDUCED_REGS__ */
+#else
lmw.bim $r0, [$sp], $r27, #0xf /* Restore all regs. */
#endif
.endm
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/restore_mac_regs.inc gcc-8.2.0/libgcc/config/nds32/isr-library/restore_mac_regs.inc
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/restore_mac_regs.inc 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/restore_mac_regs.inc 2019-01-25 15:38:32.841242694 +0100
@@ -24,7 +24,7 @@
<http://www.gnu.org/licenses/>. */
.macro RESTORE_MAC_REGS
-#ifdef NDS32_DX_REGS
+#if __NDS32_DX_REGS__
lmw.bim $r1, [$sp], $r4, #0x0
mtusr $r1, $d0.lo
mtusr $r2, $d0.hi
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/restore_partial.inc gcc-8.2.0/libgcc/config/nds32/isr-library/restore_partial.inc
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/restore_partial.inc 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/restore_partial.inc 2019-01-25 15:38:32.841242694 +0100
@@ -31,15 +31,11 @@
mtsr $r1, $IPC /* Set IPC. */
mtsr $r2, $IPSW /* Set IPSW. */
#endif
- RESTORE_FPU_REGS
- RESTORE_MAC_REGS
-#ifdef NDS32_EXT_IFC
- lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep
- stack 8-byte alignment. */
- mtusr $r1, $IFC_LP
-#endif
+ RESTORE_FPU_REGS
+ RESTORE_MAC_REGS
+ RESTORE_USR_REGS
lmw.bim $r0, [$sp], $r5, #0x0 /* Restore all regs. */
-#ifdef __NDS32_REDUCED_REGS__
+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS
lmw.bim $r15, [$sp], $r15, #0x2
#else
lmw.bim $r15, [$sp], $r27, #0x2 /* Restore all regs. */
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/restore_usr_regs.inc gcc-8.2.0/libgcc/config/nds32/isr-library/restore_usr_regs.inc
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/restore_usr_regs.inc 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/restore_usr_regs.inc 2019-01-25 15:38:32.841242694 +0100
@@ -0,0 +1,42 @@
+/* c-isr library stuff of Andes NDS32 cpu for GNU compiler
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+.macro RESTORE_USR_REGS
+#if __NDS32_EXT_IFC__ && (__NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__)
+ lmw.bim $r1, [$sp], $r4, #0x0
+ mtusr $r1, $IFC_LP
+ mtusr $r2, $LB
+ mtusr $r3, $LE
+ mtusr $r4, $LC
+#elif __NDS32_EXT_IFC__
+ lmw.bim $r1, [$sp], $r2, #0x0
+ mtusr $r1, $IFC_LP
+#elif __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__
+ lmw.bim $r1, [$sp], $r4, #0x0
+ mtusr $r1, $LB
+ mtusr $r2, $LE
+ mtusr $r3, $LC
+#endif
+.endm
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/save_all.inc gcc-8.2.0/libgcc/config/nds32/isr-library/save_all.inc
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/save_all.inc 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/save_all.inc 2019-01-25 15:38:32.841242694 +0100
@@ -23,45 +23,42 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
-.macro SAVE_ALL_4B
-#ifdef __NDS32_REDUCED_REGS__
+#if __NDS32_ISR_VECTOR_SIZE_4__
+
+/* If vector size is 4-byte, we have to save registers
+ in the macro implementation. */
+.macro SAVE_ALL
+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS
smw.adm $r15, [$sp], $r15, #0xf
smw.adm $r0, [$sp], $r10, #0x0
-#else /* not __NDS32_REDUCED_REGS__ */
+#else
smw.adm $r0, [$sp], $r27, #0xf
-#endif /* not __NDS32_REDUCED_REGS__ */
-#ifdef NDS32_EXT_IFC
- mfusr $r1, $IFC_LP
- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep
- stack 8-byte alignment. */
#endif
- SAVE_MAC_REGS
- SAVE_FPU_REGS
+ SAVE_USR_REGS
+ SAVE_MAC_REGS
+ SAVE_FPU_REGS
mfsr $r1, $IPC /* Get IPC. */
mfsr $r2, $IPSW /* Get IPSW. */
smw.adm $r1, [$sp], $r2, #0x0 /* Push IPC, IPSW. */
move $r1, $sp /* $r1 is ptr to NDS32_CONTEXT. */
mfsr $r0, $ITYPE /* Get VID to $r0. */
srli $r0, $r0, #5
-#ifdef __NDS32_ISA_V2__
andi $r0, $r0, #127
-#else
- fexti33 $r0, #6
-#endif
.endm
+#else /* not __NDS32_ISR_VECTOR_SIZE_4__ */
+
+/* If vector size is 16-byte, some works can be done in
+ the vector section generated by compiler, so that we
+ can implement less in the macro. */
.macro SAVE_ALL
-/* SAVE_REG_TBL code has been moved to
- vector table generated by compiler. */
-#ifdef NDS32_EXT_IFC
- mfusr $r1, $IFC_LP
- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep
- stack 8-byte alignment. */
-#endif
- SAVE_MAC_REGS
- SAVE_FPU_REGS
+ SAVE_USR_REGS
+ SAVE_MAC_REGS
+ SAVE_FPU_REGS
mfsr $r1, $IPC /* Get IPC. */
mfsr $r2, $IPSW /* Get IPSW. */
smw.adm $r1, [$sp], $r2, #0x0 /* Push IPC, IPSW. */
move $r1, $sp /* $r1 is ptr to NDS32_CONTEXT. */
.endm
+
+#endif /* not __NDS32_ISR_VECTOR_SIZE_4__ */
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/save_mac_regs.inc gcc-8.2.0/libgcc/config/nds32/isr-library/save_mac_regs.inc
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/save_mac_regs.inc 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/save_mac_regs.inc 2019-01-25 15:38:32.841242694 +0100
@@ -24,7 +24,7 @@
<http://www.gnu.org/licenses/>. */
.macro SAVE_MAC_REGS
-#ifdef NDS32_DX_REGS
+#if __NDS32_DX_REGS__
mfusr $r1, $d0.lo
mfusr $r2, $d0.hi
mfusr $r3, $d1.lo
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/save_partial.inc gcc-8.2.0/libgcc/config/nds32/isr-library/save_partial.inc
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/save_partial.inc 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/save_partial.inc 2019-01-25 15:38:32.841242694 +0100
@@ -23,20 +23,20 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
-.macro SAVE_PARTIAL_4B
-#ifdef __NDS32_REDUCED_REGS__
+#if __NDS32_ISR_VECTOR_SIZE_4__
+
+/* If vector size is 4-byte, we have to save registers
+ in the macro implementation. */
+.macro SAVE_PARTIAL
+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS
smw.adm $r15, [$sp], $r15, #0x2
-#else /* not __NDS32_REDUCED_REGS__ */
+#else
smw.adm $r15, [$sp], $r27, #0x2
-#endif /* not __NDS32_REDUCED_REGS__ */
- smw.adm $r0, [$sp], $r5, #0x0
-#ifdef NDS32_EXT_IFC
- mfusr $r1, $IFC_LP
- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep
- stack 8-byte alignment. */
#endif
- SAVE_MAC_REGS
- SAVE_FPU_REGS
+ smw.adm $r0, [$sp], $r5, #0x0
+ SAVE_USR_REGS
+ SAVE_MAC_REGS
+ SAVE_FPU_REGS
#if defined(NDS32_NESTED) || defined(NDS32_NESTED_READY)
mfsr $r1, $IPC /* Get IPC. */
mfsr $r2, $IPSW /* Get IPSW. */
@@ -44,26 +44,24 @@
#endif
mfsr $r0, $ITYPE /* Get VID to $r0. */
srli $r0, $r0, #5
-#ifdef __NDS32_ISA_V2__
andi $r0, $r0, #127
-#else
- fexti33 $r0, #6
-#endif
.endm
+#else /* not __NDS32_ISR_VECTOR_SIZE_4__ */
+
+/* If vector size is 16-byte, some works can be done in
+ the vector section generated by compiler, so that we
+ can implement less in the macro. */
+
.macro SAVE_PARTIAL
-/* SAVE_CALLER_REGS code has been moved to
- vector table generated by compiler. */
-#ifdef NDS32_EXT_IFC
- mfusr $r1, $IFC_LP
- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep
- stack 8-byte alignment. */
-#endif
- SAVE_MAC_REGS
- SAVE_FPU_REGS
+ SAVE_USR_REGS
+ SAVE_MAC_REGS
+ SAVE_FPU_REGS
#if defined(NDS32_NESTED) || defined(NDS32_NESTED_READY)
mfsr $r1, $IPC /* Get IPC. */
mfsr $r2, $IPSW /* Get IPSW. */
smw.adm $r1, [$sp], $r2, #0x0 /* Push IPC, IPSW. */
#endif
.endm
+
+#endif /* not __NDS32_ISR_VECTOR_SIZE_4__ */
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/save_usr_regs.inc gcc-8.2.0/libgcc/config/nds32/isr-library/save_usr_regs.inc
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/save_usr_regs.inc 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/save_usr_regs.inc 2019-01-25 15:38:32.841242694 +0100
@@ -0,0 +1,44 @@
+/* c-isr library stuff of Andes NDS32 cpu for GNU compiler
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+.macro SAVE_USR_REGS
+/* Store User Special Registers according to supported ISA extension
+ !!! WATCH OUT !!! Take care of 8-byte alignment issue. */
+#if __NDS32_EXT_IFC__ && (__NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__)
+ mfusr $r1, $IFC_LP
+ mfusr $r2, $LB
+ mfusr $r3, $LE
+ mfusr $r4, $LC
+ smw.adm $r1, [$sp], $r4, #0x0 /* Save even. Ok! */
+#elif __NDS32_EXT_IFC__
+ mfusr $r1, $IFC_LP
+ smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep stack 8-byte aligned. */
+#elif (__NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__)
+ mfusr $r1, $LB
+ mfusr $r2, $LE
+ mfusr $r3, $LC
+ smw.adm $r1, [$sp], $r4, #0x0 /* Save extra $r4 to keep stack 8-byte aligned. */
+#endif
+.endm
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid00.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid00.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid00.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid00.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.00, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_00
.type _nds32_vector_00, @function
_nds32_vector_00:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid01.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid01.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid01.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid01.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.01, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_01
.type _nds32_vector_01, @function
_nds32_vector_01:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid02.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid02.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid02.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid02.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.02, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_02
.type _nds32_vector_02, @function
_nds32_vector_02:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid03.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid03.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid03.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid03.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.03, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_03
.type _nds32_vector_03, @function
_nds32_vector_03:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid04.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid04.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid04.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid04.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.04, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_04
.type _nds32_vector_04, @function
_nds32_vector_04:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid05.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid05.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid05.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid05.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.05, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_05
.type _nds32_vector_05, @function
_nds32_vector_05:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid06.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid06.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid06.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid06.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.06, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_06
.type _nds32_vector_06, @function
_nds32_vector_06:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid07.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid07.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid07.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid07.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.07, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_07
.type _nds32_vector_07, @function
_nds32_vector_07:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid08.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid08.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid08.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid08.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.08, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_08
.type _nds32_vector_08, @function
_nds32_vector_08:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid09.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid09.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid09.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid09.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.09, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_09
.type _nds32_vector_09, @function
_nds32_vector_09:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid10.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid10.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid10.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid10.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.10, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_10
.type _nds32_vector_10, @function
_nds32_vector_10:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid11.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid11.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid11.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid11.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.11, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_11
.type _nds32_vector_11, @function
_nds32_vector_11:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid12.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid12.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid12.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid12.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.12, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_12
.type _nds32_vector_12, @function
_nds32_vector_12:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid13.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid13.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid13.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid13.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.13, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_13
.type _nds32_vector_13, @function
_nds32_vector_13:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid14.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid14.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid14.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid14.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.14, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_14
.type _nds32_vector_14, @function
_nds32_vector_14:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid15.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid15.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid15.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid15.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.15, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_15
.type _nds32_vector_15, @function
_nds32_vector_15:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid16.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid16.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid16.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid16.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.16, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_16
.type _nds32_vector_16, @function
_nds32_vector_16:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid17.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid17.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid17.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid17.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.17, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_17
.type _nds32_vector_17, @function
_nds32_vector_17:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid18.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid18.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid18.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid18.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.18, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_18
.type _nds32_vector_18, @function
_nds32_vector_18:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid19.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid19.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid19.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid19.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.19, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_19
.type _nds32_vector_19, @function
_nds32_vector_19:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid20.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid20.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid20.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid20.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.20, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_20
.type _nds32_vector_20, @function
_nds32_vector_20:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid21.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid21.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid21.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid21.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.21, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_21
.type _nds32_vector_21, @function
_nds32_vector_21:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid22.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid22.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid22.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid22.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.22, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_22
.type _nds32_vector_22, @function
_nds32_vector_22:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid23.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid23.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid23.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid23.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.23, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_23
.type _nds32_vector_23, @function
_nds32_vector_23:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid24.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid24.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid24.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid24.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.24, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_24
.type _nds32_vector_24, @function
_nds32_vector_24:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid25.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid25.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid25.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid25.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.25, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_25
.type _nds32_vector_25, @function
_nds32_vector_25:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid26.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid26.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid26.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid26.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.26, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_26
.type _nds32_vector_26, @function
_nds32_vector_26:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid27.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid27.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid27.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid27.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.27, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_27
.type _nds32_vector_27, @function
_nds32_vector_27:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid28.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid28.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid28.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid28.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.28, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_28
.type _nds32_vector_28, @function
_nds32_vector_28:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid29.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid29.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid29.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid29.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.29, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_29
.type _nds32_vector_29, @function
_nds32_vector_29:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid30.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid30.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid30.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid30.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.30, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_30
.type _nds32_vector_30, @function
_nds32_vector_30:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid31.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid31.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid31.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid31.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.31, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_31
.type _nds32_vector_31, @function
_nds32_vector_31:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid32.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid32.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid32.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid32.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.32, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_32
.type _nds32_vector_32, @function
_nds32_vector_32:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid33.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid33.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid33.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid33.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.33, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_33
.type _nds32_vector_33, @function
_nds32_vector_33:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid34.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid34.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid34.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid34.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.34, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_34
.type _nds32_vector_34, @function
_nds32_vector_34:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid35.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid35.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid35.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid35.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.35, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_35
.type _nds32_vector_35, @function
_nds32_vector_35:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid36.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid36.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid36.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid36.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.36, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_36
.type _nds32_vector_36, @function
_nds32_vector_36:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid37.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid37.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid37.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid37.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.37, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_37
.type _nds32_vector_37, @function
_nds32_vector_37:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid38.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid38.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid38.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid38.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.38, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_38
.type _nds32_vector_38, @function
_nds32_vector_38:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid39.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid39.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid39.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid39.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.39, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_39
.type _nds32_vector_39, @function
_nds32_vector_39:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid40.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid40.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid40.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid40.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.40, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_40
.type _nds32_vector_40, @function
_nds32_vector_40:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid41.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid41.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid41.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid41.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.41, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_41
.type _nds32_vector_41, @function
_nds32_vector_41:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid42.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid42.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid42.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid42.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.42, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_42
.type _nds32_vector_42, @function
_nds32_vector_42:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid43.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid43.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid43.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid43.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.43, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_43
.type _nds32_vector_43, @function
_nds32_vector_43:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid44.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid44.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid44.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid44.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.44, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_44
.type _nds32_vector_44, @function
_nds32_vector_44:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid45.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid45.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid45.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid45.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.45, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_45
.type _nds32_vector_45, @function
_nds32_vector_45:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid46.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid46.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid46.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid46.S 2019-01-25 15:38:32.841242694 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.46, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_46
.type _nds32_vector_46, @function
_nds32_vector_46:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid47.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid47.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid47.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid47.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.47, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_47
.type _nds32_vector_47, @function
_nds32_vector_47:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid48.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid48.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid48.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid48.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.48, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_48
.type _nds32_vector_48, @function
_nds32_vector_48:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid49.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid49.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid49.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid49.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.49, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_49
.type _nds32_vector_49, @function
_nds32_vector_49:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid50.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid50.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid50.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid50.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.50, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_50
.type _nds32_vector_50, @function
_nds32_vector_50:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid51.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid51.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid51.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid51.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.51, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_51
.type _nds32_vector_51, @function
_nds32_vector_51:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid52.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid52.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid52.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid52.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.52, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_52
.type _nds32_vector_52, @function
_nds32_vector_52:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid53.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid53.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid53.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid53.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.53, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_53
.type _nds32_vector_53, @function
_nds32_vector_53:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid54.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid54.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid54.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid54.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.54, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_54
.type _nds32_vector_54, @function
_nds32_vector_54:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid55.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid55.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid55.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid55.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.55, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_55
.type _nds32_vector_55, @function
_nds32_vector_55:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid56.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid56.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid56.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid56.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.56, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_56
.type _nds32_vector_56, @function
_nds32_vector_56:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid57.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid57.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid57.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid57.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.57, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_57
.type _nds32_vector_57, @function
_nds32_vector_57:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid58.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid58.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid58.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid58.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.58, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_58
.type _nds32_vector_58, @function
_nds32_vector_58:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid59.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid59.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid59.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid59.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.59, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_59
.type _nds32_vector_59, @function
_nds32_vector_59:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid60.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid60.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid60.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid60.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.60, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_60
.type _nds32_vector_60, @function
_nds32_vector_60:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid61.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid61.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid61.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid61.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.61, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_61
.type _nds32_vector_61, @function
_nds32_vector_61:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid62.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid62.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid62.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid62.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.62, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_62
.type _nds32_vector_62, @function
_nds32_vector_62:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid63.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid63.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid63.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid63.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.63, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_63
.type _nds32_vector_63, @function
_nds32_vector_63:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid64.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid64.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid64.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid64.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.64, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_64
.type _nds32_vector_64, @function
_nds32_vector_64:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid65.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid65.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid65.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid65.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.65, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_65
.type _nds32_vector_65, @function
_nds32_vector_65:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid66.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid66.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid66.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid66.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.66, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_66
.type _nds32_vector_66, @function
_nds32_vector_66:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid67.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid67.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid67.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid67.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.67, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_67
.type _nds32_vector_67, @function
_nds32_vector_67:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid68.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid68.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid68.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid68.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.68, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_68
.type _nds32_vector_68, @function
_nds32_vector_68:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid69.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid69.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid69.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid69.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.69, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_69
.type _nds32_vector_69, @function
_nds32_vector_69:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid70.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid70.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid70.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid70.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.70, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_70
.type _nds32_vector_70, @function
_nds32_vector_70:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid71.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid71.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid71.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid71.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.71, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_71
.type _nds32_vector_71, @function
_nds32_vector_71:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid72.S gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid72.S
--- gcc-8.2.0.orig/libgcc/config/nds32/isr-library/vec_vid72.S 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/isr-library/vec_vid72.S 2019-01-25 15:38:32.845242705 +0100
@@ -24,8 +24,15 @@
<http://www.gnu.org/licenses/>. */
.section .nds32_vector.72, "ax"
+#if __NDS32_ISR_VECTOR_SIZE_4__
+ /* The vector size is default 4-byte for v3 architecture. */
+ .vec_size 4
+ .align 2
+#else
+ /* The vector size is default 16-byte for other architectures. */
.vec_size 16
.align 4
+#endif
.weak _nds32_vector_72
.type _nds32_vector_72, @function
_nds32_vector_72:
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/linux-atomic.c gcc-8.2.0/libgcc/config/nds32/linux-atomic.c
--- gcc-8.2.0.orig/libgcc/config/nds32/linux-atomic.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/linux-atomic.c 2019-01-25 15:38:32.845242705 +0100
@@ -0,0 +1,282 @@
+/* Linux-specific atomic operations for NDS32 Linux.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
+
+This file 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.
+
+This file 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* We implement byte, short and int versions of each atomic operation
+ using the kernel helper defined below. There is no support for
+ 64-bit operations yet. */
+
+/* This function copy form NDS32 Linux-kernal. */
+static inline int
+__kernel_cmpxchg (int oldval, int newval, int *mem)
+{
+ int temp1, temp2, temp3, offset;
+
+ asm volatile ("msync\tall\n"
+ "movi\t%0, #0\n"
+ "1:\n"
+ "\tllw\t%1, [%4+%0]\n"
+ "\tsub\t%3, %1, %6\n"
+ "\tcmovz\t%2, %5, %3\n"
+ "\tcmovn\t%2, %1, %3\n"
+ "\tscw\t%2, [%4+%0]\n"
+ "\tbeqz\t%2, 1b\n"
+ : "=&r" (offset), "=&r" (temp3), "=&r" (temp2), "=&r" (temp1)
+ : "r" (mem), "r" (newval), "r" (oldval) : "memory");
+
+ return temp1;
+}
+
+#define HIDDEN __attribute__ ((visibility ("hidden")))
+
+#ifdef __NDS32_EL__
+#define INVERT_MASK_1 0
+#define INVERT_MASK_2 0
+#else
+#define INVERT_MASK_1 24
+#define INVERT_MASK_2 16
+#endif
+
+#define MASK_1 0xffu
+#define MASK_2 0xffffu
+
+#define FETCH_AND_OP_WORD(OP, PFX_OP, INF_OP) \
+ int HIDDEN \
+ __sync_fetch_and_##OP##_4 (int *ptr, int val) \
+ { \
+ int failure, tmp; \
+ \
+ do { \
+ tmp = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); \
+ failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \
+ } while (failure != 0); \
+ \
+ return tmp; \
+ }
+
+FETCH_AND_OP_WORD (add, , +)
+FETCH_AND_OP_WORD (sub, , -)
+FETCH_AND_OP_WORD (or, , |)
+FETCH_AND_OP_WORD (and, , &)
+FETCH_AND_OP_WORD (xor, , ^)
+FETCH_AND_OP_WORD (nand, ~, &)
+
+#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH
+#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH
+
+/* Implement both __sync_<op>_and_fetch and __sync_fetch_and_<op> for
+ subword-sized quantities. */
+
+#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN) \
+ TYPE HIDDEN \
+ NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE val) \
+ { \
+ int *wordptr = (int *) ((unsigned long) ptr & ~3); \
+ unsigned int mask, shift, oldval, newval; \
+ int failure; \
+ \
+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
+ mask = MASK_##WIDTH << shift; \
+ \
+ do { \
+ oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \
+ newval = ((PFX_OP (((oldval & mask) >> shift) \
+ INF_OP (unsigned int) val)) << shift) & mask; \
+ newval |= oldval & ~mask; \
+ failure = __kernel_cmpxchg (oldval, newval, wordptr); \
+ } while (failure != 0); \
+ \
+ return (RETURN & mask) >> shift; \
+ }
+
+
+SUBWORD_SYNC_OP (add, , +, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (or, , |, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (and, , &, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, oldval)
+
+SUBWORD_SYNC_OP (add, , +, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (or, , |, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (and, , &, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, oldval)
+
+#define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \
+ int HIDDEN \
+ __sync_##OP##_and_fetch_4 (int *ptr, int val) \
+ { \
+ int tmp, failure; \
+ \
+ do { \
+ tmp = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); \
+ failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \
+ } while (failure != 0); \
+ \
+ return PFX_OP (tmp INF_OP val); \
+ }
+
+OP_AND_FETCH_WORD (add, , +)
+OP_AND_FETCH_WORD (sub, , -)
+OP_AND_FETCH_WORD (or, , |)
+OP_AND_FETCH_WORD (and, , &)
+OP_AND_FETCH_WORD (xor, , ^)
+OP_AND_FETCH_WORD (nand, ~, &)
+
+SUBWORD_SYNC_OP (add, , +, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (or, , |, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (and, , &, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, newval)
+
+SUBWORD_SYNC_OP (add, , +, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (or, , |, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (and, , &, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, newval)
+
+int HIDDEN
+__sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval)
+{
+ int actual_oldval, fail;
+
+ while (1)
+ {
+ actual_oldval = __atomic_load_n (ptr, __ATOMIC_SEQ_CST);
+
+ if (oldval != actual_oldval)
+ return actual_oldval;
+
+ fail = __kernel_cmpxchg (actual_oldval, newval, ptr);
+
+ if (!fail)
+ return oldval;
+ }
+}
+
+#define SUBWORD_VAL_CAS(TYPE, WIDTH) \
+ TYPE HIDDEN \
+ __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
+ TYPE newval) \
+ { \
+ int *wordptr = (int *)((unsigned long) ptr & ~3), fail; \
+ unsigned int mask, shift, actual_oldval, actual_newval; \
+ \
+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
+ mask = MASK_##WIDTH << shift; \
+ \
+ while (1) \
+ { \
+ actual_oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \
+ \
+ if (((actual_oldval & mask) >> shift) != (unsigned int) oldval) \
+ return (actual_oldval & mask) >> shift; \
+ \
+ actual_newval = (actual_oldval & ~mask) \
+ | (((unsigned int) newval << shift) & mask); \
+ \
+ fail = __kernel_cmpxchg (actual_oldval, actual_newval, \
+ wordptr); \
+ \
+ if (!fail) \
+ return oldval; \
+ } \
+ }
+
+SUBWORD_VAL_CAS (unsigned short, 2)
+SUBWORD_VAL_CAS (unsigned char, 1)
+
+typedef unsigned char bool;
+
+bool HIDDEN
+__sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval)
+{
+ int failure = __kernel_cmpxchg (oldval, newval, ptr);
+ return (failure == 0);
+}
+
+#define SUBWORD_BOOL_CAS(TYPE, WIDTH) \
+ bool HIDDEN \
+ __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
+ TYPE newval) \
+ { \
+ TYPE actual_oldval \
+ = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \
+ return (oldval == actual_oldval); \
+ }
+
+SUBWORD_BOOL_CAS (unsigned short, 2)
+SUBWORD_BOOL_CAS (unsigned char, 1)
+
+int HIDDEN
+__sync_lock_test_and_set_4 (int *ptr, int val)
+{
+ int failure, oldval;
+
+ do {
+ oldval = __atomic_load_n (ptr, __ATOMIC_SEQ_CST);
+ failure = __kernel_cmpxchg (oldval, val, ptr);
+ } while (failure != 0);
+
+ return oldval;
+}
+
+#define SUBWORD_TEST_AND_SET(TYPE, WIDTH) \
+ TYPE HIDDEN \
+ __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val) \
+ { \
+ int failure; \
+ unsigned int oldval, newval, shift, mask; \
+ int *wordptr = (int *) ((unsigned long) ptr & ~3); \
+ \
+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
+ mask = MASK_##WIDTH << shift; \
+ \
+ do { \
+ oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \
+ newval = (oldval & ~mask) \
+ | (((unsigned int) val << shift) & mask); \
+ failure = __kernel_cmpxchg (oldval, newval, wordptr); \
+ } while (failure != 0); \
+ \
+ return (oldval & mask) >> shift; \
+ }
+
+SUBWORD_TEST_AND_SET (unsigned short, 2)
+SUBWORD_TEST_AND_SET (unsigned char, 1)
+
+#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \
+ void HIDDEN \
+ __sync_lock_release_##WIDTH (TYPE *ptr) \
+ { \
+ /* All writes before this point must be seen before we release \
+ the lock itself. */ \
+ __builtin_nds32_msync_all (); \
+ *ptr = 0; \
+ }
+
+SYNC_LOCK_RELEASE (int, 4)
+SYNC_LOCK_RELEASE (short, 2)
+SYNC_LOCK_RELEASE (char, 1)
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/linux-unwind.h gcc-8.2.0/libgcc/config/nds32/linux-unwind.h
--- gcc-8.2.0.orig/libgcc/config/nds32/linux-unwind.h 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/linux-unwind.h 2019-01-25 15:38:32.845242705 +0100
@@ -0,0 +1,143 @@
+/* DWARF2 EH unwinding support for NDS32 Linux signal frame.
+ Copyright (C) 2014-2015 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef inhibit_libc
+
+/* Do code reading to identify a signal frame, and set the frame
+ state data appropriately. See unwind-dw2.c for the structs.
+ The corresponding bits in the Linux kernel are in
+ arch/nds32/kernel/signal.c. */
+
+#include <signal.h>
+#include <asm/unistd.h>
+#include <sys/ucontext.h>
+
+/* Exactly the same layout as the kernel structures, unique names. */
+
+/* arch/nds32/kernel/signal.c */
+struct _rt_sigframe {
+ siginfo_t info;
+ struct ucontext_t uc;
+};
+
+#define RT_SIGRETURN 0x8b00f044
+
+#define MD_FALLBACK_FRAME_STATE_FOR nds32_fallback_frame_state
+
+/* This function is supposed to be invoked by uw_frame_state_for()
+ when there is no unwind data available.
+
+ Generally, given the _Unwind_Context CONTEXT for a stack frame,
+ we need to look up its caller and decode information into FS.
+ However, if the exception handling happens within a signal handler,
+ the return address of signal handler is a special module, which
+ contains signal return syscall and has no FDE in the .eh_frame section.
+ We need to implement MD_FALLBACK_FRAME_STATE_FOR so that we can
+ unwind through signal frames. */
+static _Unwind_Reason_Code
+nds32_fallback_frame_state (struct _Unwind_Context *context,
+ _Unwind_FrameState *fs)
+{
+ u_int32_t *pc = (u_int32_t *) context->ra;
+ struct sigcontext *sc_;
+ _Unwind_Ptr new_cfa;
+
+#ifdef __NDS32_EB__
+#error "Signal handler is not supported for force unwind."
+#endif
+
+ if ((_Unwind_Ptr) pc & 3)
+ return _URC_END_OF_STACK;
+
+ /* Check if we are going through a signal handler.
+ See arch/nds32/kernel/signal.c implementation.
+ FIXME: Currently we only handle little endian (EL) case. */
+ if (pc[0] == RT_SIGRETURN)
+ {
+ /* Using '_sigfame' memory address to locate kernal's sigcontext.
+ The sigcontext structures in arch/nds32/include/asm/sigcontext.h. */
+ struct _rt_sigframe *rt_;
+ rt_ = context->cfa;
+ sc_ = &rt_->uc.uc_mcontext;
+ }
+ else
+ return _URC_END_OF_STACK;
+
+ /* Update cfa from sigcontext. */
+ new_cfa = (_Unwind_Ptr) sc_;
+ fs->regs.cfa_how = CFA_REG_OFFSET;
+ fs->regs.cfa_reg = STACK_POINTER_REGNUM;
+ fs->regs.cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
+
+#define NDS32_PUT_FS_REG(NUM, NAME) \
+ (fs->regs.reg[NUM].how = REG_SAVED_OFFSET, \
+ fs->regs.reg[NUM].loc.offset = (_Unwind_Ptr) &(sc_->NAME) - new_cfa)
+
+ /* Restore all registers value. */
+ NDS32_PUT_FS_REG (0, nds32_r0);
+ NDS32_PUT_FS_REG (1, nds32_r1);
+ NDS32_PUT_FS_REG (2, nds32_r2);
+ NDS32_PUT_FS_REG (3, nds32_r3);
+ NDS32_PUT_FS_REG (4, nds32_r4);
+ NDS32_PUT_FS_REG (5, nds32_r5);
+ NDS32_PUT_FS_REG (6, nds32_r6);
+ NDS32_PUT_FS_REG (7, nds32_r7);
+ NDS32_PUT_FS_REG (8, nds32_r8);
+ NDS32_PUT_FS_REG (9, nds32_r9);
+ NDS32_PUT_FS_REG (10, nds32_r10);
+ NDS32_PUT_FS_REG (11, nds32_r11);
+ NDS32_PUT_FS_REG (12, nds32_r12);
+ NDS32_PUT_FS_REG (13, nds32_r13);
+ NDS32_PUT_FS_REG (14, nds32_r14);
+ NDS32_PUT_FS_REG (15, nds32_r15);
+ NDS32_PUT_FS_REG (16, nds32_r16);
+ NDS32_PUT_FS_REG (17, nds32_r17);
+ NDS32_PUT_FS_REG (18, nds32_r18);
+ NDS32_PUT_FS_REG (19, nds32_r19);
+ NDS32_PUT_FS_REG (20, nds32_r20);
+ NDS32_PUT_FS_REG (21, nds32_r21);
+ NDS32_PUT_FS_REG (22, nds32_r22);
+ NDS32_PUT_FS_REG (23, nds32_r23);
+ NDS32_PUT_FS_REG (24, nds32_r24);
+ NDS32_PUT_FS_REG (25, nds32_r25);
+
+ NDS32_PUT_FS_REG (28, nds32_fp);
+ NDS32_PUT_FS_REG (29, nds32_gp);
+ NDS32_PUT_FS_REG (30, nds32_lp);
+ NDS32_PUT_FS_REG (31, nds32_sp);
+
+ /* Restore PC, point to trigger signal instruction. */
+ NDS32_PUT_FS_REG (32, nds32_ipc);
+
+#undef NDS32_PUT_FS_REG
+
+ /* The retaddr is PC, use PC to find FDE. */
+ fs->retaddr_column = 32;
+ fs->signal_frame = 1;
+
+ return _URC_NO_REASON;
+}
+
+#endif
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/t-nds32-glibc gcc-8.2.0/libgcc/config/nds32/t-nds32-glibc
--- gcc-8.2.0.orig/libgcc/config/nds32/t-nds32-glibc 1970-01-01 01:00:00.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/t-nds32-glibc 2019-01-25 15:38:37.357255536 +0100
@@ -0,0 +1,34 @@
+# Rules of glibc library makefile of Andes NDS32 cpu for GNU compiler
+# Copyright (C) 2012-2015 Free Software Foundation, Inc.
+# Contributed by Andes Technology Corporation.
+#
+# 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
+# <http://www.gnu.org/licenses/>.
+
+# Compiler flags to use when compiling 'libgcc2.c'
+HOST_LIBGCC2_CFLAGS = -O2 -fPIC -fwrapv
+LIB2ADD += $(srcdir)/config/nds32/linux-atomic.c
+
+#LIB1ASMSRC = nds32/lib1asmsrc-newlib.S
+#LIB1ASMFUNCS = _divsi3 _modsi3 _udivsi3 _umodsi3
+
+# List of functions not to build from libgcc2.c.
+#LIB2FUNCS_EXCLUDE = _clzsi2
+
+# List of extra C and assembler files(*.S) to add to static libgcc2.
+#LIB2ADD_ST += $(srcdir)/config/nds32/lib2csrc-newlib/_clzsi2.c
+
+# ------------------------------------------------------------------------
diff -urN gcc-8.2.0.orig/libgcc/config/nds32/t-nds32-isr gcc-8.2.0/libgcc/config/nds32/t-nds32-isr
--- gcc-8.2.0.orig/libgcc/config/nds32/t-nds32-isr 2018-01-03 11:03:58.000000000 +0100
+++ gcc-8.2.0/libgcc/config/nds32/t-nds32-isr 2019-01-25 15:38:37.357255536 +0100
@@ -23,11 +23,11 @@
# Makfile fragment rules for libnds32_isr.a to support ISR attribute extension
###############################################################################
-# basic flags setting
+# Basic flags setting.
ISR_CFLAGS = $(CFLAGS) -c
-# the object files we would like to create
-LIBNDS32_ISR_16B_OBJS = \
+# The object files we would like to create.
+LIBNDS32_ISR_VEC_OBJS = \
vec_vid00.o vec_vid01.o vec_vid02.o vec_vid03.o \
vec_vid04.o vec_vid05.o vec_vid06.o vec_vid07.o \
vec_vid08.o vec_vid09.o vec_vid10.o vec_vid11.o \
@@ -46,40 +46,9 @@
vec_vid60.o vec_vid61.o vec_vid62.o vec_vid63.o \
vec_vid64.o vec_vid65.o vec_vid66.o vec_vid67.o \
vec_vid68.o vec_vid69.o vec_vid70.o vec_vid71.o \
- vec_vid72.o \
- excp_isr_ps_nn.o excp_isr_ps_ns.o excp_isr_ps_nr.o \
- excp_isr_sa_nn.o excp_isr_sa_ns.o excp_isr_sa_nr.o \
- intr_isr_ps_nn.o intr_isr_ps_ns.o intr_isr_ps_nr.o \
- intr_isr_sa_nn.o intr_isr_sa_ns.o intr_isr_sa_nr.o \
- reset.o
-
-LIBNDS32_ISR_4B_OBJS = \
- vec_vid00_4b.o vec_vid01_4b.o vec_vid02_4b.o vec_vid03_4b.o \
- vec_vid04_4b.o vec_vid05_4b.o vec_vid06_4b.o vec_vid07_4b.o \
- vec_vid08_4b.o vec_vid09_4b.o vec_vid10_4b.o vec_vid11_4b.o \
- vec_vid12_4b.o vec_vid13_4b.o vec_vid14_4b.o vec_vid15_4b.o \
- vec_vid16_4b.o vec_vid17_4b.o vec_vid18_4b.o vec_vid19_4b.o \
- vec_vid20_4b.o vec_vid21_4b.o vec_vid22_4b.o vec_vid23_4b.o \
- vec_vid24_4b.o vec_vid25_4b.o vec_vid26_4b.o vec_vid27_4b.o \
- vec_vid28_4b.o vec_vid29_4b.o vec_vid30_4b.o vec_vid31_4b.o \
- vec_vid32_4b.o vec_vid33_4b.o vec_vid34_4b.o vec_vid35_4b.o \
- vec_vid36_4b.o vec_vid37_4b.o vec_vid38_4b.o vec_vid39_4b.o \
- vec_vid40_4b.o vec_vid41_4b.o vec_vid42_4b.o vec_vid43_4b.o \
- vec_vid44_4b.o vec_vid45_4b.o vec_vid46_4b.o vec_vid47_4b.o \
- vec_vid48_4b.o vec_vid49_4b.o vec_vid50_4b.o vec_vid51_4b.o \
- vec_vid52_4b.o vec_vid53_4b.o vec_vid54_4b.o vec_vid55_4b.o \
- vec_vid56_4b.o vec_vid57_4b.o vec_vid58_4b.o vec_vid59_4b.o \
- vec_vid60_4b.o vec_vid61_4b.o vec_vid62_4b.o vec_vid63_4b.o \
- vec_vid64_4b.o vec_vid65_4b.o vec_vid66_4b.o vec_vid67_4b.o \
- vec_vid68_4b.o vec_vid69_4b.o vec_vid70_4b.o vec_vid71_4b.o \
- vec_vid72_4b.o \
- excp_isr_ps_nn_4b.o excp_isr_ps_ns_4b.o excp_isr_ps_nr_4b.o \
- excp_isr_sa_nn_4b.o excp_isr_sa_ns_4b.o excp_isr_sa_nr_4b.o \
- intr_isr_ps_nn_4b.o intr_isr_ps_ns_4b.o intr_isr_ps_nr_4b.o \
- intr_isr_sa_nn_4b.o intr_isr_sa_ns_4b.o intr_isr_sa_nr_4b.o \
- reset_4b.o
+ vec_vid72.o
-LIBNDS32_ISR_COMMON_OBJS = \
+LIBNDS32_ISR_JMP_OBJS = \
jmptbl_vid00.o jmptbl_vid01.o jmptbl_vid02.o jmptbl_vid03.o \
jmptbl_vid04.o jmptbl_vid05.o jmptbl_vid06.o jmptbl_vid07.o \
jmptbl_vid08.o jmptbl_vid09.o jmptbl_vid10.o jmptbl_vid11.o \
@@ -98,29 +67,32 @@
jmptbl_vid60.o jmptbl_vid61.o jmptbl_vid62.o jmptbl_vid63.o \
jmptbl_vid64.o jmptbl_vid65.o jmptbl_vid66.o jmptbl_vid67.o \
jmptbl_vid68.o jmptbl_vid69.o jmptbl_vid70.o jmptbl_vid71.o \
- jmptbl_vid72.o \
+ jmptbl_vid72.o
+
+LIBNDS32_ISR_COMMON_OBJS = \
+ excp_isr_ps_nn.o excp_isr_ps_ns.o excp_isr_ps_nr.o \
+ excp_isr_sa_nn.o excp_isr_sa_ns.o excp_isr_sa_nr.o \
+ intr_isr_ps_nn.o intr_isr_ps_ns.o intr_isr_ps_nr.o \
+ intr_isr_sa_nn.o intr_isr_sa_ns.o intr_isr_sa_nr.o \
+ reset.o \
nmih.o \
wrh.o
-LIBNDS32_ISR_COMPLETE_OBJS = $(LIBNDS32_ISR_16B_OBJS) $(LIBNDS32_ISR_4B_OBJS) $(LIBNDS32_ISR_COMMON_OBJS)
-
+LIBNDS32_ISR_COMPLETE_OBJS = $(LIBNDS32_ISR_VEC_OBJS) $(LIBNDS32_ISR_JMP_OBJS) $(LIBNDS32_ISR_COMMON_OBJS)
-# Build common objects for ISR library
-nmih.o: $(srcdir)/config/nds32/isr-library/nmih.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/nmih.S -o nmih.o
-wrh.o: $(srcdir)/config/nds32/isr-library/wrh.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/wrh.S -o wrh.o
-jmptbl_vid%.o: $(srcdir)/config/nds32/isr-library/jmptbl_vid%.S
+# Build vector vid objects for ISR library.
+vec_vid%.o: $(srcdir)/config/nds32/isr-library/vec_vid%.S
$(GCC_FOR_TARGET) $(ISR_CFLAGS) $< -o $@
-
-# Build 16b version objects for ISR library. (no "_4b" postfix string)
-vec_vid%.o: $(srcdir)/config/nds32/isr-library/vec_vid%.S
+# Build jump table objects for ISR library.
+jmptbl_vid%.o: $(srcdir)/config/nds32/isr-library/jmptbl_vid%.S
$(GCC_FOR_TARGET) $(ISR_CFLAGS) $< -o $@
+
+# Build commen objects for ISR library.
excp_isr_ps_nn.o: $(srcdir)/config/nds32/isr-library/excp_isr.S
$(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/excp_isr.S -o excp_isr_ps_nn.o
@@ -160,48 +132,12 @@
reset.o: $(srcdir)/config/nds32/isr-library/reset.S
$(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/reset.S -o reset.o
-# Build 4b version objects for ISR library.
-vec_vid%_4b.o: $(srcdir)/config/nds32/isr-library/vec_vid%_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $< -o $@
-
-excp_isr_ps_nn_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_ps_nn_4b.o
-
-excp_isr_ps_ns_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_ps_ns_4b.o
-
-excp_isr_ps_nr_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_ps_nr_4b.o
-
-excp_isr_sa_nn_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_sa_nn_4b.o
-
-excp_isr_sa_ns_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_sa_ns_4b.o
-
-excp_isr_sa_nr_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_sa_nr_4b.o
-
-intr_isr_ps_nn_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_ps_nn_4b.o
-
-intr_isr_ps_ns_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_ps_ns_4b.o
-
-intr_isr_ps_nr_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_ps_nr_4b.o
-
-intr_isr_sa_nn_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_sa_nn_4b.o
-
-intr_isr_sa_ns_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_sa_ns_4b.o
+nmih.o: $(srcdir)/config/nds32/isr-library/nmih.S
+ $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/nmih.S -o nmih.o
-intr_isr_sa_nr_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_sa_nr_4b.o
+wrh.o: $(srcdir)/config/nds32/isr-library/wrh.S
+ $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/wrh.S -o wrh.o
-reset_4b.o: $(srcdir)/config/nds32/isr-library/reset_4b.S
- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/reset_4b.S -o reset_4b.o
# The rule to create libnds32_isr.a file
diff -urN gcc-8.2.0.orig/libgcc/config.host gcc-8.2.0/libgcc/config.host
--- gcc-8.2.0.orig/libgcc/config.host 2018-04-06 22:04:17.000000000 +0200
+++ gcc-8.2.0/libgcc/config.host 2019-01-25 15:38:32.841242694 +0100
@@ -974,6 +974,23 @@
tmake_file="$tm_file t-crtstuff t-fdpbit msp430/t-msp430"
extra_parts="$extra_parts libmul_none.a libmul_16.a libmul_32.a libmul_f5.a"
;;
+nds32*-linux*)
+ # Basic makefile fragment and extra_parts for crt stuff.
+ # We also append c-isr library implementation.
+ tmake_file="${tmake_file} t-slibgcc-libgcc"
+ tmake_file="${tmake_file} nds32/t-nds32-glibc nds32/t-crtstuff t-softfp-sfdf t-softfp"
+ # The header file of defining MD_FALLBACK_FRAME_STATE_FOR.
+ md_unwind_header=nds32/linux-unwind.h
+ # Append library definition makefile fragment according to --with-nds32-lib=X setting.
+ case "${with_nds32_lib}" in
+ "" | glibc | uclibc )
+ ;;
+ *)
+ echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: glibc uclibc" 1>&2
+ exit 1
+ ;;
+ esac
+ ;;
nds32*-elf*)
# Basic makefile fragment and extra_parts for crt stuff.
# We also append c-isr library implementation.