Commit 8b9322f0 by Monk Chiang Committed by Chung-Ju Wu

[NDS32] Add intrinsic functions for interrupt control.

gcc/
	* config.gcc (nds32le-*-*, nds32be-*-*): Add nds32/nds32_intrinsic.h
	into tm_file.
	* config/nds32/constants.md (unspec_volatile_element): Add enum values
	for interrupt control.
	* config/nds32/nds32-intrinsic.c: Implementation of intrinsic
	functions for interrupt control.
	* config/nds32/nds32-intrinsic.md: Likewise.
	* config/nds32/nds32_intrinsic.h: Likewise.
	* config/nds32/nds32.h (nds32_builtins): Likewise.

From-SVN: r259223
parent 5f2a98c3
2018-04-08 Monk Chiang <sh.chiang04@gmail.com>
* config.gcc (nds32le-*-*, nds32be-*-*): Add nds32/nds32_intrinsic.h
into tm_file.
* config/nds32/constants.md (unspec_volatile_element): Add enum values
for interrupt control.
* config/nds32/nds32-intrinsic.c: Implementation of intrinsic
functions for interrupt control.
* config/nds32/nds32-intrinsic.md: Likewise.
* config/nds32/nds32_intrinsic.h: Likewise.
* config/nds32/nds32.h (nds32_builtins): Likewise.
2018-04-08 Chung-Ju Wu <jasonwucj@gmail.com>
* config/nds32/nds32.c (nds32_init_machine_status,
......
......@@ -2335,13 +2335,13 @@ msp430*-*-*)
nds32le-*-*)
target_cpu_default="0"
tm_defines="${tm_defines}"
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} nds32/nds32_intrinsic.h"
tmake_file="nds32/t-nds32 nds32/t-mlibs"
;;
nds32be-*-*)
target_cpu_default="0|MASK_BIG_ENDIAN"
tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} nds32/nds32_intrinsic.h"
tmake_file="nds32/t-nds32 nds32/t-mlibs"
;;
nios2-*-*)
......
......@@ -122,6 +122,18 @@
UNSPEC_VOLATILE_TLBOP_PB
UNSPEC_VOLATILE_TLBOP_INV
UNSPEC_VOLATILE_TLBOP_FLUA
UNSPEC_VOLATILE_ENABLE_INT
UNSPEC_VOLATILE_DISABLE_INT
UNSPEC_VOLATILE_SET_PENDING_SWINT
UNSPEC_VOLATILE_CLR_PENDING_SWINT
UNSPEC_VOLATILE_CLR_PENDING_HWINT
UNSPEC_VOLATILE_GET_ALL_PENDING_INT
UNSPEC_VOLATILE_GET_PENDING_INT
UNSPEC_VOLATILE_SET_INT_PRIORITY
UNSPEC_VOLATILE_GET_INT_PRIORITY
UNSPEC_VOLATILE_SET_TRIG_LEVEL
UNSPEC_VOLATILE_SET_TRIG_EDGE
UNSPEC_VOLATILE_GET_TRIG_TYPE
UNSPEC_VOLATILE_RELAX_GROUP
UNSPEC_VOLATILE_POP25_RETURN
])
......
......@@ -467,6 +467,37 @@ nds32_expand_scw_builtin (enum insn_code icode, tree exp, rtx target)
return target;
}
/* Expand set int priority builtins. */
static rtx
nds32_expand_priority_builtin (enum insn_code icode, tree exp, rtx target,
const char *name)
{
rtx pat;
rtx op0 = nds32_read_argument (exp, 0);
rtx op1 = nds32_read_argument (exp, 1);
/* set_int_priority intrinsic function that two arguments are immediate,
so check whether auguments are immedite. */
if (!nds32_check_constant_argument (icode, 0, op0, name))
return NULL_RTX;
if (!nds32_check_constant_argument (icode, 1, op1, name))
return NULL_RTX;
op0 = nds32_legitimize_argument (icode, 0, op0);
op1 = nds32_legitimize_argument (icode, 1, op1);
/* Emit and return the new instruction. */
pat = GEN_FCN (icode) (op0, op1);
if (! pat)
return NULL_RTX;
emit_insn (pat);
return target;
}
struct builtin_description
{
const enum insn_code icode;
......@@ -490,6 +521,8 @@ static struct builtin_description bdesc_noarg[] =
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)
NDS32_BUILTIN(unspec_get_all_pending_int, "get_all_pending_int",
GET_ALL_PENDING_INT)
};
/* Intrinsics that take just one argument. */
......@@ -526,9 +559,20 @@ static struct builtin_description bdesc_1argimm[] =
{
NDS32_BUILTIN(unspec_volatile_mfsr, "mfsr", MFSR)
NDS32_BUILTIN(unspec_volatile_mfusr, "mfsr", MFUSR)
NDS32_BUILTIN(unspec_get_pending_int, "get_pending_int", GET_PENDING_INT)
NDS32_BUILTIN(unspec_get_int_priority, "get_int_priority", GET_INT_PRIORITY)
NDS32_NO_TARGET_BUILTIN(unspec_trap, "trap", TRAP)
NDS32_NO_TARGET_BUILTIN(unspec_break, "break", BREAK)
NDS32_NO_TARGET_BUILTIN(unspec_syscall, "syscall", SYSCALL)
NDS32_NO_TARGET_BUILTIN(unspec_enable_int, "enable_int", ENABLE_INT)
NDS32_NO_TARGET_BUILTIN(unspec_disable_int, "disable_int", DISABLE_INT)
NDS32_NO_TARGET_BUILTIN(unspec_clr_pending_hwint, "clr_pending_hwint",
CLR_PENDING_HWINT)
NDS32_NO_TARGET_BUILTIN(unspec_set_trig_level, "set_trig_level",
SET_TRIG_LEVEL)
NDS32_NO_TARGET_BUILTIN(unspec_set_trig_edge, "set_trig_edge",
SET_TRIG_EDGE)
NDS32_BUILTIN(unspec_get_trig_type, "get_trig_type", GET_TRIG_TYPE)
};
/* Intrinsics that take two arguments. */
......@@ -739,6 +783,20 @@ nds32_expand_builtin_impl (tree exp,
emit_insn (gen_unspec_volatile_setgie_dis ());
emit_insn (gen_unspec_dsb ());
return target;
case NDS32_BUILTIN_GIE_DIS:
emit_insn (gen_unspec_volatile_setgie_dis ());
emit_insn (gen_unspec_dsb ());
return target;
case NDS32_BUILTIN_GIE_EN:
emit_insn (gen_unspec_volatile_setgie_en ());
emit_insn (gen_unspec_dsb ());
return target;
case NDS32_BUILTIN_SET_PENDING_SWINT:
emit_insn (gen_unspec_set_pending_swint ());
return target;
case NDS32_BUILTIN_CLR_PENDING_SWINT:
emit_insn (gen_unspec_clr_pending_swint ());
return target;
case NDS32_BUILTIN_CCTL_L1D_INVALALL:
emit_insn (gen_cctl_l1d_invalall());
return target;
......@@ -775,6 +833,10 @@ nds32_expand_builtin_impl (tree exp,
case NDS32_BUILTIN_SCW:
return nds32_expand_scw_builtin (CODE_FOR_unspec_volatile_scw,
exp, target);
case NDS32_BUILTIN_SET_INT_PRIORITY:
return nds32_expand_priority_builtin (CODE_FOR_unspec_set_int_priority,
exp, target,
"__nds32__set_int_priority");
return target;
default:
break;
......@@ -911,6 +973,21 @@ nds32_init_builtins_impl (void)
/* Interrupt. */
ADD_NDS32_BUILTIN0 ("setgie_en", void, SETGIE_EN);
ADD_NDS32_BUILTIN0 ("setgie_dis", void, SETGIE_DIS);
ADD_NDS32_BUILTIN0 ("gie_en", void, GIE_EN);
ADD_NDS32_BUILTIN0 ("gie_dis", void, GIE_DIS);
ADD_NDS32_BUILTIN1 ("enable_int", void, integer, ENABLE_INT);
ADD_NDS32_BUILTIN1 ("disable_int", void, integer, DISABLE_INT);
ADD_NDS32_BUILTIN0 ("set_pending_swint", void, SET_PENDING_SWINT);
ADD_NDS32_BUILTIN0 ("clr_pending_swint", void, CLR_PENDING_SWINT);
ADD_NDS32_BUILTIN0 ("get_all_pending_int", unsigned, GET_ALL_PENDING_INT);
ADD_NDS32_BUILTIN1 ("get_pending_int", unsigned, integer, GET_PENDING_INT);
ADD_NDS32_BUILTIN1 ("get_int_priority", unsigned, integer, GET_INT_PRIORITY);
ADD_NDS32_BUILTIN2 ("set_int_priority", void, integer, integer,
SET_INT_PRIORITY);
ADD_NDS32_BUILTIN1 ("clr_pending_hwint", void, integer, CLR_PENDING_HWINT);
ADD_NDS32_BUILTIN1 ("set_trig_level", void, integer, SET_TRIG_LEVEL);
ADD_NDS32_BUILTIN1 ("set_trig_edge", void, integer, SET_TRIG_EDGE);
ADD_NDS32_BUILTIN1 ("get_trig_type", unsigned, integer, GET_TRIG_TYPE);
/* Load and Store */
ADD_NDS32_BUILTIN1 ("llw", unsigned, ptr_uint, LLW);
......
......@@ -164,6 +164,445 @@
[(set_attr "type" "misc")]
)
(define_expand "unspec_enable_int"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_ENABLE_INT)]
""
{
rtx system_reg;
rtx temp_reg = gen_reg_rtx (SImode);
/* Set system register form nds32_intrinsic_register_names[]. */
if ((INTVAL (operands[0]) >= NDS32_INT_H16)
&& (INTVAL (operands[0]) <= NDS32_INT_H31))
{
system_reg = GEN_INT (__NDS32_REG_INT_MASK2__);
operands[0] = GEN_INT (1 << (INTVAL (operands[0])));
}
else if ((INTVAL (operands[0]) >= NDS32_INT_H32)
&& (INTVAL (operands[0]) <= NDS32_INT_H63))
{
system_reg = GEN_INT (__NDS32_REG_INT_MASK3__);
operands[0] = GEN_INT (1 << (INTVAL (operands[0]) - 32));
}
else
{
system_reg = GEN_INT (__NDS32_REG_INT_MASK__);
if (INTVAL (operands[0]) == NDS32_INT_SWI)
operands[0] = GEN_INT (1 << 16);
else if ((INTVAL (operands[0]) >= NDS32_INT_ALZ)
&& (INTVAL (operands[0]) <= NDS32_INT_DSSIM))
operands[0] = GEN_INT (1 << (INTVAL (operands[0]) - 4));
else
operands[0] = GEN_INT (1 << (INTVAL (operands[0])));
}
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_insn (gen_iorsi3 (temp_reg, temp_reg, operands[0]));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
DONE;
})
(define_expand "unspec_disable_int"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_DISABLE_INT)]
""
{
rtx system_reg;
rtx temp_reg = gen_reg_rtx (SImode);
/* Set system register form nds32_intrinsic_register_names[]. */
if ((INTVAL (operands[0]) >= NDS32_INT_H16)
&& (INTVAL (operands[0]) <= NDS32_INT_H31))
{
system_reg = GEN_INT (__NDS32_REG_INT_MASK2__);
operands[0] = GEN_INT (~(1 << INTVAL (operands[0])));
}
else if ((INTVAL (operands[0]) >= NDS32_INT_H32)
&& (INTVAL (operands[0]) <= NDS32_INT_H63))
{
system_reg = GEN_INT (__NDS32_REG_INT_MASK3__);
operands[0] = GEN_INT (~(1 << (INTVAL (operands[0]) - 32)));
}
else
{
system_reg = GEN_INT (__NDS32_REG_INT_MASK__);
if (INTVAL (operands[0]) == NDS32_INT_SWI)
operands[0] = GEN_INT (~(1 << 16));
else if ((INTVAL (operands[0]) >= NDS32_INT_ALZ)
&& (INTVAL (operands[0]) <= NDS32_INT_DSSIM))
operands[0] = GEN_INT (~(1 << (INTVAL (operands[0]) - 4)));
else
operands[0] = GEN_INT (~(1 << INTVAL (operands[0])));
}
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_insn (gen_andsi3 (temp_reg, temp_reg, operands[0]));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
DONE;
})
(define_expand "unspec_set_pending_swint"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SET_PENDING_SWINT)]
""
{
/* Get $INT_PEND system register form nds32_intrinsic_register_names[] */
rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
rtx temp_reg = gen_reg_rtx (SImode);
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_insn (gen_iorsi3 (temp_reg, temp_reg, GEN_INT (65536)));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
DONE;
})
(define_expand "unspec_clr_pending_swint"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLR_PENDING_SWINT)]
""
{
/* Get $INT_PEND system register form nds32_intrinsic_register_names[] */
rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
rtx temp_reg = gen_reg_rtx (SImode);
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_insn (gen_andsi3 (temp_reg, temp_reg, GEN_INT (~(1 << 16))));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
DONE;
})
(define_expand "unspec_clr_pending_hwint"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_CLR_PENDING_HWINT)]
""
{
rtx system_reg = NULL_RTX;
rtx temp_reg = gen_reg_rtx (SImode);
rtx clr_hwint;
unsigned offset = 0;
/* Set system register form nds32_intrinsic_register_names[]. */
if ((INTVAL (operands[0]) >= NDS32_INT_H0)
&& (INTVAL (operands[0]) <= NDS32_INT_H15))
{
system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
}
else if ((INTVAL (operands[0]) >= NDS32_INT_H16)
&& (INTVAL (operands[0]) <= NDS32_INT_H31))
{
system_reg = GEN_INT (__NDS32_REG_INT_PEND2__);
}
else if ((INTVAL (operands[0]) >= NDS32_INT_H32)
&& (INTVAL (operands[0]) <= NDS32_INT_H63))
{
system_reg = GEN_INT (__NDS32_REG_INT_PEND3__);
offset = 32;
}
else
error ("__nds32__clr_pending_hwint not support NDS32_INT_SWI,"
" NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
/* $INT_PEND type is write one clear. */
clr_hwint = GEN_INT (1 << (INTVAL (operands[0]) - offset));
if (system_reg != NULL_RTX)
{
emit_move_insn (temp_reg, clr_hwint);
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
}
DONE;
})
(define_expand "unspec_get_all_pending_int"
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_GET_ALL_PENDING_INT))]
""
{
rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
emit_insn (gen_unspec_dsb ());
DONE;
})
(define_expand "unspec_get_pending_int"
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_PENDING_INT))]
""
{
rtx system_reg = NULL_RTX;
/* Set system register form nds32_intrinsic_register_names[]. */
if ((INTVAL (operands[1]) >= NDS32_INT_H0)
&& (INTVAL (operands[1]) <= NDS32_INT_H15))
{
system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
operands[2] = GEN_INT (31 - INTVAL (operands[1]));
}
else if (INTVAL (operands[1]) == NDS32_INT_SWI)
{
system_reg = GEN_INT (__NDS32_REG_INT_PEND__);
operands[2] = GEN_INT (15);
}
else if ((INTVAL (operands[1]) >= NDS32_INT_H16)
&& (INTVAL (operands[1]) <= NDS32_INT_H31))
{
system_reg = GEN_INT (__NDS32_REG_INT_PEND2__);
operands[2] = GEN_INT (31 - INTVAL (operands[1]));
}
else if ((INTVAL (operands[1]) >= NDS32_INT_H32)
&& (INTVAL (operands[1]) <= NDS32_INT_H63))
{
system_reg = GEN_INT (__NDS32_REG_INT_PEND3__);
operands[2] = GEN_INT (31 - (INTVAL (operands[1]) - 32));
}
else
error ("get_pending_int not support NDS32_INT_ALZ,"
" NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
/* mfsr op0, sytem_reg */
if (system_reg != NULL_RTX)
{
emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
emit_insn (gen_unspec_dsb ());
}
DONE;
})
(define_expand "unspec_set_int_priority"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")
(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_SET_INT_PRIORITY)]
""
{
rtx system_reg = NULL_RTX;
rtx priority = NULL_RTX;
rtx mask = NULL_RTX;
rtx temp_reg = gen_reg_rtx (SImode);
rtx mask_reg = gen_reg_rtx (SImode);
rtx set_reg = gen_reg_rtx (SImode);
unsigned offset = 0;
/* Get system register form nds32_intrinsic_register_names[]. */
if (INTVAL (operands[0]) <= NDS32_INT_H15)
{
system_reg = GEN_INT (__NDS32_REG_INT_PRI__);
offset = 0;
}
else if (INTVAL (operands[0]) >= NDS32_INT_H16
&& INTVAL (operands[0]) <= NDS32_INT_H31)
{
system_reg = GEN_INT (__NDS32_REG_INT_PRI2__);
/* The $INT_PRI2 first bit correspond to H16, so need
subtract 16. */
offset = 16;
}
else if (INTVAL (operands[0]) >= NDS32_INT_H32
&& INTVAL (operands[0]) <= NDS32_INT_H47)
{
system_reg = GEN_INT (__NDS32_REG_INT_PRI3__);
/* The $INT_PRI3 first bit correspond to H32, so need
subtract 32. */
offset = 32;
}
else if (INTVAL (operands[0]) >= NDS32_INT_H48
&& INTVAL (operands[0]) <= NDS32_INT_H63)
{
system_reg = GEN_INT (__NDS32_REG_INT_PRI4__);
/* The $INT_PRI3 first bit correspond to H48, so need
subtract 48. */
offset = 48;
}
else
error ("set_int_priority not support NDS32_INT_SWI,"
" NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
mask = GEN_INT (~(3 << 2 * (INTVAL (operands[0]) - offset)));
priority = GEN_INT ((int) (INTVAL (operands[1])
<< ((INTVAL (operands[0]) - offset) * 2)));
if (system_reg != NULL_RTX)
{
emit_move_insn (mask_reg, mask);
emit_move_insn (set_reg, priority);
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_insn (gen_andsi3 (temp_reg, temp_reg, mask_reg));
emit_insn (gen_iorsi3 (temp_reg, temp_reg, set_reg));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
}
DONE;
})
(define_expand "unspec_get_int_priority"
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_INT_PRIORITY))]
""
{
rtx system_reg = NULL_RTX;
rtx priority = NULL_RTX;
unsigned offset = 0;
/* Get system register form nds32_intrinsic_register_names[] */
if (INTVAL (operands[1]) <= NDS32_INT_H15)
{
system_reg = GEN_INT (__NDS32_REG_INT_PRI__);
offset = 0;
}
else if (INTVAL (operands[1]) >= NDS32_INT_H16
&& INTVAL (operands[1]) <= NDS32_INT_H31)
{
system_reg = GEN_INT (__NDS32_REG_INT_PRI2__);
/* The $INT_PRI2 first bit correspond to H16, so need
subtract 16. */
offset = 16;
}
else if (INTVAL (operands[1]) >= NDS32_INT_H32
&& INTVAL (operands[1]) <= NDS32_INT_H47)
{
system_reg = GEN_INT (__NDS32_REG_INT_PRI3__);
/* The $INT_PRI3 first bit correspond to H32, so need
subtract 32. */
offset = 32;
}
else if (INTVAL (operands[1]) >= NDS32_INT_H48
&& INTVAL (operands[1]) <= NDS32_INT_H63)
{
system_reg = GEN_INT (__NDS32_REG_INT_PRI4__);
/* The $INT_PRI4 first bit correspond to H48, so need
subtract 48. */
offset = 48;
}
else
error ("set_int_priority not support NDS32_INT_SWI,"
" NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
priority = GEN_INT (31 - 2 * (INTVAL (operands[1]) - offset));
if (system_reg != NULL_RTX)
{
emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
emit_insn (gen_ashlsi3 (operands[0], operands[0], priority));
emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (30)));
emit_insn (gen_unspec_dsb ());
}
DONE;
})
(define_expand "unspec_set_trig_level"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_SET_TRIG_LEVEL)]
""
{
rtx system_reg = NULL_RTX;
rtx temp_reg = gen_reg_rtx (SImode);
rtx set_level;
unsigned offset = 0;
if (INTVAL (operands[0]) >= NDS32_INT_H0
&& INTVAL (operands[0]) <= NDS32_INT_H31)
{
system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__);
offset = 0;
}
else if (INTVAL (operands[0]) >= NDS32_INT_H32
&& INTVAL (operands[0]) <= NDS32_INT_H63)
{
system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__);
offset = 32;
}
else
error ("__nds32__set_trig_type_level not support NDS32_INT_SWI,"
" NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
if (system_reg != NULL_RTX)
{
/* TRIGGER register, 0 mean level triggered and 1 mean edge triggered. */
set_level = GEN_INT (~(1 << (INTVAL (operands[0]) - offset)));
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_insn (gen_andsi3 (temp_reg, temp_reg, set_level));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
}
DONE;
})
(define_expand "unspec_set_trig_edge"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_SET_TRIG_EDGE)]
""
{
rtx system_reg = NULL_RTX;
rtx temp_reg = gen_reg_rtx (SImode);
rtx set_level;
unsigned offset = 0;
if (INTVAL (operands[0]) >= NDS32_INT_H0
&& INTVAL (operands[0]) <= NDS32_INT_H31)
{
system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__);
offset = 0;
}
else if (INTVAL (operands[0]) >= NDS32_INT_H32
&& INTVAL (operands[0]) <= NDS32_INT_H63)
{
system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__);
offset = 32;
}
else
error ("__nds32__set_trig_type_edge not support NDS32_INT_SWI,"
" NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
if (system_reg != NULL_RTX)
{
/* TRIGGER register, 0 mean level triggered and 1 mean edge triggered. */
set_level = GEN_INT ((1 << (INTVAL (operands[0]) - offset)));
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_insn (gen_iorsi3 (temp_reg, temp_reg, set_level));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
}
DONE;
})
(define_expand "unspec_get_trig_type"
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_TRIG_TYPE))]
""
{
rtx system_reg = NULL_RTX;
rtx trig_type;
unsigned offset = 0;
if (INTVAL (operands[1]) >= NDS32_INT_H0
&& INTVAL (operands[1]) <= NDS32_INT_H31)
{
system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__);
offset = 0;
}
else if (INTVAL (operands[1]) >= NDS32_INT_H32
&& INTVAL (operands[1]) <= NDS32_INT_H63)
{
system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__);
offset = 32;
}
else
error ("__nds32__get_trig_type not support NDS32_INT_SWI,"
" NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM");
if (system_reg != NULL_RTX)
{
trig_type = GEN_INT (31 - (INTVAL (operands[1]) - offset));
emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
emit_insn (gen_ashlsi3 (operands[0], operands[0], trig_type));
emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
emit_insn (gen_unspec_dsb ());
}
DONE;
})
;; ------------------------------------------------------------------------
;; Cache Synchronization Instructions
......
......@@ -498,6 +498,20 @@ enum nds32_builtins
NDS32_BUILTIN_UASTORE_HW,
NDS32_BUILTIN_UASTORE_W,
NDS32_BUILTIN_UASTORE_DW,
NDS32_BUILTIN_GIE_DIS,
NDS32_BUILTIN_GIE_EN,
NDS32_BUILTIN_ENABLE_INT,
NDS32_BUILTIN_DISABLE_INT,
NDS32_BUILTIN_SET_PENDING_SWINT,
NDS32_BUILTIN_CLR_PENDING_SWINT,
NDS32_BUILTIN_CLR_PENDING_HWINT,
NDS32_BUILTIN_GET_ALL_PENDING_INT,
NDS32_BUILTIN_GET_PENDING_INT,
NDS32_BUILTIN_SET_INT_PRIORITY,
NDS32_BUILTIN_GET_INT_PRIORITY,
NDS32_BUILTIN_SET_TRIG_LEVEL,
NDS32_BUILTIN_SET_TRIG_EDGE,
NDS32_BUILTIN_GET_TRIG_TYPE,
NDS32_BUILTIN_COUNT
};
......
......@@ -238,6 +238,78 @@ enum nds32_dpref
/* ------------------------------------------------------------------------ */
/* Define interrupt number for intrinsic function. */
#define NDS32_INT_H0 0
#define NDS32_INT_H1 1
#define NDS32_INT_H2 2
#define NDS32_INT_H3 3
#define NDS32_INT_H4 4
#define NDS32_INT_H5 5
#define NDS32_INT_H6 6
#define NDS32_INT_H7 7
#define NDS32_INT_H8 8
#define NDS32_INT_H9 9
#define NDS32_INT_H10 10
#define NDS32_INT_H11 11
#define NDS32_INT_H12 12
#define NDS32_INT_H13 13
#define NDS32_INT_H14 14
#define NDS32_INT_H15 15
#define NDS32_INT_H16 16
#define NDS32_INT_H17 17
#define NDS32_INT_H18 18
#define NDS32_INT_H19 19
#define NDS32_INT_H20 20
#define NDS32_INT_H21 21
#define NDS32_INT_H22 22
#define NDS32_INT_H23 23
#define NDS32_INT_H24 24
#define NDS32_INT_H25 25
#define NDS32_INT_H26 26
#define NDS32_INT_H27 27
#define NDS32_INT_H28 28
#define NDS32_INT_H29 29
#define NDS32_INT_H30 30
#define NDS32_INT_H31 31
#define NDS32_INT_H32 32
#define NDS32_INT_H33 33
#define NDS32_INT_H34 34
#define NDS32_INT_H35 35
#define NDS32_INT_H36 36
#define NDS32_INT_H37 37
#define NDS32_INT_H38 38
#define NDS32_INT_H39 39
#define NDS32_INT_H40 40
#define NDS32_INT_H41 41
#define NDS32_INT_H42 42
#define NDS32_INT_H43 43
#define NDS32_INT_H44 44
#define NDS32_INT_H45 45
#define NDS32_INT_H46 46
#define NDS32_INT_H47 47
#define NDS32_INT_H48 48
#define NDS32_INT_H49 49
#define NDS32_INT_H50 50
#define NDS32_INT_H51 51
#define NDS32_INT_H52 52
#define NDS32_INT_H53 53
#define NDS32_INT_H54 54
#define NDS32_INT_H55 55
#define NDS32_INT_H56 56
#define NDS32_INT_H57 57
#define NDS32_INT_H58 58
#define NDS32_INT_H59 59
#define NDS32_INT_H60 60
#define NDS32_INT_H61 61
#define NDS32_INT_H62 62
#define NDS32_INT_H63 63
#define NDS32_INT_SWI 64
#define NDS32_INT_ALZ 65
#define NDS32_INT_IDIVZE 66
#define NDS32_INT_DSSIM 67
/* ------------------------------------------------------------------------ */
/* Define intrinsic register name macro for compatibility. */
#define NDS32_SR_CPU_VER __NDS32_REG_CPU_VER__
#define NDS32_SR_ICM_CFG __NDS32_REG_ICM_CFG__
......@@ -502,6 +574,9 @@ enum nds32_dpref
#define __nds32__setend_little() \
(__builtin_nds32_setend_little())
#define __nds32__setgie_en() \
(__builtin_nds32_setgie_en())
#define __nds32__setgie_dis() \
(__builtin_nds32_setgie_dis())
#define __nds32__jr_itoff(a) \
(__builtin_nds32_jr_itoff ((a)))
......@@ -616,4 +691,33 @@ enum nds32_dpref
#define __nds32__tlbop_flua() \
(__builtin_nds32_tlbop_flua())
#define __nds32__gie_dis() \
(__builtin_nds32_gie_dis())
#define __nds32__gie_en() \
(__builtin_nds32_gie_en())
#define __nds32__enable_int(a) \
(__builtin_nds32_enable_int ((a)))
#define __nds32__disable_int(a) \
(__builtin_nds32_disable_int ((a)))
#define __nds32__set_pending_swint() \
(__builtin_nds32_set_pending_swint())
#define __nds32__clr_pending_swint() \
(__builtin_nds32_clr_pending_swint())
#define __nds32__clr_pending_hwint(a) \
(__builtin_nds32_clr_pending_hwint(a))
#define __nds32__get_all_pending_int() \
(__builtin_nds32_get_all_pending_int())
#define __nds32__get_pending_int(a) \
(__builtin_nds32_get_pending_int ((a)))
#define __nds32__set_int_priority(a, b) \
(__builtin_nds32_set_int_priority ((a), (b)))
#define __nds32__get_int_priority(a) \
(__builtin_nds32_get_int_priority ((a)))
#define __nds32__set_trig_type_level(a) \
(__builtin_nds32_set_trig_level(a))
#define __nds32__set_trig_type_edge(a) \
(__builtin_nds32_set_trig_edge(a))
#define __nds32__get_trig_type(a) \
(__builtin_nds32_get_trig_type ((a)))
#endif /* nds32_intrinsic.h */
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