[NDS32] Add intrinsic functions for particular instructions.
authorMonk Chiang <sh.chiang04@gmail.com>
Sat, 7 Apr 2018 08:16:41 +0000 (08:16 +0000)
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>
Sat, 7 Apr 2018 08:16:41 +0000 (08:16 +0000)
gcc/
* config/nds32/constants.md (unspec_element, unspec_volatile_element):
Add enum values for particular instructions.
* config/nds32/nds32-intrinsic.c: Implementation of expanding
particular intrinsic functions.
* config/nds32/nds32-intrinsic.md: Likewise.
* config/nds32/nds32_intrinsic.h: Likewise.
* config/nds32/nds32.h (nds32_builtins): Likewise.
* config/nds32/nds32.md (type): Add pbsad and pbsada.
(btst, ave): New patterns for particular instructions.

From-SVN: r259208

gcc/ChangeLog
gcc/config/nds32/constants.md
gcc/config/nds32/nds32-intrinsic.c
gcc/config/nds32/nds32-intrinsic.md
gcc/config/nds32/nds32.h
gcc/config/nds32/nds32.md
gcc/config/nds32/nds32_intrinsic.h

index ffc87d710327ab369d2a3a77b6394cadb8d65dc6..cba352564296a5169f4d5ad6f20876687ac42690 100644 (file)
@@ -1,3 +1,15 @@
+2018-04-07  Monk Chiang  <sh.chiang04@gmail.com>
+
+       * config/nds32/constants.md (unspec_element, unspec_volatile_element):
+       Add enum values for particular instructions.
+       * config/nds32/nds32-intrinsic.c: Implementation of expanding
+       particular intrinsic functions.
+       * config/nds32/nds32-intrinsic.md: Likewise.
+       * config/nds32/nds32_intrinsic.h: Likewise.
+       * config/nds32/nds32.h (nds32_builtins): Likewise.
+       * config/nds32/nds32.md (type): Add pbsad and pbsada.
+       (btst, ave): New patterns for particular instructions.
+
 2018-04-07  Monk Chiang  <sh.chiang04@gmail.com>
 
        * config/nds32/constants.md (unspec_element, unspec_volatile_element):
index 77d96892102579bb5227b6d302eeaf639d22f04d..3facf5ba898814dadc99113aefd61839202ed76a 100644 (file)
   UNSPEC_FCPYNSS
   UNSPEC_FCPYSD
   UNSPEC_FCPYSS
+  UNSPEC_CLIP
+  UNSPEC_CLIPS
+  UNSPEC_CLO
+  UNSPEC_PBSAD
+  UNSPEC_PBSADA
+  UNSPEC_BSE
+  UNSPEC_BSE_2
+  UNSPEC_BSP
+  UNSPEC_BSP_2
   UNSPEC_FFB
   UNSPEC_FFMISM
   UNSPEC_FLMISM
+  UNSPEC_SVA
+  UNSPEC_SVS
+  UNSPEC_WSBH
   UNSPEC_LWUP
   UNSPEC_LBUP
   UNSPEC_SWUP
   UNSPEC_VOLATILE_FMFCSR
   UNSPEC_VOLATILE_FMTCSR
   UNSPEC_VOLATILE_FMFCFG
+  UNSPEC_VOLATILE_JR_ITOFF
+  UNSPEC_VOLATILE_JR_TOFF
+  UNSPEC_VOLATILE_JRAL_ITON
+  UNSPEC_VOLATILE_JRAL_TON
+  UNSPEC_VOLATILE_RET_ITOFF
+  UNSPEC_VOLATILE_RET_TOFF
+  UNSPEC_VOLATILE_STANDBY_NO_WAKE_GRANT
+  UNSPEC_VOLATILE_STANDBY_WAKE_GRANT
+  UNSPEC_VOLATILE_STANDBY_WAKE_DONE
+  UNSPEC_VOLATILE_TEQZ
+  UNSPEC_VOLATILE_TNEZ
+  UNSPEC_VOLATILE_TRAP
+  UNSPEC_VOLATILE_SETEND_BIG
+  UNSPEC_VOLATILE_SETEND_LITTLE
+  UNSPEC_VOLATILE_BREAK
+  UNSPEC_VOLATILE_SYSCALL
+  UNSPEC_VOLATILE_NOP
   UNSPEC_VOLATILE_LLW
   UNSPEC_VOLATILE_SCW
   UNSPEC_VOLATILE_CCTL_L1D_INVALALL
