+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):
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
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)
{
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. */
{
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. */
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)
};
+/* 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[] =
{
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:
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;
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);
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);
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);
"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"
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,
;; 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
(__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) \
(__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) \