diff gcc/config/nds32/nds32-intrinsic.md @ 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-intrinsic.md	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/config/nds32/nds32-intrinsic.md	Thu Oct 25 07:37:49 2018 +0900
@@ -1,5 +1,5 @@
 ;; Intrinsic patterns description 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.
@@ -40,6 +40,26 @@
    (set_attr "length"    "4")]
 )
 
+(define_expand "mtsr_isb"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(match_operand:SI 1 "immediate_operand" ""))]
+  ""
+{
+  emit_insn (gen_unspec_volatile_mtsr (operands[0], operands[1]));
+  emit_insn (gen_unspec_volatile_isb());
+  DONE;
+})
+
+(define_expand "mtsr_dsb"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(match_operand:SI 1 "immediate_operand" ""))]
+  ""
+{
+  emit_insn (gen_unspec_volatile_mtsr (operands[0], operands[1]));
+  emit_insn (gen_unspec_dsb());
+  DONE;
+})
+
 (define_insn "unspec_volatile_mtsr"
   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
 			(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MTSR)]
@@ -58,6 +78,74 @@
    (set_attr "length"    "4")]
 )
 
+;; FPU Register Transfer.
+
+(define_insn "unspec_fcpynsd"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+	 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
+		     (match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYNSD))]
+  ""
+  "fcpynsd\t%0, %1, %2"
+  [(set_attr "type"   "misc")
+   (set_attr "length"    "4")]
+)
+
+(define_insn "unspec_fcpynss"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+	 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
+		     (match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYNSS))]
+  ""
+  "fcpynss\t%0, %1, %2"
+  [(set_attr "type"   "misc")
+   (set_attr "length"    "4")]
+)
+
+(define_insn "unspec_fcpysd"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+	 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
+		     (match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYSD))]
+  ""
+  "fcpysd\t%0, %1, %2"
+  [(set_attr "type"   "misc")
+   (set_attr "length"    "4")]
+)
+
+(define_insn "unspec_fcpyss"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+	 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
+		     (match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYSS))]
+  ""
+  "fcpyss\t%0, %1, %2"
+  [(set_attr "type"   "misc")
+   (set_attr "length"    "4")]
+)
+
+(define_insn "unspec_fmfcsr"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+	 (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCSR))]
+  ""
+  "fmfcsr\t%0"
+  [(set_attr "type"   "misc")
+   (set_attr "length"    "4")]
+)
+
+(define_insn "unspec_fmtcsr"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_FMTCSR)]
+  ""
+  "fmtcsr\t%0"
+  [(set_attr "type"   "misc")
+   (set_attr "length"    "4")]
+)
+
+(define_insn "unspec_fmfcfg"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCFG))]
+  ""
+  "fmfcfg\t%0"
+  [(set_attr "type"   "misc")
+   (set_attr "length"    "4")]
+)
+
 ;; ------------------------------------------------------------------------
 
 ;; Interrupt Instructions.
@@ -76,6 +164,445 @@
   [(set_attr "type" "misc")]
 )
 