index fb67e6fe5d546fd91d9bbf3313e3a771e0c9543e..49b03f3f7409db2167e6ab889695b0fd7f6118e7 100644 (file)
@@ -239,6 +239,72 @@ nds32_expand_binop_builtin (enum insn_code icode, tree exp, rtx target,
   return target;
 }
 
+/* Expand builtins that take two operands and the second is immediate.  */
+static rtx
+nds32_expand_binopimm_builtin (enum insn_code icode, tree exp, rtx target,
+                              bool return_p, const char *name)
+{
+  rtx pat;
+  rtx op0 = nds32_read_argument (exp, 0);
+  rtx op1 = nds32_read_argument (exp, 1);
+  int op0_num = return_p ? 1 : 0;
+  int op1_num = return_p ? 2 : 1;
+
+  if (return_p)
+    target = nds32_legitimize_target (icode, target);
+
+  if (!nds32_check_constant_argument (icode, op1_num, op1, name))
+    return NULL_RTX;
+
+  op0 = nds32_legitimize_argument (icode, op0_num, op0);
+  op1 = nds32_legitimize_argument (icode, op1_num, op1);
+
+  /* Emit and return the new instruction. */
+  if (return_p)
+    pat = GEN_FCN (icode) (target, op0, op1);
+  else
+    pat = GEN_FCN (icode) (op0, op1);
+
+  if (! pat)
+    return NULL_RTX;
+
+  emit_insn (pat);
+  return target;
+}
+
+/* Expand builtins that take three operands.  */
+static rtx
+nds32_expand_triop_builtin (enum insn_code icode, tree exp, rtx target,
+                           bool return_p)
+{
+  rtx pat;
+  rtx op0 = nds32_read_argument (exp, 0);
+  rtx op1 = nds32_read_argument (exp, 1);
+  rtx op2 = nds32_read_argument (exp, 2);
+  int op0_num = return_p ? 1 : 0;
+  int op1_num = return_p ? 2 : 1;
+  int op2_num = return_p ? 3 : 2;
+
+  if (return_p)
+    target = nds32_legitimize_target (icode, target);
+
+  op0 = nds32_legitimize_argument (icode, op0_num, op0);
+  op1 = nds32_legitimize_argument (icode, op1_num, op1);
+  op2 = nds32_legitimize_argument (icode, op2_num, op2);
+
+  /* Emit and return the new instruction. */
+  if (return_p)
+    pat = GEN_FCN (icode) (target, op0, op1, op2);
+  else
+    pat = GEN_FCN (icode) (op0, op1, op2);
+
+  if (! pat)
+    return NULL_RTX;
+
+  emit_insn (pat);
+  return target;
+}
+
 /* Expand builtins for load.  */
 static rtx
 nds32_expand_builtin_load (enum insn_code icode, tree exp, rtx target)
