diff gcc/config/nds32/nds32.h @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/gcc/config/nds32/nds32.h	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/config/nds32/nds32.h	Thu Oct 25 07:37:49 2018 +0900
@@ -1,5 +1,5 @@
 /* Definitions of target machine of Andes NDS32 cpu for GNU compiler
-   Copyright (C) 2012-2017 Free Software Foundation, Inc.
+   Copyright (C) 2012-2018 Free Software Foundation, Inc.
    Contributed by Andes Technology Corporation.
 
    This file is part of GCC.
@@ -24,6 +24,9 @@
 /* The following are auxiliary macros or structure declarations
    that are used all over the nds32.c and nds32.h.  */
 
+#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
+  (LENGTH = nds32_adjust_insn_length (INSN, LENGTH))
+
 /* Use SYMBOL_FLAG_MACH_DEP to define our own symbol_ref flag.
    It is used in nds32_encode_section_info() to store flag in symbol_ref
    in case the symbol should be placed in .rodata section.
@@ -33,68 +36,23 @@
 #define NDS32_SYMBOL_REF_RODATA_P(x) \
   ((SYMBOL_REF_FLAGS (x) & NDS32_SYMBOL_FLAG_RODATA) != 0)
 
-/* Computing the Length of an Insn.  */
-#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
-  (LENGTH = nds32_adjust_insn_length (INSN, LENGTH))
-
-/* Check instruction LS-37-FP-implied form.
-   Note: actually its immediate range is imm9u
-         since it is used for lwi37/swi37 instructions.  */
-#define NDS32_LS_37_FP_P(rt, ra, imm)       \
-  (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \
-   && REGNO (ra) == FP_REGNUM               \
-   && satisfies_constraint_Iu09 (imm))
-
-/* Check instruction LS-37-SP-implied form.
-   Note: actually its immediate range is imm9u
-         since it is used for lwi37/swi37 instructions.  */
-#define NDS32_LS_37_SP_P(rt, ra, imm)       \
-  (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \
-   && REGNO (ra) == SP_REGNUM               \
-   && satisfies_constraint_Iu09 (imm))
-
-
-/* Check load/store instruction form : Rt3, Ra3, imm3u.  */
-#define NDS32_LS_333_P(rt, ra, imm, mode) nds32_ls_333_p (rt, ra, imm, mode)
-
-/* Check load/store instruction form : Rt4, Ra5, const_int_0.
-   Note: no need to check ra because Ra5 means it covers all registers.  */
-#define NDS32_LS_450_P(rt, ra, imm)                     \
-  ((imm == const0_rtx)                                  \
-   && (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS         \
-       || REGNO_REG_CLASS (REGNO (rt)) == MIDDLE_REGS))
+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
+};
 
-/* Check instruction RRI-333-form.  */
-#define NDS32_RRI_333_P(rt, ra, imm)           \
-  (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS    \
-   && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS \
-   && satisfies_constraint_Iu03 (imm))
-
-/* Check instruction RI-45-form.  */
-#define NDS32_RI_45_P(rt, ra, imm)                     \
-  (REGNO (rt) == REGNO (ra)                            \
-   && (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS        \
-       || REGNO_REG_CLASS (REGNO (rt)) == MIDDLE_REGS) \
-   && satisfies_constraint_Iu05 (imm))
-
-
-/* Check instruction RR-33-form.  */
-#define NDS32_RR_33_P(rt, ra)                   \
-  (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS     \
-   && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
-
-/* Check instruction RRR-333-form.  */
-#define NDS32_RRR_333_P(rt, ra, rb)             \
-  (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS     \
-   && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS  \
-   && REGNO_REG_CLASS (REGNO (rb)) == LOW_REGS)
-
-/* Check instruction RR-45-form.
-   Note: no need to check rb because Rb5 means it covers all registers.  */
-#define NDS32_RR_45_P(rt, ra, rb)               \
-  (REGNO (rt) == REGNO (ra)                     \
-   && (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \
-       || REGNO_REG_CLASS (REGNO (rt)) == MIDDLE_REGS))
+/* Classifies expand result for expand helper function.  */
+enum nds32_expand_result_type
+{
+  EXPAND_DONE,
+  EXPAND_FAIL,
+  EXPAND_CREATE_TEMPLATE
+};
 
 /* Classifies address type to distinguish 16-bit/32-bit format.  */
 enum nds32_16bit_address_type
@@ -105,6 +63,10 @@
   ADDRESS_LO_REG_IMM3U,
   /* post_inc [lo_reg + imm3u]: 333 format address.  */
   ADDRESS_POST_INC_LO_REG_IMM3U,
+  /* post_modify [lo_reg + imm3u]: 333 format address.  */
+  ADDRESS_POST_MODIFY_LO_REG_IMM3U,
+  /* [$r8 + imm7u]: r8 imply address.  */
+  ADDRESS_R8_IMM7U,
   /* [$fp + imm7u]: fp imply address.  */
   ADDRESS_FP_IMM7U,
   /* [$sp + imm7u]: sp imply address.  */
@@ -118,18 +80,63 @@
 
 /* Define maximum numbers of registers for passing arguments.  */
 #define NDS32_MAX_GPR_REGS_FOR_ARGS 6
+#define NDS32_MAX_FPR_REGS_FOR_ARGS 6
 
 /* Define the register number for first argument.  */
 #define NDS32_GPR_ARG_FIRST_REGNUM 0
+#define NDS32_FPR_ARG_FIRST_REGNUM 34
 
 /* Define the register number for return value.  */
 #define NDS32_GPR_RET_FIRST_REGNUM 0
+#define NDS32_FPR_RET_FIRST_REGNUM 34
 
 /* Define the first integer register number.  */
 #define NDS32_FIRST_GPR_REGNUM 0
 /* Define the last integer register number.  */
 #define NDS32_LAST_GPR_REGNUM 31
 
+#define NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM 6
+#define NDS32_LAST_CALLEE_SAVE_GPR_REGNUM \
+  (TARGET_REDUCED_REGS ? 10 : 14)
+
+/* Define the floating-point number of registers.  */
+#define NDS32_FLOAT_REGISTER_NUMBER                           \
+ (((nds32_fp_regnum == NDS32_CONFIG_FPU_0)              \
+   || (nds32_fp_regnum == NDS32_CONFIG_FPU_4)) ? 8      \
+  : ((nds32_fp_regnum == NDS32_CONFIG_FPU_1)            \
+    || (nds32_fp_regnum == NDS32_CONFIG_FPU_5)) ? 16    \
+  : ((nds32_fp_regnum == NDS32_CONFIG_FPU_2)            \
+    || (nds32_fp_regnum == NDS32_CONFIG_FPU_6)) ? 32    \
+  : ((nds32_fp_regnum == NDS32_CONFIG_FPU_3)            \
+    || (nds32_fp_regnum == NDS32_CONFIG_FPU_7)) ? 64    \
+  : 32)
+
+#define NDS32_EXT_FPU_DOT_E (nds32_fp_regnum >= 4)
+
+/* Define the first floating-point register number.  */
+#define NDS32_FIRST_FPR_REGNUM 34
+/* Define the last floating-point register number.  */
+#define NDS32_LAST_FPR_REGNUM \
+  (NDS32_FIRST_FPR_REGNUM + NDS32_FLOAT_REGISTER_NUMBER - 1)
+
+
+#define NDS32_IS_EXT_FPR_REGNUM(regno) \
+  (((regno) >= NDS32_FIRST_FPR_REGNUM + 32) \
+   && ((regno) < NDS32_FIRST_FPR_REGNUM + 64))
+
+#define NDS32_IS_FPR_REGNUM(regno) \
+  (((regno) >= NDS32_FIRST_FPR_REGNUM) \
+   && ((regno) <= NDS32_LAST_FPR_REGNUM))
+
+#define NDS32_FPR_REGNO_OK_FOR_SINGLE(regno) \
+  ((regno) <= NDS32_LAST_FPR_REGNUM)
+
+#define NDS32_FPR_REGNO_OK_FOR_DOUBLE(regno) \
+  ((((regno) - NDS32_FIRST_FPR_REGNUM) & 1) == 0)
+
+#define NDS32_IS_GPR_REGNUM(regno) \
+  (((regno) <= NDS32_LAST_GPR_REGNUM))
+
 /* Define double word alignment bits.  */
 #define NDS32_DOUBLE_WORD_ALIGNMENT 64
 
@@ -138,6 +145,14 @@
 #define NDS32_SINGLE_WORD_ALIGN_P(value) (((value) & 0x03) == 0)
 #define NDS32_DOUBLE_WORD_ALIGN_P(value) (((value) & 0x07) == 0)
 
+/* Determine whether we would like to have code generation strictly aligned.
+   We set it strictly aligned when -malways-align is enabled.
+   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) \
@@ -173,7 +188,14 @@
       : ((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM))               \
    : ((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM))
 
-/* This macro is to check if there are still available registers
+#define NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG(reg_offset, mode, type) \
+  ((NDS32_NEED_N_REGS_FOR_ARG (mode, type) > 1)                    \
+   ? ((NDS32_MODE_TYPE_ALIGN (mode, type) > PARM_BOUNDARY)         \
+      ? (((reg_offset) + NDS32_FPR_ARG_FIRST_REGNUM + 1) & ~1)     \
+      : ((reg_offset) + NDS32_FPR_ARG_FIRST_REGNUM))               \
+   : ((reg_offset) + NDS32_FPR_ARG_FIRST_REGNUM))
+
+/* These two macros are to check if there are still available registers
    for passing argument, which must be entirely in registers.  */
 #define NDS32_ARG_ENTIRE_IN_GPR_REG_P(reg_offset, mode, type)   \
   ((NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (reg_offset, mode, type) \
@@ -181,13 +203,23 @@
    <= (NDS32_GPR_ARG_FIRST_REGNUM                               \
        + NDS32_MAX_GPR_REGS_FOR_ARGS))
 
-/* This macro is to check if there are still available registers
+#define NDS32_ARG_ENTIRE_IN_FPR_REG_P(reg_offset, mode, type)   \
+  ((NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (reg_offset, mode, type) \
+    + NDS32_NEED_N_REGS_FOR_ARG (mode, type))                   \
+   <= (NDS32_FPR_ARG_FIRST_REGNUM                               \
+       + NDS32_MAX_FPR_REGS_FOR_ARGS))
+
+/* These two macros are to check if there are still available registers
    for passing argument, either entirely in registers or partially
    in registers.  */
 #define NDS32_ARG_PARTIAL_IN_GPR_REG_P(reg_offset, mode, type) \
   (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (reg_offset, mode, type) \
    < NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS)
 
+#define NDS32_ARG_PARTIAL_IN_FPR_REG_P(reg_offset, mode, type) \
+  (NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (reg_offset, mode, type) \
+   < NDS32_FPR_ARG_FIRST_REGNUM + NDS32_MAX_FPR_REGS_FOR_ARGS)
+
 /* This macro is to check if the register is required to be saved on stack.
    If call_used_regs[regno] == 0, regno is the callee-saved register.
    If df_regs_ever_live_p(regno) == true, it is used in the current function.
@@ -196,6 +228,19 @@
 #define NDS32_REQUIRED_CALLEE_SAVED_P(regno)                  \
   ((!call_used_regs[regno]) && (df_regs_ever_live_p (regno)))
 
+/* This macro is to check if the push25/pop25 are available to be used
+   for code generation.  Because pop25 also performs return behavior,
+   the instructions may not be available for some cases.
+   If we want to use push25/pop25, all the following conditions must
+   be satisfied:
+     1. TARGET_V3PUSH is set.
+     2. Current function is not an ISR function.
+     3. Current function is not a variadic function.*/
+#define NDS32_V3PUSH_AVAILABLE_P  \
+  (TARGET_V3PUSH \
+   && !nds32_isr_function_p (current_function_decl) \
+   && (cfun->machine->va_args_size == 0))
+
 /* ------------------------------------------------------------------------ */
 
 /* A C structure for machine-specific, per-function data.
@@ -222,6 +267,10 @@
      callee-saved registers.  */
   int callee_saved_gpr_regs_size;
 
+  /* Number of bytes on the stack for saving floating-point
+     callee-saved registers.  */
+  int callee_saved_fpr_regs_size;
+
   /* The padding bytes in callee-saved area may be required.  */
   int callee_saved_area_gpr_padding_bytes;
 
@@ -230,6 +279,11 @@
   /* The last required general purpose callee-saved register.  */
   int callee_saved_last_gpr_regno;
 
+  /* The first required floating-point callee-saved register.  */
+  int callee_saved_first_fpr_regno;
+  /* The last required floating-point callee-saved register.  */
+  int callee_saved_last_fpr_regno;
+
   /* The padding bytes in varargs area may be required.  */
   int va_args_area_padding_bytes;
 
@@ -238,18 +292,43 @@
   /* The last required register that should be saved on stack for va_args.  */
   int va_args_last_regno;
 
+  /* Number of bytes on the stack for saving exception handling registers.  */
+  int eh_return_data_regs_size;
+  /* The first register of passing exception handling information.  */
+  int eh_return_data_first_regno;
+  /* The last register of passing exception handling information.  */
+  int eh_return_data_last_regno;
+
+  /* Indicate that whether this function
+     calls __builtin_eh_return.  */
+  int use_eh_return_p;
+
   /* Indicate that whether this function needs
      prologue/epilogue code generation.  */
   int naked_p;
   /* Indicate that whether this function
      uses fp_as_gp optimization.  */
   int fp_as_gp_p;
+  /* Indicate that whether this function is under strictly aligned
+     situation for legitimate address checking.  This flag informs
+     nds32_legitimate_address_p() how to treat offset alignment:
+       1. The IVOPT phase needs to detect available range for memory access,
+	  such as checking [base + 32767] ~ [base + (-32768)].
+	  For this case we do not want address to be strictly aligned.
+       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.  */
 typedef struct
 {
   unsigned int gpr_offset;
+  unsigned int fpr_offset;
 } nds32_cumulative_args;
 
 /* ------------------------------------------------------------------------ */
@@ -288,7 +367,8 @@
 {
   NDS32_NESTED,
   NDS32_NOT_NESTED,
-  NDS32_NESTED_READY
+  NDS32_NESTED_READY,
+  NDS32_CRITICAL
 };
 
 /* Define structure to record isr information.
@@ -316,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.
@@ -340,20 +427,463 @@
 {
   NDS32_BUILTIN_ISYNC,
   NDS32_BUILTIN_ISB,
+  NDS32_BUILTIN_DSB,
+  NDS32_BUILTIN_MSYNC_ALL,
+  NDS32_BUILTIN_MSYNC_STORE,
   NDS32_BUILTIN_MFSR,
   NDS32_BUILTIN_MFUSR,
   NDS32_BUILTIN_MTSR,
+  NDS32_BUILTIN_MTSR_ISB,
+  NDS32_BUILTIN_MTSR_DSB,
   NDS32_BUILTIN_MTUSR,
   NDS32_BUILTIN_SETGIE_EN,
-  NDS32_BUILTIN_SETGIE_DIS
+  NDS32_BUILTIN_SETGIE_DIS,
+  NDS32_BUILTIN_FMFCFG,
+  NDS32_BUILTIN_FMFCSR,
+  NDS32_BUILTIN_FMTCSR,
+  NDS32_BUILTIN_FCPYNSS,
+  NDS32_BUILTIN_FCPYSS,
+  NDS32_BUILTIN_FCPYNSD,
+  NDS32_BUILTIN_FCPYSD,
+  NDS32_BUILTIN_ABS,
+  NDS32_BUILTIN_AVE,
+  NDS32_BUILTIN_BCLR,
+  NDS32_BUILTIN_BSET,
+  NDS32_BUILTIN_BTGL,
+  NDS32_BUILTIN_BTST,
+  NDS32_BUILTIN_CLIP,
+  NDS32_BUILTIN_CLIPS,
+  NDS32_BUILTIN_CLZ,
+  NDS32_BUILTIN_CLO,
+  NDS32_BUILTIN_MAX,
+  NDS32_BUILTIN_MIN,
+  NDS32_BUILTIN_PBSAD,
+  NDS32_BUILTIN_PBSADA,
+  NDS32_BUILTIN_BSE,
+  NDS32_BUILTIN_BSP,
+  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,
+  NDS32_BUILTIN_WSBH,
+  NDS32_BUILTIN_JR_ITOFF,
+  NDS32_BUILTIN_JR_TOFF,
+  NDS32_BUILTIN_JRAL_ITON,
+  NDS32_BUILTIN_JRAL_TON,
+  NDS32_BUILTIN_RET_ITOFF,
+  NDS32_BUILTIN_RET_TOFF,
+  NDS32_BUILTIN_STANDBY_NO_WAKE_GRANT,
+  NDS32_BUILTIN_STANDBY_WAKE_GRANT,
+  NDS32_BUILTIN_STANDBY_WAKE_DONE,
+  NDS32_BUILTIN_TEQZ,
+  NDS32_BUILTIN_TNEZ,
+  NDS32_BUILTIN_TRAP,
+  NDS32_BUILTIN_SETEND_BIG,
+  NDS32_BUILTIN_SETEND_LITTLE,
+  NDS32_BUILTIN_SYSCALL,
+  NDS32_BUILTIN_BREAK,
+  NDS32_BUILTIN_NOP,
+  NDS32_BUILTIN_SCHE_BARRIER,
+  NDS32_BUILTIN_GET_CURRENT_SP,
+  NDS32_BUILTIN_SET_CURRENT_SP,
+  NDS32_BUILTIN_RETURN_ADDRESS,
+  NDS32_BUILTIN_LLW,
+  NDS32_BUILTIN_LWUP,
+  NDS32_BUILTIN_LBUP,
+  NDS32_BUILTIN_SCW,
+  NDS32_BUILTIN_SWUP,
+  NDS32_BUILTIN_SBUP,
+  NDS32_BUILTIN_CCTL_VA_LCK,
+  NDS32_BUILTIN_CCTL_IDX_WBINVAL,
+  NDS32_BUILTIN_CCTL_VA_WBINVAL_L1,
+  NDS32_BUILTIN_CCTL_VA_WBINVAL_LA,
+  NDS32_BUILTIN_CCTL_IDX_READ,
+  NDS32_BUILTIN_CCTL_IDX_WRITE,
+  NDS32_BUILTIN_CCTL_L1D_INVALALL,
+  NDS32_BUILTIN_CCTL_L1D_WBALL_ALVL,
+  NDS32_BUILTIN_CCTL_L1D_WBALL_ONE_LVL,
+  NDS32_BUILTIN_DPREF_QW,
+  NDS32_BUILTIN_DPREF_HW,
+  NDS32_BUILTIN_DPREF_W,
+  NDS32_BUILTIN_DPREF_DW,
+  NDS32_BUILTIN_TLBOP_TRD,
+  NDS32_BUILTIN_TLBOP_TWR,
+  NDS32_BUILTIN_TLBOP_RWR,
+  NDS32_BUILTIN_TLBOP_RWLK,
+  NDS32_BUILTIN_TLBOP_UNLK,
+  NDS32_BUILTIN_TLBOP_PB,
+  NDS32_BUILTIN_TLBOP_INV,
+  NDS32_BUILTIN_TLBOP_FLUA,
+  NDS32_BUILTIN_UALOAD_HW,
+  NDS32_BUILTIN_UALOAD_W,
+  NDS32_BUILTIN_UALOAD_DW,
+  NDS32_BUILTIN_UASTORE_HW,
+  NDS32_BUILTIN_UASTORE_W,
+  NDS32_BUILTIN_UASTORE_DW,
+  NDS32_BUILTIN_GIE_DIS,
+  NDS32_BUILTIN_GIE_EN,
+  NDS32_BUILTIN_ENABLE_INT,
+  NDS32_BUILTIN_DISABLE_INT,
+  NDS32_BUILTIN_SET_PENDING_SWINT,
+  NDS32_BUILTIN_CLR_PENDING_SWINT,
+  NDS32_BUILTIN_CLR_PENDING_HWINT,
+  NDS32_BUILTIN_GET_ALL_PENDING_INT,
+  NDS32_BUILTIN_GET_PENDING_INT,
+  NDS32_BUILTIN_SET_INT_PRIORITY,
+  NDS32_BUILTIN_GET_INT_PRIORITY,
+  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,
+  NDS32_BUILTIN_COUNT
 };
 
 /* ------------------------------------------------------------------------ */
 
+#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)
+#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)
+
 #define TARGET_CMODEL_SMALL \
    (nds32_cmodel_option == CMODEL_SMALL)
 #define TARGET_CMODEL_MEDIUM \
@@ -361,55 +891,96 @@
 #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 \
    (nds32_cmodel_option == CMODEL_SMALL\
     || nds32_cmodel_option == CMODEL_MEDIUM)
 
-#define TARGET_SOFT_FLOAT 1
-#define TARGET_HARD_FLOAT 0
+#define TARGET_MUL_SLOW \
+  (nds32_mul_config == MUL_TYPE_SLOW)
+
+/* Run-time Target Specification.  */
+#define TARGET_SOFT_FLOAT (nds32_abi == NDS32_ABI_V2)
+/* Use hardware floating point calling convention.  */
+#define TARGET_HARD_FLOAT (nds32_abi == NDS32_ABI_V2_FP_PLUS)
+
+/* 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 == 1
+#  define TARGET_DEFAULT_ABI NDS32_ABI_V2_FP_PLUS
+#  define TARGET_DEFAULT_FPU_ISA MASK_FPU_DOUBLE | MASK_FPU_SINGLE
+#  define TARGET_DEFAULT_FPU_FMA 0
+#else
+#  if TARGET_ARCH_DEFAULT == 2
+#    define TARGET_DEFAULT_ABI NDS32_ABI_V2_FP_PLUS
+#    define TARGET_DEFAULT_FPU_ISA MASK_FPU_SINGLE
+#    define TARGET_DEFAULT_FPU_FMA 0
+#  else
+#    define TARGET_DEFAULT_ABI NDS32_ABI_V2
+#    define TARGET_DEFAULT_FPU_ISA 0
+#    define TARGET_DEFAULT_FPU_FMA 0
+#  endif
+#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.  */
 
 #define OPTION_DEFAULT_SPECS \
-  {"arch", "%{!march=*:-march=%(VALUE)}" }
+  {"arch", " %{!march=*:-march=%(VALUE)}" \
+	   " %{march=v3f:%{!mfloat-abi=*:-mfloat-abi=hard}" \
+	   " %{!mno-ext-fpu-sp:%{!mext-fpu-sp:-mext-fpu-sp}}" \
+	   " %{!mno-ext-fpu-dp:%{!mext-fpu-dp:-mext-fpu-dp}}}" \
+	   " %{march=v3s:%{!mfloat-abi=*:-mfloat-abi=hard}" \
+	   " %{!mno-ext-fpu-sp:%{!mext-fpu-sp:-mext-fpu-sp}}}" }, \
+  {"cpu",  "%{!mcpu=*:-mcpu=%(VALUE)}" },   \
+  {"float", "%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}" }
 
 #define CC1_SPEC \
-  ""
+  NDS32_EXT_DSP_SPEC
 
 #define ASM_SPEC \
-  " %{mbig-endian:-EB} %{mlittle-endian:-EL}"
-
-/* 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}"
+  " %{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}" \
+  " %{mno-ext-fpu-mac:-mno-mac}" \
+  " %{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}" \
+  " %{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.
@@ -420,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 }
@@ -430,34 +1003,8 @@
 
 /* Run-time Target Specification.  */
 
-#define TARGET_CPU_CPP_BUILTINS()                     \
-  do                                                  \
-    {                                                 \
-      builtin_define ("__nds32__");                   \
-                                                      \
-      if (TARGET_ISA_V2)                              \
-        builtin_define ("__NDS32_ISA_V2__");          \
-      if (TARGET_ISA_V3)                              \
-        builtin_define ("__NDS32_ISA_V3__");          \
-      if (TARGET_ISA_V3M)                             \
-        builtin_define ("__NDS32_ISA_V3M__");         \
-                                                      \
-      if (TARGET_BIG_ENDIAN)                          \
-        builtin_define ("__big_endian__");            \
-      if (TARGET_REDUCED_REGS)                        \
-        builtin_define ("__NDS32_REDUCED_REGS__");    \
-      if (TARGET_CMOV)                                \
-        builtin_define ("__NDS32_CMOV__");            \
-      if (TARGET_PERF_EXT)                            \
-        builtin_define ("__NDS32_PERF_EXT__");        \
-      if (TARGET_16_BIT)                              \
-        builtin_define ("__NDS32_16_BIT__");          \
-      if (TARGET_GP_DIRECT)                           \
-        builtin_define ("__NDS32_GP_DIRECT__");       \
-                                                      \
-      builtin_assert ("cpu=nds32");                   \
-      builtin_assert ("machine=nds32");               \
-    } while (0)
+#define TARGET_CPU_CPP_BUILTINS() \
+  nds32_cpu_cpp_builtins (pfile)
 
 
 /* Defining Data Structures for Per-function Information.  */
@@ -487,10 +1034,17 @@
 
 #define STACK_BOUNDARY 64
 
-#define FUNCTION_BOUNDARY 32
+#define FUNCTION_BOUNDARY \
+  ((NDS32_ALIGN_P () || TARGET_ALIGN_FUNCTION) ? 32 : 16)
 
 #define BIGGEST_ALIGNMENT 64
 
+#define DATA_ALIGNMENT(constant, basic_align) \
+  nds32_data_alignment (constant, basic_align)
+
+#define LOCAL_ALIGNMENT(type, basic_align) \
+  nds32_local_alignment (type, basic_align)
+
 #define EMPTY_FIELD_BOUNDARY 32
 
 #define STRUCTURE_SIZE_BOUNDARY 8
@@ -515,8 +1069,8 @@
 
 #define SIZE_TYPE "long unsigned int"
 #define PTRDIFF_TYPE "long int"
-#define WCHAR_TYPE "short unsigned int"
-#define WCHAR_TYPE_SIZE 16
+#define WCHAR_TYPE "unsigned int"
+#define WCHAR_TYPE_SIZE 32
 
 
 /* Register Usage.  */
@@ -526,7 +1080,7 @@
    from 0 to just below FIRST_PSEUDO_REGISTER.
    All registers that the compiler knows about must be given numbers,
    even those that are not normally considered general registers.  */
-#define FIRST_PSEUDO_REGISTER 34
+#define FIRST_PSEUDO_REGISTER 101
 
 /* An initializer that says which registers are used for fixed
    purposes all throughout the compiled code and are therefore
@@ -537,24 +1091,38 @@
    $r30 : $lp
    $r31 : $sp
 
-   caller-save registers: $r0 ~ $r5, $r16 ~ $r23
-   callee-save registers: $r6 ~ $r10, $r11 ~ $r14
+   caller-save registers: $r0 ~ $r5, $r16 ~ $r23, $fs0 ~ $fs5, $fs22 ~ $fs47
+   callee-save registers: $r6 ~ $r10, $r11 ~ $r14, $fs6 ~ $fs21, $fs48 ~ $fs63
 
    reserved for assembler : $r15
    reserved for other use : $r24, $r25, $r26, $r27 */
-#define FIXED_REGISTERS                 \
-{ /* r0  r1  r2  r3  r4  r5  r6  r7  */ \
-      0,  0,  0,  0,  0,  0,  0,  0,    \
-  /* r8  r9  r10 r11 r12 r13 r14 r15 */ \
-      0,  0,  0,  0,  0,  0,  0,  1,    \
-  /* r16 r17 r18 r19 r20 r21 r22 r23 */ \
-      0,  0,  0,  0,  0,  0,  0,  0,    \
-  /* r24 r25 r26 r27 r28 r29 r30 r31 */ \
-      1,  1,  1,  1,  0,  1,  0,  1,    \
-  /* ARG_POINTER:32 */                  \
-      1,                                \
-  /* FRAME_POINTER:33 */                \
-      1                                 \
+#define FIXED_REGISTERS \
+{ /* r0   r1   r2   r3   r4   r5   r6   r7   */ \
+      0,   0,   0,   0,   0,   0,   0,   0,     \
+  /* r8   r9   r10  r11  r12  r13  r14  r15  */ \
+      0,   0,   0,   0,   0,   0,   0,   1,     \
+  /* r16  r17  r18  r19  r20  r21  r22  r23  */ \
+      0,   0,   0,   0,   0,   0,   0,   0,     \
+  /* r24  r25  r26  r27  r28  r29  r30  r31  */ \
+      1,   1,   1,   1,   0,   1,   0,   1,     \
+  /* AP   FP   fs0  fs1  fs2  fs3  fs4  fs5  */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fs6  fs7  fs8  fs9  fs10 fs11 fs12 fs13 */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fs14 fs15 fs16 fs17 fs18 fs19 fs20 fs21 */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fs22 fs23 fs24 fs25 fs26 fs27 fs28 fs29 */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fs30 fs31 fd16      fd17      fd18      */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fd19      fd20      fd21      fd22      */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fd23      fd24      fd25      fd26      */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fd27      fd28      fd29      fd30      */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fd31      Reserved..................... */ \
+      1,   1,   1,   1,   1                     \
 }
 
 /* Identifies the registers that are not available for
@@ -563,35 +1131,59 @@
 
    0 : callee-save registers
    1 : caller-save registers */
-#define CALL_USED_REGISTERS             \
-{ /* r0  r1  r2  r3  r4  r5  r6  r7  */ \
-      1,  1,  1,  1,  1,  1,  0,  0,    \
-  /* r8  r9  r10 r11 r12 r13 r14 r15 */ \
-      0,  0,  0,  0,  0,  0,  0,  1,    \
-  /* r16 r17 r18 r19 r20 r21 r22 r23 */ \
-      1,  1,  1,  1,  1,  1,  1,  1,    \
-  /* r24 r25 r26 r27 r28 r29 r30 r31 */ \
-      1,  1,  1,  1,  0,  1,  0,  1,    \
-  /* ARG_POINTER:32 */                  \
-      1,                                \
-  /* FRAME_POINTER:33 */                \
-      1                                 \
+#define CALL_USED_REGISTERS \
+{ /* r0   r1   r2   r3   r4   r5   r6   r7   */ \
+      1,   1,   1,   1,   1,   1,   0,   0,     \
+  /* r8   r9   r10  r11  r12  r13  r14  r15  */ \
+      0,   0,   0,   0,   0,   0,   0,   1,     \
+  /* r16  r17  r18  r19  r20  r21  r22  r23  */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* r24  r25  r26  r27  r28  r29  r30  r31  */ \
+      1,   1,   1,   1,   0,   1,   0,   1,     \
+  /* AP   FP   fs0  fs1  fs2  fs3  fs4  fs5  */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fs6  fs7  fs8  fs9  fs10 fs11 fs12 fs13 */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fs14 fs15 fs16 fs17 fs18 fs19 fs20 fs21 */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fs22 fs23 fs24 fs25 fs26 fs27 fs28 fs29 */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fs30 fs31 fd16      fd17      fd18      */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fd19      fd20      fd21      fd22      */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fd23      fd24      fd25      fd26      */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fd27      fd28      fd29      fd30      */ \
+      1,   1,   1,   1,   1,   1,   1,   1,     \
+  /* fd31      Reserved..................... */ \
+      1,   1,   1,   1,   1                     \
 }
 
 /* In nds32 target, we have three levels of registers:
      LOW_COST_REGS    : $r0 ~ $r7
      MIDDLE_COST_REGS : $r8 ~ $r11, $r16 ~ $r19
      HIGH_COST_REGS   : $r12 ~ $r14, $r20 ~ $r31 */
-#define REG_ALLOC_ORDER           \
-{                                 \
-   0,  1,  2,  3,  4,  5,  6,  7, \
-   8,  9, 10, 11, 16, 17, 18, 19, \
-  12, 13, 14, 15, 20, 21, 22, 23, \
-  24, 25, 26, 27, 28, 29, 30, 31, \
-  32,                             \
-  33                              \
+#define REG_ALLOC_ORDER \
+{   0,   1,   2,   3,   4,   5,   6,   7, \
+   16,  17,  18,  19,   9,  10,  11,  12, \
+   13,  14,  8,   15,  20,  21,  22,  23, \
+   24,  25,  26,  27,  28,  29,  30,  31, \
+   32,  33,  34,  35,  36,  37,  38,  39, \
+   40,  41,  42,  43,  44,  45,  46,  47, \
+   48,  49,  50,  51,  52,  53,  54,  55, \
+   56,  57,  58,  59,  60,  61,  62,  63, \
+   64,  65,  66,  67,  68,  69,  70,  71, \
+   72,  73,  74,  75,  76,  77,  78,  79, \
+   80,  81,  82,  83,  84,  85,  86,  87, \
+   88,  89,  90,  91,  92,  93,  94,  95, \
+   96,  97,  98,  99, 100,                \
 }
 
+/* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order
+   to be rearranged based on optimizing for speed or size.  */
+#define ADJUST_REG_ALLOC_ORDER nds32_adjust_reg_alloc_order ()
+
 /* Tell IRA to use the order we define rather than messing it up with its
    own cost calculations.  */
 #define HONOR_REG_ALLOC_ORDER optimize_size
@@ -609,13 +1201,17 @@
 enum reg_class
 {
   NO_REGS,
+  R5_REG,
+  R8_REG,
   R15_TA_REG,
   STACK_REG,
+  FRAME_POINTER_REG,
   LOW_REGS,
   MIDDLE_REGS,
   HIGH_REGS,
   GENERAL_REGS,
   FRAME_REGS,
+  FP_REGS,
   ALL_REGS,
   LIM_REG_CLASSES
 };
@@ -625,27 +1221,47 @@
 #define REG_CLASS_NAMES \
 {                       \
   "NO_REGS",            \
+  "R5_REG",             \
+  "R8_REG",             \
   "R15_TA_REG",         \
   "STACK_REG",          \
+  "FRAME_POINTER_REG",  \
   "LOW_REGS",           \
   "MIDDLE_REGS",        \
   "HIGH_REGS",          \
   "GENERAL_REGS",       \
   "FRAME_REGS",         \
+  "FP_REGS",            \
   "ALL_REGS"            \
 }
 
 #define REG_CLASS_CONTENTS \
-{                                                            \
-  {0x00000000, 0x00000000}, /* NO_REGS     :              */ \
-  {0x00008000, 0x00000000}, /* R15_TA_REG  : 15           */ \
-  {0x80000000, 0x00000000}, /* STACK_REG   : 31           */ \
-  {0x000000ff, 0x00000000}, /* LOW_REGS    : 0-7          */ \
-  {0x000f0fff, 0x00000000}, /* MIDDLE_REGS : 0-11, 16-19  */ \
-  {0xfff07000, 0x00000000}, /* HIGH_REGS   : 12-14, 20-31 */ \
-  {0xffffffff, 0x00000000}, /* GENERAL_REGS: 0-31         */ \
-  {0x00000000, 0x00000003}, /* FRAME_REGS  : 32, 33       */ \
-  {0xffffffff, 0x00000003}  /* ALL_REGS    : 0-31, 32, 33 */ \
+{ /* NO_REGS                                    */  \
+  {0x00000000, 0x00000000, 0x00000000, 0x00000000}, \
+  /* R5_REG              : 5                    */  \
+  {0x00000020, 0x00000000, 0x00000000, 0x00000000}, \
+  /* R8_REG              : 8                    */  \
+  {0x00000100, 0x00000000, 0x00000000, 0x00000000}, \
+  /* R15_TA_REG          : 15                   */  \
+  {0x00008000, 0x00000000, 0x00000000, 0x00000000}, \
+  /* STACK_REG           : 31                   */  \
+  {0x80000000, 0x00000000, 0x00000000, 0x00000000}, \
+  /* FRAME_POINTER_REG   : 28                   */  \
+  {0x10000000, 0x00000000, 0x00000000, 0x00000000}, \
+  /* LOW_REGS            : 0-7                  */  \
+  {0x000000ff, 0x00000000, 0x00000000, 0x00000000}, \
+  /* MIDDLE_REGS         : 0-11, 16-19          */  \
+  {0x000f0fff, 0x00000000, 0x00000000, 0x00000000}, \
+  /* HIGH_REGS           : 12-14, 20-31         */  \
+  {0xfff07000, 0x00000000, 0x00000000, 0x00000000}, \
+  /* GENERAL_REGS        : 0-31                 */  \
+  {0xffffffff, 0x00000000, 0x00000000, 0x00000000}, \
+  /* FRAME_REGS          : 32, 33               */  \
+  {0x00000000, 0x00000003, 0x00000000, 0x00000000}, \
+  /* FP_REGS             : 34-98                */  \
+  {0x00000000, 0xfffffffc, 0xffffffff, 0x00000003}, \
+  /* ALL_REGS            : 0-100                */  \
+  {0xffffffff, 0xffffffff, 0xffffffff, 0x0000001f}  \
 }
 
 #define REGNO_REG_CLASS(regno) nds32_regno_reg_class (regno)
@@ -653,13 +1269,18 @@
 #define BASE_REG_CLASS GENERAL_REGS
 #define INDEX_REG_CLASS GENERAL_REGS
 
+#define TEST_REGNO(R, TEST, VALUE) \
+  ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
+
 /* Return nonzero if it is suitable for use as a
    base register in operand addresses.
    So far, we return nonzero only if "num" is a hard reg
    of the suitable class or a pseudo register which is
    allocated to a suitable hard reg.  */
 #define REGNO_OK_FOR_BASE_P(num) \
-  ((num) < 32 || (unsigned) reg_renumber[num] < 32)
+  (TEST_REGNO (num, <, 32) \
+   || TEST_REGNO (num, ==, FRAME_POINTER_REGNUM) \
+   || TEST_REGNO (num, ==, ARG_POINTER_REGNUM))
 
 /* Return nonzero if it is suitable for use as a
    index register in operand addresses.
@@ -669,7 +1290,9 @@
    The difference between an index register and a base register is that
    the index register may be scaled.  */
 #define REGNO_OK_FOR_INDEX_P(num) \
-  ((num) < 32 || (unsigned) reg_renumber[num] < 32)
+  (TEST_REGNO (num, <, 32) \
+   || TEST_REGNO (num, ==, FRAME_POINTER_REGNUM) \
+   || TEST_REGNO (num, ==, ARG_POINTER_REGNUM))
 
 
 /* Obsolete Macros for Defining Constraints.  */
@@ -686,6 +1309,11 @@
 #define FIRST_PARM_OFFSET(fundecl) \
   (NDS32_DOUBLE_WORD_ALIGN_P (crtl->args.pretend_args_size) ? 0 : 4)
 
+/* A C expression whose value is RTL representing the address in a stack frame
+   where the pointer to the caller's frame is stored.  */
+#define DYNAMIC_CHAIN_ADDRESS(frameaddr) \
+  nds32_dynamic_chain_address (frameaddr)
+
 #define RETURN_ADDR_RTX(count, frameaddr) \
   nds32_return_addr_rtx (count, frameaddr)
 
@@ -697,6 +1325,15 @@
 #define INCOMING_RETURN_ADDR_RTX    gen_rtx_REG (Pmode, LP_REGNUM)
 #define DWARF_FRAME_RETURN_COLUMN   DWARF_FRAME_REGNUM (LP_REGNUM)
 
+/* Use $r0 $r1 to pass exception handling information.  */
+#define EH_RETURN_DATA_REGNO(N) (((N) < 2) ? (N) : INVALID_REGNUM)
+/* The register $r2 that represents a location in which to store a stack
+   adjustment to be applied before function return.
+   This is used to unwind the stack to an exception handler's call frame.  */
+#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 2)
+
+#define DBX_REGISTER_NUMBER(REGNO) nds32_dbx_register_number (REGNO)
+
 #define STACK_POINTER_REGNUM SP_REGNUM
 
 #define FRAME_POINTER_REGNUM 33
@@ -725,12 +1362,11 @@
 #define INIT_CUMULATIVE_ARGS(cum, fntype, libname, fndecl, n_named_args) \
   nds32_init_cumulative_args (&cum, fntype, libname, fndecl, n_named_args)
 
-/* The REGNO is an unsigned integer but NDS32_GPR_ARG_FIRST_REGNUM may be 0.
-   We better cast REGNO into signed integer so that we can avoid
-   'comparison of unsigned expression >= 0 is always true' warning.  */
-#define FUNCTION_ARG_REGNO_P(regno)                                        \
-  (((int) regno - NDS32_GPR_ARG_FIRST_REGNUM >= 0)                         \
-   && ((int) regno - NDS32_GPR_ARG_FIRST_REGNUM < NDS32_MAX_GPR_REGS_FOR_ARGS))
+#define FUNCTION_ARG_REGNO_P(regno)                                           \
+ (IN_RANGE ((regno), NDS32_FIRST_GPR_REGNUM, NDS32_MAX_GPR_REGS_FOR_ARGS - 1) \
+  || ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)                                \
+      && IN_RANGE ((regno), NDS32_FPR_ARG_FIRST_REGNUM,                       \
+		   NDS32_FIRST_FPR_REGNUM + NDS32_MAX_FPR_REGS_FOR_ARGS - 1)))
 
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
@@ -742,7 +1378,15 @@
 #define EXIT_IGNORE_STACK 1
 
 #define FUNCTION_PROFILER(file, labelno) \
-  fprintf (file, "/* profiler %d */", (labelno))
+  fprintf (file, "/* profiler %d */\n", (labelno))
+
+#define PROFILE_HOOK(LABEL)						\
+  {									\
+    rtx fun, lp;							\
+    lp = get_hard_reg_initial_val (Pmode, LP_REGNUM);			\
+    fun = gen_rtx_SYMBOL_REF (Pmode, "_mcount");			\
+    emit_library_call (fun, LCT_NORMAL, VOIDmode, lp, Pmode);		\
+  }
 
 
 /* Implementing the Varargs Macros.  */
@@ -790,9 +1434,15 @@
 /* We have "LW.bi   Rt, [Ra], Rb" instruction form.  */
 #define HAVE_POST_MODIFY_REG  1
 
+#define USE_LOAD_POST_INCREMENT(mode) \
+  nds32_use_load_post_increment(mode)
+#define USE_LOAD_POST_DECREMENT(mode) USE_LOAD_POST_INCREMENT(mode)
+#define USE_STORE_POST_DECREMENT(mode) USE_LOAD_POST_DECREMENT(mode)
+#define USE_STORE_POST_INCREMENT(mode) USE_LOAD_POST_INCREMENT(mode)
+
 #define CONSTANT_ADDRESS_P(x) (CONSTANT_P (x) && GET_CODE (x) != CONST_DOUBLE)
 
-#define MAX_REGS_PER_ADDRESS 2
+#define MAX_REGS_PER_ADDRESS 3
 
 
 /* Anchored Addresses.  */
@@ -806,7 +1456,11 @@
 /* A C expression for the cost of a branch instruction.
    A value of 1 is the default;
    other values are interpreted relative to that.  */
-#define BRANCH_COST(speed_p, predictable_p) ((speed_p) ? 2 : 0)
+#define BRANCH_COST(speed_p, predictable_p) ((speed_p) ? 2 : 1)
+
+/* Override BRANCH_COST heuristic which empirically produces worse
+   performance for removing short circuiting from the logical ops.  */
+#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
 
 #define SLOW_BYTE_ACCESS 1
 
@@ -836,12 +1490,17 @@
 
 #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.  */
 
 #define ASM_COMMENT_START "!"
 
-#define ASM_APP_ON "! #APP"
+#define ASM_APP_ON "! #APP\n"
 
 #define ASM_APP_OFF "! #NO_APP\n"
 
@@ -856,14 +1515,77 @@
 
 #define LOCAL_LABEL_PREFIX "."
 
-#define REGISTER_NAMES                                            \
-{                                                                 \
-  "$r0",  "$r1",  "$r2",  "$r3",  "$r4",  "$r5",  "$r6",  "$r7",  \
+#define REGISTER_NAMES \
+{ "$r0",  "$r1",  "$r2",  "$r3",  "$r4",  "$r5",  "$r6",  "$r7",  \
   "$r8",  "$r9",  "$r10", "$r11", "$r12", "$r13", "$r14", "$ta",  \
   "$r16", "$r17", "$r18", "$r19", "$r20", "$r21", "$r22", "$r23", \
   "$r24", "$r25", "$r26", "$r27", "$fp",  "$gp",  "$lp",  "$sp",  \
-  "$AP",                                                          \
-  "$SFP"                                                          \
+  "$AP",  "$SFP", "$fs0", "$fs1", "$fs2", "$fs3", "$fs4", "$fs5", \
+  "$fs6", "$fs7", "$fs8", "$fs9", "$fs10","$fs11","$fs12","$fs13",\
+  "$fs14","$fs15","$fs16","$fs17","$fs18","$fs19","$fs20","$fs21",\
+  "$fs22","$fs23","$fs24","$fs25","$fs26","$fs27","$fs28","$fs29",\
+  "$fs30","$fs31","$fs32","$fs33","$fs34","$fs35","$fs36","$fs37",\
+  "$fs38","$fs39","$fs40","$fs41","$fs42","$fs43","$fs44","$fs45",\
+  "$fs46","$fs47","$fs48","$fs49","$fs50","$fs51","$fs52","$fs53",\
+  "$fs54","$fs55","$fs56","$fs57","$fs58","$fs59","$fs60","$fs61",\
+  "$fs62","$fs63",   "LB",   "LE",   "LC"                         \
+}
+
+#define ADDITIONAL_REGISTER_NAMES				\
+{								\
+  {"$r15", 15},							\
+  {"$r28", 28},	{"$r29", 29},	{"$r30", 30},	{"$r31", 31},	\
+  {"$a0", 0},	{"$a1", 1},	{"$a2", 2},			\
+  {"$a3", 3},	{"$a4", 4},	{"$a5", 5},			\
+  {"$s0", 6},	{"$s1", 7},	{"$s2", 8},	{"$s3", 9},	\
+  {"$s4", 10},	{"$s5", 11},	{"$s6", 12},	{"$s7", 13},	\
+  {"$s8", 14},							\
+  {"$t0", 16},	{"$t1", 17},	{"$t2", 18},	{"$t3", 19},	\
+  {"$t4", 20},	{"$t5", 21},	{"$t6", 22},	{"$t7", 23},	\
+  {"$t8", 24},	{"$t9", 25},					\
+  {"$p0", 26},	{"$p1", 27},					\
+  {"$h0", 0},	{"$h1", 1},	{"$h2", 2},	{"$h3", 3},	\
+  {"$h4", 4},	{"$h5", 5},	{"$h6", 6},	{"$h7", 7},	\
+  {"$h8", 8},	{"$h9", 9},	{"$h10", 10},	{"$h11", 11},	\
+  {"$h12", 16},	{"$h13", 17},	{"$h14", 18},	{"$h15", 19},	\
+  {"$o0", 0},	{"$o1", 1},	{"$o2", 2},	{"$o3", 3},	\
+  {"$o4", 4},	{"$o5", 5},	{"$o6", 6},	{"$o7", 7},	\
+}
+
+#define OVERLAPPING_REGISTER_NAMES		\
+{						\
+  {"$fd0",  NDS32_FIRST_FPR_REGNUM + 0,  2},	\
+  {"$fd1",  NDS32_FIRST_FPR_REGNUM + 2,  2},	\
+  {"$fd2",  NDS32_FIRST_FPR_REGNUM + 4,  2},	\
+  {"$fd3",  NDS32_FIRST_FPR_REGNUM + 6,  2},	\
+  {"$fd4",  NDS32_FIRST_FPR_REGNUM + 8,  2},	\
+  {"$fd5",  NDS32_FIRST_FPR_REGNUM + 10, 2},	\
+  {"$fd6",  NDS32_FIRST_FPR_REGNUM + 12, 2},	\
+  {"$fd7",  NDS32_FIRST_FPR_REGNUM + 14, 2},	\
+  {"$fd8",  NDS32_FIRST_FPR_REGNUM + 16, 2},	\
+  {"$fd9",  NDS32_FIRST_FPR_REGNUM + 18, 2},	\
+  {"$fd10", NDS32_FIRST_FPR_REGNUM + 20, 2},	\
+  {"$fd11", NDS32_FIRST_FPR_REGNUM + 22, 2},	\
+  {"$fd12", NDS32_FIRST_FPR_REGNUM + 24, 2},	\
+  {"$fd13", NDS32_FIRST_FPR_REGNUM + 26, 2},	\
+  {"$fd14", NDS32_FIRST_FPR_REGNUM + 28, 2},	\
+  {"$fd15", NDS32_FIRST_FPR_REGNUM + 30, 2},	\
+  {"$fd16", NDS32_FIRST_FPR_REGNUM + 32, 2},	\
+  {"$fd17", NDS32_FIRST_FPR_REGNUM + 34, 2},	\
+  {"$fd18", NDS32_FIRST_FPR_REGNUM + 36, 2},	\
+  {"$fd19", NDS32_FIRST_FPR_REGNUM + 38, 2},	\
+  {"$fd20", NDS32_FIRST_FPR_REGNUM + 40, 2},	\
+  {"$fd21", NDS32_FIRST_FPR_REGNUM + 42, 2},	\
+  {"$fd22", NDS32_FIRST_FPR_REGNUM + 44, 2},	\
+  {"$fd23", NDS32_FIRST_FPR_REGNUM + 46, 2},	\
+  {"$fd24", NDS32_FIRST_FPR_REGNUM + 48, 2},	\
+  {"$fd25", NDS32_FIRST_FPR_REGNUM + 50, 2},	\
+  {"$fd26", NDS32_FIRST_FPR_REGNUM + 52, 2},	\
+  {"$fd27", NDS32_FIRST_FPR_REGNUM + 54, 2},	\
+  {"$fd28", NDS32_FIRST_FPR_REGNUM + 56, 2},	\
+  {"$fd29", NDS32_FIRST_FPR_REGNUM + 58, 2},	\
+  {"$fd30", NDS32_FIRST_FPR_REGNUM + 60, 2},	\
+  {"$fd31", NDS32_FIRST_FPR_REGNUM + 62, 2},	\
 }
 
 /* Output normal jump table entry.  */
@@ -918,13 +1640,16 @@
 #define DWARF2_UNWIND_INFO 1
 
 #define JUMP_ALIGN(x) \
-  (align_jumps_log ? align_jumps_log : nds32_target_alignment (x))
+  (align_jumps.levels[0].log \
+   ? align_jumps : align_flags (nds32_target_alignment (x)))
 
 #define LOOP_ALIGN(x) \
-  (align_loops_log ? align_loops_log : nds32_target_alignment (x))
+  (align_loops.levels[0].log \
+   ? align_loops : align_flags (nds32_target_alignment (x)))
 
 #define LABEL_ALIGN(x) \
-  (align_labels_log ? align_labels_log : nds32_target_alignment (x))
+  (align_labels.levels[0].log \
+   ? align_labels : align_flags (nds32_target_alignment (x)))
 
 #define ASM_OUTPUT_ALIGN(stream, power) \
   fprintf (stream, "\t.align\t%d\n", power)
@@ -971,9 +1696,7 @@
 /* Return the preferred mode for and addr_diff_vec when the mininum
    and maximum offset are known.  */
 #define CASE_VECTOR_SHORTEN_MODE(min_offset, max_offset, body)  \
-   ((min_offset < 0 || max_offset >= 0x2000 ) ? SImode          \
-   : (max_offset >= 100) ? HImode                               \
-   : QImode)
+  nds32_case_vector_shorten_mode (min_offset, max_offset, body)
 
 /* Generate pc relative jump table when -fpic or -Os.  */
 #define CASE_VECTOR_PC_RELATIVE (flag_pic || optimize_size)
@@ -1001,6 +1724,11 @@
    when the condition is true.  */
 #define STORE_FLAG_VALUE 1
 
+/* A C expression that indicates whether the architecture defines a value for
+   clz or ctz with a zero operand.  In nds32 clz for 0 result 32 is defined
+   in ISA spec */
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
+
 /* An alias for the machine mode for pointers.  */
 #define Pmode SImode