+(define_expand "unspec_enable_int"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_ENABLE_INT)]
+  ""
+{
+  rtx system_reg;
+  rtx temp_reg = gen_reg_rtx (SImode);
+
+  /* Set system register form nds32_intrinsic_register_names[].  */
+  if ((INTVAL (operands[0]) >= NDS32_INT_H16)
+      && (INTVAL (operands[0]) <= NDS32_INT_H31))
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_MASK2__);
+      operands[0] = GEN_INT (1 << (INTVAL (operands[0])));
+    }
+  else if ((INTVAL (operands[0]) >= NDS32_INT_H32)
+	   && (INTVAL (operands[0]) <= NDS32_INT_H63))
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_MASK3__);
+      operands[0] = GEN_INT (1 << (INTVAL (operands[0]) - 32));
+    }
+  else
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_MASK__);
+
+      if (INTVAL (operands[0]) == NDS32_INT_SWI)
+        operands[0] = GEN_INT (1 << 16);
+      else if ((INTVAL (operands[0]) >= NDS32_INT_ALZ)
+	       && (INTVAL (operands[0]) <= NDS32_INT_DSSIM))
+	operands[0] = GEN_INT (1 << (INTVAL (operands[0]) - 4));
+      else
+	operands[0] = GEN_INT (1 << (INTVAL (operands[0])));
+    }
+
+  emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
+  emit_insn (gen_iorsi3 (temp_reg, temp_reg, operands[0]));
+  emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+  emit_insn (gen_unspec_dsb ());
+  DONE;
+})
+
+(define_expand "unspec_disable_int"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_DISABLE_INT)]
+  ""
+{
+  rtx system_reg;
+  rtx temp_reg = gen_reg_rtx (SImode);
+
+  /* Set system register form nds32_intrinsic_register_names[].  */
+  if ((INTVAL (operands[0]) >= NDS32_INT_H16)
+      && (INTVAL (operands[0]) <= NDS32_INT_H31))
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_MASK2__);
+      operands[0] = GEN_INT (~(1 << INTVAL (operands[0])));
+    }
+  else if ((INTVAL (operands[0]) >= NDS32_INT_H32)
+	   && (INTVAL (operands[0]) <= NDS32_INT_H63))
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_MASK3__);
+      operands[0] = GEN_INT (~(1 << (INTVAL (operands[0]) - 32)));
+    }
+  else
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_MASK__);
+
+      if (INTVAL (operands[0]) == NDS32_INT_SWI)
+        operands[0] = GEN_INT (~(1 << 16));
+      else if ((INTVAL (operands[0]) >= NDS32_INT_ALZ)
+	       && (INTVAL (operands[0]) <= NDS32_INT_DSSIM))
+	operands[0] = GEN_INT (~(1 << (INTVAL (operands[0]) - 4)));
+      else
+	operands[0] = GEN_INT (~(1 << INTVAL (operands[0])));
+    }
+
+  emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
+  emit_insn (gen_andsi3 (temp_reg, temp_reg, operands[0]));
+  emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+  emit_insn (gen_unspec_dsb ());
+  DONE;
+})
+
+(define_expand "unspec_set_pending_swint"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SET_PENDING_SWINT)]
+  ""
+{
+  /* Get $INT_PEND system register form nds32_intrinsic_register_names[]  */
+  rtx system_reg =  GEN_INT (__NDS32_REG_INT_PEND__);
+  rtx temp_reg = gen_reg_rtx (SImode);
+
+  emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
+  emit_insn (gen_iorsi3 (temp_reg, temp_reg, GEN_INT (65536)));
+  emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+  emit_insn (gen_unspec_dsb ());
+  DONE;
+})
+
+(define_expand "unspec_clr_pending_swint"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLR_PENDING_SWINT)]
+  ""
+{
+  /* Get $INT_PEND system register form nds32_intrinsic_register_names[]  */
+  rtx system_reg =  GEN_INT (__NDS32_REG_INT_PEND__);
+  rtx temp_reg = gen_reg_rtx (SImode);
+
+  emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
+  emit_insn (gen_andsi3 (temp_reg, temp_reg, GEN_INT (~(1 << 16))));
+  emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+  emit_insn (gen_unspec_dsb ());
+  DONE;
+})
+
+(define_expand "unspec_clr_pending_hwint"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_CLR_PENDING_HWINT)]
+  ""
+{
+  rtx system_reg = NULL_RTX;
+  rtx temp_reg = gen_reg_rtx (SImode);
+  rtx clr_hwint;
+  unsigned offset = 0;
+
+  /* Set system register form nds32_intrinsic_register_names[].  */
+  if ((INTVAL (operands[0]) >= NDS32_INT_H0)
+      && (INTVAL (operands[0]) <= NDS32_INT_H15))
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
+    }
+  else if ((INTVAL (operands[0]) >= NDS32_INT_H16)
+	   && (INTVAL (operands[0]) <= NDS32_INT_H31))
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_PEND2__);
+    }
+  else if ((INTVAL (operands[0]) >= NDS32_INT_H32)
+	   && (INTVAL (operands[0]) <= NDS32_INT_H63))
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_PEND3__);
+      offset = 32;
+    }
+  else
+    error ("__nds32__clr_pending_hwint not support NDS32_INT_SWI,"
+	   " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
+
+  /* $INT_PEND type is write one clear.  */
+  clr_hwint = GEN_INT (1 << (INTVAL (operands[0]) - offset));
+
+  if (system_reg != NULL_RTX)
+    {
+      emit_move_insn (temp_reg, clr_hwint);
+      emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+      emit_insn (gen_unspec_dsb ());
+    }
+  DONE;
+})
+
+(define_expand "unspec_get_all_pending_int"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_GET_ALL_PENDING_INT))]
+  ""
+{
+  rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
+  emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
+  emit_insn (gen_unspec_dsb ());
+  DONE;
+})
+
+(define_expand "unspec_get_pending_int"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_PENDING_INT))]
+  ""
+{
+  rtx system_reg = NULL_RTX;
+
+  /* Set system register form nds32_intrinsic_register_names[].  */
+  if ((INTVAL (operands[1]) >= NDS32_INT_H0)
+      && (INTVAL (operands[1]) <= NDS32_INT_H15))
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
+      operands[2] = GEN_INT (31 - INTVAL (operands[1]));
+    }
+  else if (INTVAL (operands[1]) == NDS32_INT_SWI)
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
+      operands[2] = GEN_INT (15);
+    }
+  else if ((INTVAL (operands[1]) >= NDS32_INT_H16)
+	   && (INTVAL (operands[1]) <= NDS32_INT_H31))
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_PEND2__);
+      operands[2] = GEN_INT (31 - INTVAL (operands[1]));
+    }
+  else if ((INTVAL (operands[1]) >= NDS32_INT_H32)
+	   && (INTVAL (operands[1]) <= NDS32_INT_H63))
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_PEND3__);
+      operands[2] = GEN_INT (31 - (INTVAL (operands[1]) - 32));
+    }
+  else
+    error ("get_pending_int not support NDS32_INT_ALZ,"
+	   " NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
+
+  /* mfsr op0, sytem_reg  */
+  if (system_reg != NULL_RTX)
+    {
+      emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
+      emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
+      emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
+      emit_insn (gen_unspec_dsb ());
+    }
+  DONE;
+})
+
+(define_expand "unspec_set_int_priority"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")
+			(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_SET_INT_PRIORITY)]
+  ""
+{
+  rtx system_reg = NULL_RTX;
+  rtx priority = NULL_RTX;
+  rtx mask = NULL_RTX;
+  rtx temp_reg = gen_reg_rtx (SImode);
+  rtx mask_reg = gen_reg_rtx (SImode);
+  rtx set_reg = gen_reg_rtx (SImode);
+  unsigned offset = 0;
+
+  /* Get system register form nds32_intrinsic_register_names[].  */
+  if (INTVAL (operands[0]) <= NDS32_INT_H15)
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_PRI__);
+      offset = 0;
+    }
+  else if (INTVAL (operands[0]) >= NDS32_INT_H16
+	   && INTVAL (operands[0]) <= NDS32_INT_H31)
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_PRI2__);
+      /* The $INT_PRI2 first bit correspond to H16, so need
+	 subtract 16.  */
+      offset = 16;
+    }
+  else if (INTVAL (operands[0]) >= NDS32_INT_H32
+	   && INTVAL (operands[0]) <= NDS32_INT_H47)
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_PRI3__);
+      /* The $INT_PRI3 first bit correspond to H32, so need
+	 subtract 32.  */
+      offset = 32;
+    }
+  else if (INTVAL (operands[0]) >= NDS32_INT_H48
+	   && INTVAL (operands[0]) <= NDS32_INT_H63)
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_PRI4__);
+      /* The $INT_PRI3 first bit correspond to H48, so need
+	 subtract 48.  */
+      offset = 48;
+    }
+  else
+    error ("set_int_priority not support NDS32_INT_SWI,"
+	   " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
+
+  mask = GEN_INT (~(3 << 2 * (INTVAL (operands[0]) - offset)));
+  priority = GEN_INT ((int) (INTVAL (operands[1])
+			     << ((INTVAL (operands[0]) - offset) * 2)));
+
+  if (system_reg != NULL_RTX)
+    {
+      emit_move_insn (mask_reg, mask);
+      emit_move_insn (set_reg, priority);
+      emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
+      emit_insn (gen_andsi3 (temp_reg, temp_reg, mask_reg));
+      emit_insn (gen_iorsi3 (temp_reg, temp_reg, set_reg));
+      emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+      emit_insn (gen_unspec_dsb ());
+    }
+  DONE;
+})
+
+(define_expand "unspec_get_int_priority"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_INT_PRIORITY))]
+  ""
+{
+  rtx system_reg = NULL_RTX;
+  rtx priority = NULL_RTX;
+  unsigned offset = 0;
+
+  /* Get system register form nds32_intrinsic_register_names[]  */
+  if (INTVAL (operands[1]) <= NDS32_INT_H15)
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_PRI__);
+      offset = 0;
+    }
+  else if (INTVAL (operands[1]) >= NDS32_INT_H16
+	   && INTVAL (operands[1]) <= NDS32_INT_H31)
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_PRI2__);
+      /* The $INT_PRI2 first bit correspond to H16, so need
+	 subtract 16.  */
+      offset = 16;
+    }
+  else if (INTVAL (operands[1]) >= NDS32_INT_H32
+	   && INTVAL (operands[1]) <= NDS32_INT_H47)
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_PRI3__);
+      /* The $INT_PRI3 first bit correspond to H32, so need
+	 subtract 32.  */
+      offset = 32;
+    }
+  else if (INTVAL (operands[1]) >= NDS32_INT_H48
+	   && INTVAL (operands[1]) <= NDS32_INT_H63)
+    {
+      system_reg =  GEN_INT (__NDS32_REG_INT_PRI4__);
+      /* The $INT_PRI4 first bit correspond to H48, so need
+	 subtract 48.  */
+      offset = 48;
+    }
+  else
+    error ("set_int_priority not support NDS32_INT_SWI,"
+	   " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
+
+  priority = GEN_INT (31 - 2 * (INTVAL (operands[1]) - offset));
+
+  if (system_reg != NULL_RTX)
+    {
+      emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
+      emit_insn (gen_ashlsi3 (operands[0], operands[0], priority));
+      emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (30)));
+      emit_insn (gen_unspec_dsb ());
+    }
+  DONE;
+})
+
+(define_expand "unspec_set_trig_level"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_SET_TRIG_LEVEL)]
+  ""
+{
+  rtx system_reg = NULL_RTX;
+  rtx temp_reg = gen_reg_rtx (SImode);
+  rtx set_level;
+  unsigned offset = 0;
+
+  if (INTVAL (operands[0]) >= NDS32_INT_H0
+      && INTVAL (operands[0]) <= NDS32_INT_H31)
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__);
+      offset = 0;
+    }
+  else if (INTVAL (operands[0]) >= NDS32_INT_H32
+	   && INTVAL (operands[0]) <= NDS32_INT_H63)
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__);
+      offset = 32;
+    }
+  else
+    error ("__nds32__set_trig_type_level not support NDS32_INT_SWI,"
+	   " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
+
+  if (system_reg != NULL_RTX)
+    {
+      /* TRIGGER register, 0 mean level triggered and 1 mean edge triggered. */
+      set_level = GEN_INT (~(1 << (INTVAL (operands[0]) - offset)));
+
+      emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
+      emit_insn (gen_andsi3 (temp_reg, temp_reg, set_level));
+      emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+    }
+  DONE;
+})
+
+(define_expand "unspec_set_trig_edge"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_SET_TRIG_EDGE)]
+  ""
+{
+  rtx system_reg = NULL_RTX;
+  rtx temp_reg = gen_reg_rtx (SImode);
+  rtx set_level;
+  unsigned offset = 0;
+
+  if (INTVAL (operands[0]) >= NDS32_INT_H0
+      && INTVAL (operands[0]) <= NDS32_INT_H31)
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__);
+      offset = 0;
+    }
+  else if (INTVAL (operands[0]) >= NDS32_INT_H32
+	   && INTVAL (operands[0]) <= NDS32_INT_H63)
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__);
+      offset = 32;
+    }
+  else
+    error ("__nds32__set_trig_type_edge not support NDS32_INT_SWI,"
+	   " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
+
+  if (system_reg != NULL_RTX)
+    {
+      /* TRIGGER register, 0 mean level triggered and 1 mean edge triggered. */
+      set_level = GEN_INT ((1 << (INTVAL (operands[0]) - offset)));
+
+      emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
+      emit_insn (gen_iorsi3 (temp_reg, temp_reg, set_level));
+      emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+    }
+  DONE;
+})
+
+(define_expand "unspec_get_trig_type"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_TRIG_TYPE))]
+  ""
+{
+  rtx system_reg = NULL_RTX;
+  rtx trig_type;
+  unsigned offset = 0;
+
+  if (INTVAL (operands[1]) >= NDS32_INT_H0
+      && INTVAL (operands[1]) <= NDS32_INT_H31)
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__);
+      offset = 0;
+    }
+  else if (INTVAL (operands[1]) >= NDS32_INT_H32
+	   && INTVAL (operands[1]) <= NDS32_INT_H63)
+    {
+      system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__);
+      offset = 32;
+    }
+  else
+    error ("__nds32__get_trig_type not support NDS32_INT_SWI,"
+	   " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
+
+  if (system_reg != NULL_RTX)
+    {
+      trig_type = GEN_INT (31 - (INTVAL (operands[1]) - offset));
+
+      emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
+      emit_insn (gen_ashlsi3 (operands[0], operands[0], trig_type));
+      emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
+      emit_insn (gen_unspec_dsb ());
+    }
+  DONE;
+})
+
 ;; ------------------------------------------------------------------------
 
 ;; Cache Synchronization Instructions