@@ -386,16 +452,30 @@ static struct builtin_description bdesc_noarg[] =
 {
   NDS32_BUILTIN(unspec_fmfcfg, "fmfcfg", FMFCFG)
   NDS32_BUILTIN(unspec_fmfcsr, "fmfcsr", FMFCSR)
+  NDS32_BUILTIN(unspec_get_current_sp, "get_current_sp", GET_CURRENT_SP)
+  NDS32_BUILTIN(unspec_return_address, "return_address", RETURN_ADDRESS)
 };
 
 /* Intrinsics that take just one argument.  */
 static struct builtin_description bdesc_1arg[] =
 {
+  NDS32_BUILTIN(unspec_ssabssi2, "abs", ABS)
+  NDS32_BUILTIN(clzsi2, "clz", CLZ)
+  NDS32_BUILTIN(unspec_clo, "clo", CLO)
+  NDS32_BUILTIN(unspec_wsbh, "wsbh", WSBH)
   NDS32_BUILTIN(unaligned_load_hw, "unaligned_load_hw", UALOAD_HW)
   NDS32_BUILTIN(unaligned_loadsi, "unaligned_load_w", UALOAD_W)
   NDS32_BUILTIN(unaligned_loaddi, "unaligned_load_dw", UALOAD_DW)
   NDS32_NO_TARGET_BUILTIN(unspec_volatile_isync, "isync", ISYNC)
   NDS32_NO_TARGET_BUILTIN(unspec_fmtcsr, "fmtcsr", FMTCSR)
+  NDS32_NO_TARGET_BUILTIN(unspec_jr_itoff, "jr_itoff", JR_ITOFF)
+  NDS32_NO_TARGET_BUILTIN(unspec_jr_toff, "jr_toff", JR_TOFF)
+  NDS32_NO_TARGET_BUILTIN(unspec_jral_ton, "jral_ton", JRAL_TON)
+  NDS32_NO_TARGET_BUILTIN(unspec_ret_toff, "ret_toff", RET_TOFF)
+  NDS32_NO_TARGET_BUILTIN(unspec_jral_iton, "jral_iton",JRAL_ITON)
+  NDS32_NO_TARGET_BUILTIN(unspec_ret_itoff, "ret_itoff", RET_ITOFF)
+  NDS32_NO_TARGET_BUILTIN(unspec_set_current_sp,
+                         "set_current_sp", SET_CURRENT_SP)
 };
 
 /* Intrinsics that take just one argument. and the argument is immediate.  */
@@ -403,6 +483,9 @@ static struct builtin_description bdesc_1argimm[] =
 {
   NDS32_BUILTIN(unspec_volatile_mfsr, "mfsr", MFSR)
   NDS32_BUILTIN(unspec_volatile_mfusr, "mfsr", MFUSR)
+  NDS32_NO_TARGET_BUILTIN(unspec_trap, "trap", TRAP)
+  NDS32_NO_TARGET_BUILTIN(unspec_break, "break", BREAK)
+  NDS32_NO_TARGET_BUILTIN(unspec_syscall, "syscall", SYSCALL)
 };
 
 /* Intrinsics that take two arguments.  */
@@ -412,9 +495,14 @@ static struct builtin_description bdesc_2arg[] =
   NDS32_BUILTIN(unspec_fcpyss, "fcpyss", FCPYSS)
   NDS32_BUILTIN(unspec_fcpynsd, "fcpynsd", FCPYNSD)
   NDS32_BUILTIN(unspec_fcpysd, "fcpysd", FCPYSD)
+  NDS32_BUILTIN(unspec_ave, "ave", AVE)
+  NDS32_BUILTIN(unspec_pbsad, "pbsad", PBSAD)
   NDS32_BUILTIN(unspec_ffb, "ffb", FFB)
   NDS32_BUILTIN(unspec_ffmism, "ffmsim", FFMISM)
   NDS32_BUILTIN(unspec_flmism, "flmism", FLMISM)
+  NDS32_BUILTIN(rotrsi3, "rotr", ROTR)
+  NDS32_BUILTIN(unspec_sva, "sva", SVA)
+  NDS32_BUILTIN(unspec_svs, "svs", SVS)
   NDS32_NO_TARGET_BUILTIN(mtsr_isb, "mtsr_isb", MTSR_ISB)
   NDS32_NO_TARGET_BUILTIN(mtsr_dsb, "mtsr_dsb", MTSR_DSB)
   NDS32_NO_TARGET_BUILTIN(unspec_volatile_mtsr, "mtsr", MTSR)
