Commit 2feae6cd by Monk Chiang Committed by Chung-Ju Wu

[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
parent 154e3ea6
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):
Add enum values for atomic load/store and memory sync.
* config/nds32/nds32-intrinsic.c: Implementation for atomic load/store
and memory sync.
......
......@@ -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
......
......@@ -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);
......
......@@ -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"
......
......@@ -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,
......
......@@ -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"
(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
......
......@@ -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) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment