From 2feae6cdf25ad2d1cb2fc48ab000b4ca4c5ec793 Mon Sep 17 00:00:00 2001 From: Monk Chiang Date: Sat, 7 Apr 2018 08:16:41 +0000 Subject: [PATCH] [NDS32] Add intrinsic functions for particular instructions. 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 | 12 + gcc/config/nds32/constants.md | 29 +++ gcc/config/nds32/nds32-intrinsic.c | 231 ++++++++++++++++++ gcc/config/nds32/nds32-intrinsic.md | 361 ++++++++++++++++++++++++++++ gcc/config/nds32/nds32.h | 42 ++++ gcc/config/nds32/nds32.md | 25 +- gcc/config/nds32/nds32_intrinsic.h | 106 ++++++++ 7 files changed, 801 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ffc87d71032..cba35256429 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2018-04-07 Monk Chiang + + * 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 * config/nds32/constants.md (unspec_element, unspec_volatile_element): diff --git a/gcc/config/nds32/constants.md b/gcc/config/nds32/constants.md index 77d96892102..3facf5ba898 100644 --- a/gcc/config/nds32/constants.md +++ b/gcc/config/nds32/constants.md @@ -37,9 +37,21 @@ 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 @@ -69,6 +81,23 @@ 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 diff --git a/gcc/config/nds32/nds32-intrinsic.c b/gcc/config/nds32/nds32-intrinsic.c index fb67e6fe5d5..49b03f3f740 100644 --- a/gcc/config/nds32/nds32-intrinsic.c +++ b/gcc/config/nds32/nds32-intrinsic.c @@ -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); diff --git a/gcc/config/nds32/nds32-intrinsic.md b/gcc/config/nds32/nds32-intrinsic.md index 5b58fc9229a..52437a47e61 100644 --- a/gcc/config/nds32/nds32-intrinsic.md +++ b/gcc/config/nds32/nds32-intrinsic.md @@ -339,6 +339,190 @@ "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" @@ -373,6 +557,183 @@ (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" diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h index 8f1ac32c704..f0518e0566d 100644 --- a/gcc/config/nds32/nds32.h +++ b/gcc/config/nds32/nds32.h @@ -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, diff --git a/gcc/config/nds32/nds32.md b/gcc/config/nds32/nds32.md index 428d8164af2..99731fecb7a 100644 --- a/gcc/config/nds32/nds32.md +++ b/gcc/config/nds32/nds32.md @@ -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")) @@ -1922,16 +1922,31 @@ [(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 diff --git a/gcc/config/nds32/nds32_intrinsic.h b/gcc/config/nds32/nds32_intrinsic.h index 4aa299c8832..01e1a8e3e60 100644 --- a/gcc/config/nds32/nds32_intrinsic.h +++ b/gcc/config/nds32/nds32_intrinsic.h @@ -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) \ -- 2.30.2