@@ -425,6 +513,27 @@ static struct builtin_description bdesc_2arg[] =
 
 };
 
+/* Two-argument intrinsics with an immediate second argument.  */
+static struct builtin_description bdesc_2argimm[] =
+{
+  NDS32_BUILTIN(unspec_bclr, "bclr", BCLR)
+  NDS32_BUILTIN(unspec_bset, "bset", BSET)
+  NDS32_BUILTIN(unspec_btgl, "btgl", BTGL)
+  NDS32_BUILTIN(unspec_btst, "btst", BTST)
+  NDS32_BUILTIN(unspec_clip, "clip", CLIP)
+  NDS32_BUILTIN(unspec_clips, "clips", CLIPS)
+  NDS32_NO_TARGET_BUILTIN(unspec_teqz, "teqz", TEQZ)
+  NDS32_NO_TARGET_BUILTIN(unspec_tnez, "tnez", TNEZ)
+};
+
+/* Intrinsics that take three arguments.  */
+static struct builtin_description bdesc_3arg[] =
+{
+  NDS32_BUILTIN(unspec_pbsada, "pbsada", PBSADA)
+  NDS32_NO_TARGET_BUILTIN(bse, "bse", BSE)
+  NDS32_NO_TARGET_BUILTIN(bsp, "bsp", BSP)
+};
+
 /* Intrinsics that load a value.  */
 static struct builtin_description bdesc_load[] =
 {
@@ -508,6 +617,38 @@ nds32_expand_builtin_impl (tree exp,
          return NULL_RTX;
        }
       break;
+
+    /* Performance Extension  */
+    case NDS32_BUILTIN_ABS:
+    case NDS32_BUILTIN_AVE:
+    case NDS32_BUILTIN_BCLR:
+    case NDS32_BUILTIN_BSET:
+    case NDS32_BUILTIN_BTGL:
+    case NDS32_BUILTIN_BTST:
+    case NDS32_BUILTIN_CLIP:
+    case NDS32_BUILTIN_CLIPS:
+    case NDS32_BUILTIN_CLZ:
+    case NDS32_BUILTIN_CLO:
+      if (!TARGET_EXT_PERF)
+       {
+         error ("don't support performance extension instructions");
+         return NULL_RTX;
+       }
+      break;
+
+    /* Performance Extension 2  */
+    case NDS32_BUILTIN_PBSAD:
+    case NDS32_BUILTIN_PBSADA:
+    case NDS32_BUILTIN_BSE:
+    case NDS32_BUILTIN_BSP:
+      if (!TARGET_EXT_PERF2)
+       {
+         error ("don't support performance extension "
+                "version 2 instructions");
+         return NULL_RTX;
+       }
+      break;
+
     /* String Extension  */
     case NDS32_BUILTIN_FFB:
     case NDS32_BUILTIN_FFMISM:
@@ -540,9 +681,12 @@ nds32_expand_builtin_impl (tree exp,
       return target;
     case NDS32_BUILTIN_SETGIE_EN:
       emit_insn (gen_unspec_volatile_setgie_en ());
+      emit_insn (gen_unspec_dsb ());
       return target;
     case NDS32_BUILTIN_SETGIE_DIS:
       emit_insn (gen_unspec_volatile_setgie_dis ());
+      emit_insn (gen_unspec_dsb ());
+      return target;
     case NDS32_BUILTIN_CCTL_L1D_INVALALL:
       emit_insn (gen_cctl_l1d_invalall());
       return target;
@@ -552,6 +696,27 @@ nds32_expand_builtin_impl (tree exp,
     case NDS32_BUILTIN_CCTL_L1D_WBALL_ONE_LVL:
       emit_insn (gen_cctl_l1d_wball_one_lvl());
       return target;
+    case NDS32_BUILTIN_STANDBY_NO_WAKE_GRANT:
+      emit_insn (gen_unspec_standby_no_wake_grant ());
+      return target;
+    case NDS32_BUILTIN_STANDBY_WAKE_GRANT:
+      emit_insn (gen_unspec_standby_wake_grant ());
+      return target;
+    case NDS32_BUILTIN_STANDBY_WAKE_DONE:
+      emit_insn (gen_unspec_standby_wait_done ());
+      return target;
+    case NDS32_BUILTIN_SETEND_BIG:
+      emit_insn (gen_unspec_setend_big ());
+      return target;
+    case NDS32_BUILTIN_SETEND_LITTLE:
+      emit_insn (gen_unspec_setend_little ());
+      return target;
+    case NDS32_BUILTIN_NOP:
+      emit_insn (gen_unspec_nop ());
+      return target;
+    case NDS32_BUILTIN_SCHE_BARRIER:
+      emit_insn (gen_blockage ());
+      return target;
     case NDS32_BUILTIN_SCW:
       return nds32_expand_scw_builtin (CODE_FOR_unspec_volatile_scw,
                                       exp, target);
@@ -578,6 +743,15 @@ nds32_expand_builtin_impl (tree exp,
     if (d->code == fcode)
       return nds32_expand_binop_builtin (d->icode, exp, target, d->return_p);
 
+  for (i = 0, d = bdesc_2argimm; i < ARRAY_SIZE (bdesc_2argimm); i++, d++)
+    if (d->code == fcode)
+      return nds32_expand_binopimm_builtin (d->icode, exp, target,
+                                           d->return_p, d->name);
+
+  for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
+    if (d->code == fcode)
+      return nds32_expand_triop_builtin (d->icode, exp, target, d->return_p);
+
   for (i = 0, d = bdesc_load; i < ARRAY_SIZE (bdesc_load); i++, d++)
     if (d->code == fcode)
       return nds32_expand_builtin_load (d->icode, exp, target);
@@ -702,6 +876,63 @@ nds32_init_builtins_impl (void)
   ADD_NDS32_BUILTIN3 ("cctl_idx_write", void, integer, unsigned, unsigned,
                      CCTL_IDX_WRITE);
 
+  /* Performance Extension  */
+  ADD_NDS32_BUILTIN1 ("pe_abs", integer, integer, ABS);
+  ADD_NDS32_BUILTIN2 ("pe_ave", integer, integer, integer, AVE);
+  ADD_NDS32_BUILTIN2 ("pe_bclr", unsigned, unsigned, unsigned, BCLR);
+  ADD_NDS32_BUILTIN2 ("pe_bset", unsigned, unsigned, unsigned, BSET);
+  ADD_NDS32_BUILTIN2 ("pe_btgl", unsigned, unsigned, unsigned, BTGL);
+  ADD_NDS32_BUILTIN2 ("pe_btst", unsigned, unsigned, unsigned, BTST);
+  ADD_NDS32_BUILTIN2 ("pe_clip", unsigned, integer, unsigned, CLIP);
+  ADD_NDS32_BUILTIN2 ("pe_clips", integer, integer, unsigned, CLIPS);
+  ADD_NDS32_BUILTIN1 ("pe_clz", unsigned, unsigned, CLZ);
+  ADD_NDS32_BUILTIN1 ("pe_clo", unsigned, unsigned, CLO);
+
+  /* Performance Extension 2  */
+  ADD_NDS32_BUILTIN3 ("pe2_bse", void, ptr_uint, unsigned, ptr_uint, BSE);
+  ADD_NDS32_BUILTIN3 ("pe2_bsp", void, ptr_uint, unsigned, ptr_uint, BSP);
+  ADD_NDS32_BUILTIN2 ("pe2_pbsad", unsigned, unsigned, unsigned, PBSAD);
+  ADD_NDS32_BUILTIN3 ("pe2_pbsada", unsigned, unsigned, unsigned, unsigned,
+                     PBSADA);
+
+  /* String Extension  */
+  ADD_NDS32_BUILTIN2 ("se_ffb", integer, unsigned, unsigned, FFB);
+  ADD_NDS32_BUILTIN2 ("se_ffmism", integer, unsigned, unsigned, FFMISM);
+  ADD_NDS32_BUILTIN2 ("se_flmism", integer, unsigned, unsigned, FLMISM);
+
+
+  /* ROTR  */
+  ADD_NDS32_BUILTIN2 ("rotr", unsigned, unsigned, unsigned, ROTR);
+
+  /* Swap  */
+  ADD_NDS32_BUILTIN1 ("wsbh", unsigned, unsigned, WSBH);
+
+  /* System  */
+  ADD_NDS32_BUILTIN2 ("svs", unsigned, integer, integer, SVS);
+  ADD_NDS32_BUILTIN2 ("sva", unsigned, integer, integer, SVA);
+  ADD_NDS32_BUILTIN1 ("jr_itoff", void, unsigned, JR_ITOFF);
+  ADD_NDS32_BUILTIN1 ("jr_toff", void, unsigned, JR_TOFF);
+  ADD_NDS32_BUILTIN1 ("jral_iton", void, unsigned, JRAL_ITON);
+  ADD_NDS32_BUILTIN1 ("jral_ton", void, unsigned, JRAL_TON);
+  ADD_NDS32_BUILTIN1 ("ret_itoff", void, unsigned, RET_ITOFF);
+  ADD_NDS32_BUILTIN1 ("ret_toff", void, unsigned, RET_TOFF);
+  ADD_NDS32_BUILTIN0 ("standby_no_wake_grant", void, STANDBY_NO_WAKE_GRANT);
+  ADD_NDS32_BUILTIN0 ("standby_wake_grant", void, STANDBY_WAKE_GRANT);
+  ADD_NDS32_BUILTIN0 ("standby_wait_done", void, STANDBY_WAKE_DONE);
+  ADD_NDS32_BUILTIN1 ("break", void, unsigned, BREAK);
+  ADD_NDS32_BUILTIN1 ("syscall", void, unsigned, SYSCALL);
+  ADD_NDS32_BUILTIN0 ("nop", void, NOP);
+  ADD_NDS32_BUILTIN0 ("get_current_sp", unsigned, GET_CURRENT_SP);
+  ADD_NDS32_BUILTIN1 ("set_current_sp", void, unsigned, SET_CURRENT_SP);
+  ADD_NDS32_BUILTIN2 ("teqz", void, unsigned, unsigned, TEQZ);
+  ADD_NDS32_BUILTIN2 ("tnez", void, unsigned, unsigned, TNEZ);
+  ADD_NDS32_BUILTIN1 ("trap", void, unsigned, TRAP);
+  ADD_NDS32_BUILTIN0 ("return_address", unsigned, RETURN_ADDRESS);
+  ADD_NDS32_BUILTIN0 ("setend_big", void, SETEND_BIG);
+  ADD_NDS32_BUILTIN0 ("setend_little", void, SETEND_LITTLE);
+
+  /* Schedule Barrier */
+  ADD_NDS32_BUILTIN0 ("schedule_barrier", void, SCHE_BARRIER);
   /* Unaligned Load/Store  */
   ADD_NDS32_BUILTIN1 ("unaligned_load_hw", short_unsigned, ptr_ushort,
                      UALOAD_HW);
index 5b58fc9229af1bbc4f833d970f4e865968605d2f..52437a47e61ff41ea284077fc90346f4bdc4fc05 100644 (file)
   "cctl\t%1, %R0"
   [(set_attr "type" "mmu")]
 )
+
+
+;; 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_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")]
+)
 ;;Unaligned Load/Store
 
 (define_expand "unaligned_load_hw"
index 8f1ac32c704ab777154a374d800818fd34636cc8..f0518e0566dcc9e3834a713d2fcdf39b08ae503e 100644 (file)
@@ -454,9 +454,51 @@ enum nds32_builtins
   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_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,
index 428d8164af27a4af4d09321a9d2b82e98d2e82cf..99731fecb7abc2737d606c45bf95e394df199092 100644 (file)
@@ -55,7 +55,7 @@
 
 ;; Insn type, it is used to default other attribute values.
 (define_attr "type"
-  "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,mul,mac,div,branch,mmu,misc,\
+  "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,pbsad,pbsada,mul,mac,div,branch,mmu,misc,\
    falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore"
   (const_string "unknown"))
 
   [(set_attr "type" "alu")
    (set_attr "length" "4")])
 
-(define_insn "*btst"
-  [(set (match_operand:SI 0 "register_operand"                   "=   r")
-       (zero_extract:SI (match_operand:SI 1 "register_operand"  "    r")
+(define_insn "btst"
+  [(set (match_operand:SI 0 "register_operand"                     "=   r")
+       (zero_extract:SI (match_operand:SI 1 "register_operand"    "    r")
                         (const_int 1)
-                        (match_operand:SI 2 "immediate_operand" " Iu05")))]
+                        (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")))]
   "TARGET_EXT_PERF"
   "btst\t%0, %1, %2"
   [(set_attr "type" "alu")
    (set_attr "length" "4")])
 
+(define_insn "ave"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (truncate:SI
+         (ashiftrt:DI
+           (plus:DI
+             (plus:DI
+               (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
+               (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
+             (const_int 1))
+         (const_int 1))))]
+  "TARGET_EXT_PERF"
+  "ave\t%0, %1, %2"
+  [(set_attr "type" "alu")
+   (set_attr "length" "4")])
+
 ;; ----------------------------------------------------------------------------
 
 ;; Pseudo NOPs
index 4aa299c88326f095f065025b74805536c7ccc596..01e1a8e3e600296ba62303229041e983961ea75a 100644 (file)
@@ -425,6 +425,22 @@ enum nds32_cctl_idxwrite
   (__builtin_nds32_swup ((a), (b)))
 #define __nds32__sbup(a, b) \
   (__builtin_nds32_sbup ((a), (b)))
+
+#define __nds32__mfsr(srname) \
+  (__builtin_nds32_mfsr ((srname)))
+#define __nds32__mfusr(usrname) \
+  (__builtin_nds32_mfusr ((usrname)))
+#define __nds32__mtsr(val, srname) \
+  (__builtin_nds32_mtsr ((val), (srname)))
+#define __nds32__mtsr_isb(val, srname) \
+  (__builtin_nds32_mtsr_isb ((val), (srname)))
+#define __nds32__mtsr_dsb(val, srname) \
+  (__builtin_nds32_mtsr_dsb ((val), (srname)))
+#define __nds32__mtusr(val, usrname) \
+  (__builtin_nds32_mtusr ((val), (usrname)))
+
+#define __nds32__break(swid) \
+  (__builtin_nds32_break(swid))
 #define __nds32__cctlva_lck(subtype, va) \
   (__builtin_nds32_cctl_va_lck ((subtype), (va)))
 #define __nds32__cctlidx_wbinval(subtype, idx) \
@@ -452,6 +468,96 @@ enum nds32_cctl_idxwrite
   (__builtin_nds32_msync_store())
 #define __nds32__msync_all() \
   (__builtin_nds32_msync_all())
+#define __nds32__nop() \
+  (__builtin_nds32_nop())
+
+#define __nds32__standby_wait_done() \
+  (__builtin_nds32_standby_wait_done())
+#define __nds32__standby_no_wake_grant() \
+  (__builtin_nds32_standby_no_wake_grant())
+#define __nds32__standby_wake_grant() \
+  (__builtin_nds32_standby_wake_grant())
+#define __nds32__schedule_barrier() \
+  (__builtin_nds32_schedule_barrier())
+#define __nds32__setend_big() \
+  (__builtin_nds32_setend_big())
+#define __nds32__setend_little() \
+  (__builtin_nds32_setend_little())
+#define __nds32__setgie_en() \
+
+#define __nds32__jr_itoff(a) \
+  (__builtin_nds32_jr_itoff ((a)))
+#define __nds32__jr_toff(a) \
+  (__builtin_nds32_jr_toff ((a)))
+#define __nds32__jral_iton(a) \
+  (__builtin_nds32_jral_iton ((a)))
+#define __nds32__jral_ton(a) \
+  (__builtin_nds32_jral_ton ((a)))
+#define __nds32__ret_itoff(a) \
+  (__builtin_nds32_ret_itoff ((a)))
+#define __nds32__ret_toff(a) \
+  (__builtin_nds32_ret_toff ((a)))
+#define __nds32__svs(a, b) \
+  (__builtin_nds32_svs ((a), (b)))
+#define __nds32__sva(a, b) \
+  (__builtin_nds32_sva ((a), (b)))
+
+#define __nds32__teqz(a, swid) \
+  (__builtin_nds32_teqz ((a), (swid)))
+#define __nds32__tnez(a, swid) \
+  ( __builtin_nds32_tnez ((a), (swid)))
+#define __nds32__trap(swid) \
+  (__builtin_nds32_trap ((swid)))
+#define __nds32__isync(a) \
+  (__builtin_nds32_isync ((a)))
+#define __nds32__rotr(val, ror) \
+  (__builtin_nds32_rotr ((val), (ror)))
+#define __nds32__wsbh(a) \
+  (__builtin_nds32_wsbh ((a)))
+#define __nds32__syscall(a) \
+  (__builtin_nds32_syscall ((a)))
+#define __nds32__return_address() \
+  (__builtin_nds32_return_address())
+#define __nds32__get_current_sp() \
+  (__builtin_nds32_get_current_sp())
+#define __nds32__set_current_sp(a) \
+  (__builtin_nds32_set_current_sp ((a)))
+#define __nds32__abs(a) \
+  (__builtin_nds32_pe_abs ((a)))
+#define __nds32__ave(a, b) \
+  (__builtin_nds32_pe_ave ((a), (b)))
+#define __nds32__bclr(a, pos) \
+  (__builtin_nds32_pe_bclr ((a), (pos)))
+#define __nds32__bset(a, pos) \
+  (__builtin_nds32_pe_bset ((a), (pos)))
+#define __nds32__btgl(a, pos) \
+  (__builtin_nds32_pe_btgl ((a), (pos)))
+#define __nds32__btst(a, pos) \
+  (__builtin_nds32_pe_btst ((a), (pos)))
+
+#define __nds32__clip(a, imm) \
+  (__builtin_nds32_pe_clip ((a), (imm)))
+#define __nds32__clips(a, imm) \
+  (__builtin_nds32_pe_clips ((a), (imm)))
+#define __nds32__clz(a) \
+  (__builtin_nds32_pe_clz ((a)))
+#define __nds32__clo(a) \
+  (__builtin_nds32_pe_clo ((a)))
+#define __nds32__bse(r, a, b) \
+  (__builtin_nds32_pe2_bse ((r), (a), (b)))
+#define __nds32__bsp(r, a, b) \
+  (__builtin_nds32_pe2_bsp ((r), (a), (b)))
+#define __nds32__pbsad(a, b) \
+  (__builtin_nds32_pe2_pbsad ((a), (b)))
+#define __nds32__pbsada(acc, a, b) \
+  (__builtin_nds32_pe2_pbsada ((acc), (a), (b)))
+
+#define __nds32__ffb(a, b) \
+  (__builtin_nds32_se_ffb ((a), (b)))
+#define __nds32__ffmism(a, b) \
+  (__builtin_nds32_se_ffmism ((a), (b)))
+#define __nds32__flmism(a, b) \
+  (__builtin_nds32_se_flmism ((a), (b)))
 #define __nds32__fcpynsd(a, b) \
   (__builtin_nds32_fcpynsd ((a), (b)))
 #define __nds32__fcpynss(a, b) \