@@ -94,4 +621,1065 @@
   [(set_attr "type" "misc")]
 )
 
+(define_insn "unspec_dsb"
+  [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_DSB)]
+  ""
+  "dsb"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_msync"
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_MSYNC)]
+  ""
+  "msync\t%0"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_msync_all"
+  [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_MSYNC_ALL)]
+  ""
+  "msync\tall"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_msync_store"
+  [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_MSYNC_STORE)]
+  ""
+  "msync\tstore"
+  [(set_attr "type" "misc")]
+)
+
+;; Load and Store
+
+(define_insn "unspec_volatile_llw"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
+					      (match_operand:SI 2 "register_operand" "r")))] UNSPEC_VOLATILE_LLW))]
+  ""
+  "llw\t%0, [%1 + %2]"
+  [(set_attr "length"    "4")]
+)
+
+(define_insn "unspec_lwup"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
+					      (match_operand:SI 2 "register_operand" "r")))] UNSPEC_LWUP))]
+  ""
+  "lwup\t%0, [%1 + %2]"
+  [(set_attr "length"    "4")]
+)
+
+(define_insn "unspec_lbup"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
+					      (match_operand:SI 2 "register_operand" "r")))] UNSPEC_LBUP))]
+  ""
+  "lbup\t%0, [%1 + %2]"
+  [(set_attr "length"    "4")]
+)
+
+(define_insn "unspec_volatile_scw"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
+					      (match_operand:SI 2 "register_operand" "r")))
+			     (match_operand:SI 3 "register_operand" "0")] UNSPEC_VOLATILE_SCW))]
+  ""
+  "scw\t%0, [%1 + %2]"
+  [(set_attr "length"     "4")]
+)
+
+(define_insn "unspec_swup"
+  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
+			 (match_operand:SI 1 "register_operand" "r")))
+	(unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SWUP))]
+  ""
+  "swup\t%2, [%0 + %1]"
+  [(set_attr "length"     "4")]
+)
+
+(define_insn "unspec_sbup"
+  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
+			 (match_operand:SI 1 "register_operand" "r")))
+	(unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SBUP))]
+  ""
+  "sbup\t%2, [%0 + %1]"
+  [(set_attr "length"     "4")]
+)
+
+;; CCTL
+
+(define_insn "cctl_l1d_invalall"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_INVALALL)]
+  ""
+  "cctl\tL1D_INVALALL"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "cctl_l1d_wball_alvl"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ALVL)]
+  ""
+  "cctl\tL1D_WBALL, alevel"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "cctl_l1d_wball_one_lvl"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ONE_LVL)]
+  ""
+  "cctl\tL1D_WBALL, 1level"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "cctl_idx_read"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")
+			     (match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_READ))]
+  ""
+  "cctl\t%0, %2, %X1"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "cctl_idx_write"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
+			(match_operand:SI 1 "register_operand" "r")
+			(match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WRITE)]
+  ""
+  "cctl\t%1, %2, %W0"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "cctl_va_wbinval_l1"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
+			(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_L1)]
+  ""
+  "cctl\t%1, %U0, 1level"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "cctl_va_wbinval_la"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
+			(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_LA)]
+  ""
+  "cctl\t%1, %U0, alevel"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "cctl_idx_wbinval"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
+			(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WBINVAL)]
+  ""
+  "cctl\t%1, %T0"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "cctl_va_lck"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
+			(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_LCK)]
+  ""
+  "cctl\t%1, %R0"
+  [(set_attr "type" "mmu")]
+)
+
+;;PREFETCH
+
+(define_insn "prefetch_qw"
+  [(unspec_volatile:QI [(match_operand:SI 0 "register_operand" "r")
+			(match_operand:SI 1 "nonmemory_operand" "r")
+			(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_DPREF_QW)]
+  ""
+  "dpref\t%Z2, [%0 + %1]"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "prefetch_hw"
+  [(unspec_volatile:HI [(match_operand:SI 0 "register_operand" "r")
+			(match_operand:SI 1 "nonmemory_operand" "r")
+			(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_DPREF_HW)]
+  ""
+  "dpref\t%Z2, [%0 + (%1<<1)]"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "prefetch_w"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "    r, r")
+			(match_operand:SI 1 "nonmemory_operand" "Is15, r")
+			(match_operand:SI 2 "immediate_operand" "   i, i")] UNSPEC_VOLATILE_DPREF_W)]
+  ""
+  "@
+  dprefi.w\t%Z2, [%0 + %1]
+  dpref\t%Z2, [%0 + (%1<<2)]"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "prefetch_dw"
+  [(unspec_volatile:DI [(match_operand:SI 0 "register_operand"  "   r, r")
+			(match_operand:SI 1 "nonmemory_operand" "Is15, r")
+			(match_operand:SI 2 "immediate_operand" "   i, i")] UNSPEC_VOLATILE_DPREF_DW)]
+  ""
+  "@
+  dprefi.d\t%Z2, [%0 + %1]
+  dpref\t%Z2, [%0 + (%1<<3)]"
+  [(set_attr "type" "misc")]
+)
+
+;; Performance Extension
+
+(define_expand "unspec_ave"
+  [(match_operand:SI 0 "register_operand" "")
+   (match_operand:SI 1 "register_operand" "")
+   (match_operand:SI 2 "register_operand" "")]
+  ""
+{
+  emit_insn (gen_ave (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_expand "unspec_bclr"
+  [(match_operand:SI 0 "register_operand" "")
+   (match_operand:SI 1 "register_operand" "")
+   (match_operand:SI 2 "immediate_operand" "")]
+  ""
+{
+  unsigned HOST_WIDE_INT val = ~(1u << UINTVAL (operands[2]));
+  emit_insn (gen_andsi3 (operands[0], operands[1], gen_int_mode (val, SImode)));
+  DONE;
+})
+
+(define_expand "unspec_bset"
+  [(match_operand:SI 0 "register_operand" "")
+   (match_operand:SI 1 "register_operand" "")
+   (match_operand:SI 2 "immediate_operand" "")]
+  ""
+{
+  unsigned HOST_WIDE_INT val = 1u << UINTVAL (operands[2]);
+  emit_insn (gen_iorsi3 (operands[0], operands[1], gen_int_mode (val, SImode)));
+  DONE;
+})
+
+(define_expand "unspec_btgl"
+  [(match_operand:SI 0 "register_operand" "")
+   (match_operand:SI 1 "register_operand" "")
+   (match_operand:SI 2 "immediate_operand" "")]
+  ""
+{
+  unsigned HOST_WIDE_INT val = 1u << UINTVAL (operands[2]);
+  emit_insn (gen_xorsi3 (operands[0], operands[1], gen_int_mode (val, SImode)));
+  DONE;
+})
+
+(define_expand "unspec_btst"
+  [(match_operand:SI 0 "register_operand" "")
+   (match_operand:SI 1 "register_operand" "")
+   (match_operand:SI 2 "immediate_operand" "")]
+  ""
+{
+  emit_insn (gen_btst (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_insn "unspec_clip"
+  [(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))]
+  ""
+  "clip\t%0, %1, %2"
+  [(set_attr "type" "alu")
+   (set_attr "length" "4")]
+)
+
+(define_insn "unspec_clips"
+  [(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))]
+  ""
+  "clips\t%0, %1, %2"
+  [(set_attr "type" "alu")
+   (set_attr "length" "4")]
+)
+
+(define_insn "unspec_clo"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_CLO))]
+  ""
+  "clo\t%0, %1"
+  [(set_attr "type" "alu")
+   (set_attr "length" "4")]
+)
+
+(define_insn "unspec_ssabssi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ss_abs:SI (match_operand:SI 1 "register_operand" "r")))]
+  ""
+  "abs\t%0, %1"
+  [(set_attr "type" "alu")
+   (set_attr "length" "4")]
+)
+
+;; Performance extension 2
+
+(define_insn "unspec_pbsad"
+  [(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_PBSAD))]
+  ""
+  "pbsad\t%0, %1, %2"
+  [(set_attr "type" "pbsad")
+   (set_attr "length"   "4")]
+)
+
+(define_insn "unspec_pbsada"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "0")
+		    (match_operand:SI 2 "register_operand" "r")
+		    (match_operand:SI 3 "register_operand" "r")] UNSPEC_PBSADA))]
+  ""
+  "pbsada\t%0, %2, %3"
+  [(set_attr "type" "pbsada")
+   (set_attr "length"    "4")]
+)
+
+(define_expand "bse"
+  [(match_operand:SI 0 "register_operand" "")
+   (match_operand:SI 1 "register_operand" "")
+   (match_operand:SI 2 "register_operand" "")]
+  ""
+  {
+    rtx temp0 = gen_reg_rtx (SImode);
+    rtx temp2 = gen_reg_rtx (SImode);
+
+    emit_move_insn (temp0, gen_rtx_MEM (Pmode, operands[0]));
+    emit_move_insn (temp2, gen_rtx_MEM (Pmode, operands[2]));
+    emit_insn (gen_unspec_bse (temp0, operands[1], temp2, temp0, temp2));
+    emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp0);
+    emit_move_insn (gen_rtx_MEM (Pmode, operands[2]), temp2);
+    DONE;
+  }
+)
+
+(define_insn "unspec_bse"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
+		    (match_operand:SI 2 "register_operand" "r")
+		    (match_operand:SI 3 "register_operand" "0")] UNSPEC_BSE))
+   (set (match_operand:SI 4 "register_operand" "=2")
+	(unspec:SI [(match_dup 1)
+		    (match_dup 2)
+		    (match_dup 0)] UNSPEC_BSE_2))]
+  ""
+  "bse\t%0, %1, %2"
+  [(set_attr "type" "alu")
+   (set_attr "length" "4")]
+)
+
+(define_expand "bsp"
+  [(match_operand:SI 0 "register_operand" "")
+   (match_operand:SI 1 "register_operand" "")
+   (match_operand:SI 2 "register_operand" "")]
+  ""
+  {
+    rtx temp0 = gen_reg_rtx (SImode);
+    rtx temp2 = gen_reg_rtx (SImode);
+
+    emit_move_insn (temp0, gen_rtx_MEM (Pmode, operands[0]));
+    emit_move_insn (temp2, gen_rtx_MEM (Pmode, operands[2]));
+    emit_insn (gen_unspec_bsp (temp0, operands[1], temp2, temp0, temp2));
+    emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp0);
+    emit_move_insn (gen_rtx_MEM (Pmode, operands[2]), temp2);
+    DONE;
+  }
+)
+
+(define_insn "unspec_bsp"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
+		    (match_operand:SI 2 "register_operand" "r")
+		    (match_operand:SI 3 "register_operand" "0")] UNSPEC_BSP))
+   (set (match_operand:SI 4 "register_operand" "=2")
+	(unspec:SI [(match_dup 1)
+		    (match_dup 2)
+		    (match_dup 0)] UNSPEC_BSP_2))]
+  ""
+  "bsp\t%0, %1, %2"
+  [(set_attr "type" "alu")
+   (set_attr "length" "4")]
+)
+
+;; String Extension
+
+(define_insn "unspec_ffb"
+  [(set (match_operand:SI 0 "register_operand" "=r, r")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "r, r")
+		    (match_operand:SI 2 "nonmemory_operand" "Iu08, r")] UNSPEC_FFB))]
+  ""
+  "@
+  ffbi\t%0, %1, %2
+  ffb\t%0, %1, %2"
+  [(set_attr "type" "alu")
+   (set_attr "length" "4")]
+)
+
+(define_insn "unspec_ffmism"
+  [(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_FFMISM))]
+  ""
+  "ffmism\t%0, %1, %2"
+  [(set_attr "type" "alu")
+   (set_attr "length" "4")]
+)
+
+(define_insn "unspec_flmism"
+  [(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_FLMISM))]
+  ""
+  "flmism\t%0, %1, %2"
+  [(set_attr "type" "alu")
+   (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"
+  [(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_SVA))]
+  ""
+  "sva\t%0, %1, %2"
+  [(set_attr "type"    "alu")
+   (set_attr "length"    "4")]
+)
+
+(define_insn "unspec_svs"
+  [(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_SVS))]
+  ""
+  "svs\t%0, %1, %2"
+  [(set_attr "type"    "alu")
+   (set_attr "length"    "4")]
+)
+
+(define_insn "unspec_jr_itoff"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JR_ITOFF)]
+  ""
+  "jr.itoff\t%0"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_jr_toff"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JR_TOFF)]
+  ""
+  "jr.toff\t%0"
+  [(set_attr "type" "branch")]
+)
+
+(define_insn "unspec_jral_iton"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JRAL_ITON)]
+  ""
+  "jral.iton\t%0"
+  [(set_attr "type" "branch")]
+)
+
+(define_insn "unspec_jral_ton"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JRAL_TON)]
+  ""
+  "jral.ton\t%0"
+  [(set_attr "type" "branch")]
+)
+
+(define_insn "unspec_ret_itoff"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_RET_ITOFF)]
+  ""
+  "ret.itoff\t%0"
+  [(set_attr "type" "branch")]
+)
+
+(define_insn "unspec_ret_toff"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_RET_TOFF)]
+  ""
+  "ret.toff\t%0"
+  [(set_attr "type" "branch")]
+)
+
+(define_insn "unspec_standby_no_wake_grant"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_NO_WAKE_GRANT)]
+  ""
+  "standby\tno_wake_grant"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_standby_wake_grant"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_WAKE_GRANT)]
+  ""
+  "standby\twake_grant"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_standby_wait_done"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_WAKE_DONE)]
+  ""
+  "standby\twait_done"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_teqz"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
+			(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_TEQZ)]
+  ""
+  "teqz\t%0, %1"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_tnez"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
+			(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_TNEZ)]
+  ""
+  "tnez\t%0, %1"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_trap"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_TRAP)]
+  ""
+  "trap\t%0"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_setend_big"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETEND_BIG)]
+  ""
+  "setend.b"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_setend_little"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETEND_LITTLE)]
+  ""
+  "setend.l"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_break"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_BREAK)]
+  ""
+  "break\t%0"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_syscall"
+  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_SYSCALL)]
+  ""
+  "syscall\t%0"
+  [(set_attr "type" "misc")]
+)
+
+(define_insn "unspec_nop"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_NOP)]
+  ""
+  "nop"
+  [(set_attr "type" "misc")]
+)
+
+(define_expand "unspec_get_current_sp"
+  [(match_operand:SI 0 "register_operand" "")]
+  ""
+{
+  emit_move_insn (operands[0], gen_rtx_REG (SImode, SP_REGNUM));
+  DONE;
+})
+
+(define_expand "unspec_set_current_sp"
+  [(match_operand:SI 0 "register_operand" "")]
+  ""
+{
+  emit_move_insn (gen_rtx_REG (SImode, SP_REGNUM), operands[0]);
+  DONE;
+})
+
+(define_expand "unspec_return_address"
+  [(match_operand:SI 0 "register_operand" "")]
+  ""
+{
+  emit_move_insn (operands[0], gen_rtx_REG (SImode, LP_REGNUM));
+  DONE;
+})
+
+;; Swap
+
+(define_insn "unspec_wsbh"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_WSBH))]
+  ""
+  "wsbh\t%0, %1"
+  [(set_attr "type"    "alu")
+   (set_attr "length"    "4")]
+)
+
+;; TLBOP Intrinsic
+
+(define_insn "unspec_tlbop_trd"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TRD)]
+  ""
+  "tlbop\t%0, TRD"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "unspec_tlbop_twr"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TWR)]
+  ""
+  "tlbop\t%0, TWR"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "unspec_tlbop_rwr"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWR)]
+  ""
+  "tlbop\t%0, RWR"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "unspec_tlbop_rwlk"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWLK)]
+  ""
+  "tlbop\t%0, RWLK"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "unspec_tlbop_unlk"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_UNLK)]
+  ""
+  "tlbop\t%0, UNLK"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "unspec_tlbop_pb"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_PB))]
+  ""
+  "tlbop\t%0, %1, PB"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "unspec_tlbop_inv"
+  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_INV)]
+  ""
+  "tlbop\t%0, INV"
+  [(set_attr "type" "mmu")]
+)
+
+(define_insn "unspec_tlbop_flua"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_TLBOP_FLUA)]
+  ""
+  "tlbop\tFLUA"
+  [(set_attr "type" "mmu")]
+)
+
+;;Unaligned Load/Store
+
+(define_expand "unaligned_load_hw"
+  [(set (match_operand:HI 0 "register_operand" "")
+	(unspec:HI [(mem:HI (match_operand:SI 1 "register_operand" ""))] UNSPEC_UALOAD_HW))]
+  ""
+{
+  operands[0] = simplify_gen_subreg (SImode, operands[0],
+				     GET_MODE (operands[0]), 0);
+  if (TARGET_ISA_V3M)
+    {
+      nds32_expand_unaligned_load (operands, HImode);
+    }
+  else
+    {
+      emit_insn (gen_unaligned_load_w (operands[0],
+				       gen_rtx_MEM (SImode, operands[1])));
+
+      if (WORDS_BIG_ENDIAN)
+	emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT(16)));
+      else
+	emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0xffff)));
+    }
+
+  DONE;
+})
+
+(define_expand "unaligned_loadsi"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_W))]
+  ""
+{
+  if (flag_unaligned_access)
+    {
+      rtx mem = gen_rtx_MEM (SImode, operands[1]);
+      emit_move_insn (operands[0], mem);
+    }
+  else
+    {
+      if (TARGET_ISA_V3M)
+	nds32_expand_unaligned_load (operands, SImode);
+      else
+	emit_insn (gen_unaligned_load_w (operands[0],
+					 gen_rtx_MEM (SImode, (operands[1]))));
+    }
+  DONE;
+})
+
+(define_insn "unaligned_load_w"
+  [(set (match_operand:SI 0 "register_operand"                       "=  r")
+	(unspec:SI [(match_operand:SI 1 "nds32_lmw_smw_base_operand" " Umw")] UNSPEC_UALOAD_W))]
+  ""
+{
+  return nds32_output_lmw_single_word (operands);
+}
+  [(set_attr "type"   "load")
+   (set_attr "length"    "4")]
+)
+
+(define_expand "unaligned_loaddi"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))]
+  ""
+{
+  if (TARGET_ISA_V3M)
+    {
+      nds32_expand_unaligned_load (operands, DImode);
+    }
+  else
+    emit_insn (gen_unaligned_load_dw (operands[0], operands[1]));
+  DONE;
+})
+
+(define_insn "unaligned_load_dw"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))]
+  ""
+{
+  rtx otherops[3];
+  otherops[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
+  otherops[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
+  otherops[2] = operands[1];
+
+  output_asm_insn ("lmw.bi\t%0, [%2], %1, 0", otherops);
+  return "";
+}
+  [(set_attr "type"   "load")
+   (set_attr "length"    "4")]
+)
+
+(define_expand "unaligned_store_hw"
+  [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
+	(unspec:HI [(match_operand:HI 1 "register_operand" "")] UNSPEC_UASTORE_HW))]
+  ""
+{
+  operands[1] = simplify_gen_subreg (SImode, operands[1],
+				     GET_MODE (operands[1]), 0);
+  nds32_expand_unaligned_store (operands, HImode);
+  DONE;
+})
+
+(define_expand "unaligned_storesi"
+  [(set (mem:SI (match_operand:SI 0 "register_operand" "r"))
+	(unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_UASTORE_W))]
+  ""
+{
+  if (flag_unaligned_access)
+    {
+      rtx mem = gen_rtx_MEM (SImode, operands[0]);
+      emit_move_insn (mem, operands[1]);
+    }
+  else
+    {
+      if (TARGET_ISA_V3M)
+	nds32_expand_unaligned_store (operands, SImode);
+      else
+	emit_insn (gen_unaligned_store_w (gen_rtx_MEM (SImode, operands[0]),
+					  operands[1]));
+    }
+  DONE;
+})
+
+(define_insn "unaligned_store_w"
+  [(set (match_operand:SI 0 "nds32_lmw_smw_base_operand"   "=Umw")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "   r")] UNSPEC_UASTORE_W))]
+  ""
+{
+  return nds32_output_smw_single_word (operands);
+}
+  [(set_attr "type"   "store")
+   (set_attr "length"     "4")]
+)
+
+(define_expand "unaligned_storedi"
+  [(set (mem:DI (match_operand:SI 0 "register_operand" "r"))
+	(unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_UASTORE_DW))]
+  ""
+{
+  if (TARGET_ISA_V3M)
+    nds32_expand_unaligned_store (operands, DImode);
+  else
+    emit_insn (gen_unaligned_store_dw (gen_rtx_MEM (DImode, operands[0]),
+				       operands[1]));
+  DONE;
+})
+
+(define_insn "unaligned_store_dw"
+  [(set (match_operand:DI 0 "nds32_lmw_smw_base_operand"   "=Umw")
+	(unspec:DI [(match_operand:DI 1 "register_operand" "   r")] UNSPEC_UASTORE_DW))]
+  ""
+{
+  return nds32_output_smw_double_word (operands);
+}
+  [(set_attr "type"   "store")
+   (set_attr "length"     "4")]
+)
+
+(define_expand "unspec_unaligned_feature"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE))]
+  ""
+{
+  /* Get $MMU_CTL system register form nds32_intrinsic_register_names[]  */
+  rtx system_reg =  GEN_INT (__NDS32_REG_MMU_CTL__);
+  rtx temp_reg = gen_reg_rtx (SImode);
+  rtx temp2_reg = gen_reg_rtx (SImode);
+
+  emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
+  emit_move_insn (temp_reg, operands[0]);
+  emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
+  emit_insn (gen_iorsi3 (operands[0], operands[0], temp2_reg));
+  emit_insn (gen_unspec_volatile_mtsr (operands[0], system_reg));
+  emit_insn (gen_unspec_dsb ());
+
+  emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
+  emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+  emit_insn (gen_unspec_dsb ());
+
+  emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (8)));
+  emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
+  DONE;
+})
+
+(define_expand "unspec_enable_unaligned"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)]
+  ""
+{
+  /* Get $MMU_CTL system register form nds32_intrinsic_register_names[]  */
+  rtx system_reg =  GEN_INT (__NDS32_REG_MMU_CTL__);
+  rtx temp_reg = gen_reg_rtx (SImode);
+  rtx temp2_reg = gen_reg_rtx (SImode);
+  emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
+  emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
+  emit_insn (gen_iorsi3 (temp_reg, temp_reg, temp2_reg));
+  emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+  emit_insn (gen_unspec_dsb ());
+  DONE;
+})
+
+(define_expand "unspec_disable_unaligned"
+  [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)]
+  ""
+{
+  /* Get $MMU_CTL system register form nds32_intrinsic_register_names[]  */
+  rtx system_reg =  GEN_INT (__NDS32_REG_MMU_CTL__);
+  rtx temp_reg = gen_reg_rtx (SImode);
+  rtx temp2_reg = gen_reg_rtx (SImode);
+  emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
+  emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
+  emit_insn (gen_one_cmplsi2 (temp2_reg, temp2_reg));
+  emit_insn (gen_andsi3 (temp_reg, temp_reg, temp2_reg));
+  emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
+  emit_insn (gen_unspec_dsb ());
+  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")]
+)
+
 ;; ------------------------------------------------------------------------