;; Intrinsic patterns description of Andes NDS32 cpu for GNU compiler
;; Copyright (C) 2012-2022 Free Software Foundation, Inc.
;; Contributed by Andes Technology Corporation.
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; .
;; ------------------------------------------------------------------------
;; Register Transfer.
(define_insn "unspec_volatile_mfsr"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MFSR))]
""
"mfsr\t%0, %V1"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
(define_insn "unspec_volatile_mfusr"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MFUSR))]
""
"mfusr\t%0, %V1"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
(define_expand "mtsr_isb"
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "immediate_operand" ""))]
""
{
emit_insn (gen_unspec_volatile_mtsr (operands[0], operands[1]));
emit_insn (gen_unspec_volatile_isb());
DONE;
})
(define_expand "mtsr_dsb"
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "immediate_operand" ""))]
""
{
emit_insn (gen_unspec_volatile_mtsr (operands[0], operands[1]));
emit_insn (gen_unspec_dsb());
DONE;
})
(define_insn "unspec_volatile_mtsr"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MTSR)]
""
"mtsr\t%0, %V1"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
(define_insn "unspec_volatile_mtusr"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MTUSR)]
""
"mtusr\t%0, %V1"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
;; FPU Register Transfer.
(define_insn "unspec_fcpynsd"
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(match_operand:DF 1 "register_operand" "f")
(match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYNSD))]
""
"fcpynsd\t%0, %1, %2"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
(define_insn "unspec_fcpynss"
[(set (match_operand:SF 0 "register_operand" "=f")
(unspec:SF [(match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYNSS))]
""
"fcpynss\t%0, %1, %2"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
(define_insn "unspec_fcpysd"
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(match_operand:DF 1 "register_operand" "f")
(match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYSD))]
""
"fcpysd\t%0, %1, %2"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
(define_insn "unspec_fcpyss"
[(set (match_operand:SF 0 "register_operand" "=f")
(unspec:SF [(match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYSS))]
""
"fcpyss\t%0, %1, %2"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
(define_insn "unspec_fmfcsr"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCSR))]
""
"fmfcsr\t%0"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
(define_insn "unspec_fmtcsr"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_FMTCSR)]
""
"fmtcsr\t%0"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
(define_insn "unspec_fmfcfg"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCFG))]
""
"fmfcfg\t%0"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
;; ------------------------------------------------------------------------
;; Interrupt Instructions.
(define_insn "unspec_volatile_setgie_en"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETGIE_EN)]
""
"setgie.e"
[(set_attr "type" "misc")]
)
(define_insn "unspec_volatile_setgie_dis"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETGIE_DIS)]
""
"setgie.d"
[(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 %,"
" %, %, %");
/* $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 ("% not support %,"
" %, %");
/* 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 ("i% not support %,"
" %, %, %");
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 ("% not support %,"
" %, %, %");
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 %,"
" %, %, %");
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 %,"
" %, %, %");
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 %,"
" %, %, %");
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
(define_insn "unspec_volatile_isync"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_ISYNC)]
""
"isync\t%0"
[(set_attr "type" "misc")]
)
(define_insn "unspec_volatile_isb"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_ISB)]
""
"isb"
[(set_attr "type" "misc")]
)
(define_insn "unspec_dsb"
[(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_DSB)]
""
"dsb"
[(set_attr "type" "misc")]
)
(define_insn "unspec_msync"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_MSYNC)]
""
"msync\t%0"
[(set_attr "type" "misc")]
)
(define_insn "unspec_msync_all"
[(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_MSYNC_ALL)]
""
"msync\tall"
[(set_attr "type" "misc")]
)
(define_insn "unspec_msync_store"
[(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_MSYNC_STORE)]
""
"msync\tstore"
[(set_attr "type" "misc")]
)
;; Load and Store
(define_insn "unspec_volatile_llw"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r")))] UNSPEC_VOLATILE_LLW))]
""
"llw\t%0, [%1 + %2]"
[(set_attr "length" "4")]
)
(define_insn "unspec_lwup"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r")))] UNSPEC_LWUP))]
""
"lwup\t%0, [%1 + %2]"
[(set_attr "length" "4")]
)
(define_insn "unspec_lbup"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r")))] UNSPEC_LBUP))]
""
"lbup\t%0, [%1 + %2]"
[(set_attr "length" "4")]
)
(define_insn "unspec_volatile_scw"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r")))
(match_operand:SI 3 "register_operand" "0")] UNSPEC_VOLATILE_SCW))]
""
"scw\t%0, [%1 + %2]"
[(set_attr "length" "4")]
)
(define_insn "unspec_swup"
[(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "register_operand" "r")))
(unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SWUP))]
""
"swup\t%2, [%0 + %1]"
[(set_attr "length" "4")]
)
(define_insn "unspec_sbup"
[(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "register_operand" "r")))
(unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SBUP))]
""
"sbup\t%2, [%0 + %1]"
[(set_attr "length" "4")]
)
;; CCTL
(define_insn "cctl_l1d_invalall"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_INVALALL)]
""
"cctl\tL1D_INVALALL"
[(set_attr "type" "mmu")]
)
(define_insn "cctl_l1d_wball_alvl"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ALVL)]
""
"cctl\tL1D_WBALL, alevel"
[(set_attr "type" "mmu")]
)
(define_insn "cctl_l1d_wball_one_lvl"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ONE_LVL)]
""
"cctl\tL1D_WBALL, 1level"
[(set_attr "type" "mmu")]
)
(define_insn "cctl_idx_read"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")
(match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_READ))]
""
"cctl\t%0, %2, %X1"
[(set_attr "type" "mmu")]
)
(define_insn "cctl_idx_write"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
(match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WRITE)]
""
"cctl\t%1, %2, %W0"
[(set_attr "type" "mmu")]
)
(define_insn "cctl_va_wbinval_l1"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_L1)]
""
"cctl\t%1, %U0, 1level"
[(set_attr "type" "mmu")]
)
(define_insn "cctl_va_wbinval_la"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_LA)]
""
"cctl\t%1, %U0, alevel"
[(set_attr "type" "mmu")]
)
(define_insn "cctl_idx_wbinval"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WBINVAL)]
""
"cctl\t%1, %T0"
[(set_attr "type" "mmu")]
)
(define_insn "cctl_va_lck"
[(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_LCK)]
""
"cctl\t%1, %R0"
[(set_attr "type" "mmu")]
)
;;PREFETCH
(define_insn "prefetch_qw"
[(unspec_volatile:QI [(match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "nonmemory_operand" "r")
(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_DPREF_QW)]
""
"dpref\t%Z2, [%0 + %1]"
[(set_attr "type" "misc")]
)
(define_insn "prefetch_hw"
[(unspec_volatile:HI [(match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "nonmemory_operand" "r")
(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_DPREF_HW)]
""
"dpref\t%Z2, [%0 + (%1<<1)]"
[(set_attr "type" "misc")]
)
(define_insn "prefetch_w"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" " r, r")
(match_operand:SI 1 "nonmemory_operand" "Is15, r")
(match_operand:SI 2 "immediate_operand" " i, i")] UNSPEC_VOLATILE_DPREF_W)]
""
"@
dprefi.w\t%Z2, [%0 + %1]
dpref\t%Z2, [%0 + (%1<<2)]"
[(set_attr "type" "misc")]
)
(define_insn "prefetch_dw"
[(unspec_volatile:DI [(match_operand:SI 0 "register_operand" " r, r")
(match_operand:SI 1 "nonmemory_operand" "Is15, r")
(match_operand:SI 2 "immediate_operand" " i, i")] UNSPEC_VOLATILE_DPREF_DW)]
""
"@
dprefi.d\t%Z2, [%0 + %1]
dpref\t%Z2, [%0 + (%1<<3)]"
[(set_attr "type" "misc")]
)
;; 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 (match_operand:SI 0 "register_operand" "=r, r")
(unspec:SI [(match_operand:SI 1 "register_operand" "r, r")
(match_operand:SI 2 "nonmemory_operand" "Iu08, r")] UNSPEC_FFB))]
""
"@
ffbi\t%0, %1, %2
ffb\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
(define_insn "unspec_ffmism"
[(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_FFMISM))]
""
"ffmism\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
(define_insn "unspec_flmism"
[(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_FLMISM))]
""
"flmism\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
;; SATURATION
(define_insn "unspec_kaddw"
[(set (match_operand:SI 0 "register_operand" "=r")
(ss_plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r")))]
""
"kaddw\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
(define_insn "unspec_ksubw"
[(set (match_operand:SI 0 "register_operand" "=r")
(ss_minus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r")))]
""
"ksubw\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
(define_insn "unspec_kaddh"
[(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_KADDH))]
""
"kaddh\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
(define_insn "unspec_ksubh"
[(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_KSUBH))]
""
"ksubh\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
(define_insn "unspec_kaddh_dsp"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r"))
(const_int 15)] UNSPEC_CLIPS))]
"NDS32_EXT_DSP_P ()"
"kaddh\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
(define_insn "unspec_ksubh_dsp"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(minus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r"))
(const_int 15)] UNSPEC_CLIPS))]
"NDS32_EXT_DSP_P ()"
"ksubh\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
(define_insn "unspec_kdmbb"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
(match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBB))]
""
"kdmbb\t%0, %1, %2"
[(set_attr "type" "mul")
(set_attr "length" "4")]
)
(define_insn "unspec_kdmbt"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
(match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBT))]
""
"kdmbt\t%0, %1, %2"
[(set_attr "type" "mul")
(set_attr "length" "4")]
)
(define_insn "unspec_kdmtb"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
(match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTB))]
""
"kdmtb\t%0, %1, %2"
[(set_attr "type" "mul")
(set_attr "length" "4")]
)
(define_insn "unspec_kdmtt"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
(match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTT))]
""
"kdmtt\t%0, %1, %2"
[(set_attr "type" "mul")
(set_attr "length" "4")]
)
(define_insn "unspec_khmbb"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
(match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBB))]
""
"khmbb\t%0, %1, %2"
[(set_attr "type" "mul")
(set_attr "length" "4")]
)
(define_insn "unspec_khmbt"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
(match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBT))]
""
"khmbt\t%0, %1, %2"
[(set_attr "type" "mul")
(set_attr "length" "4")]
)
(define_insn "unspec_khmtb"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
(match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTB))]
""
"khmtb\t%0, %1, %2"
[(set_attr "type" "mul")
(set_attr "length" "4")]
)
(define_insn "unspec_khmtt"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r")
(match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTT))]
""
"khmtt\t%0, %1, %2"
[(set_attr "type" "mul")
(set_attr "length" "4")]
)
(define_insn "unspec_kslraw"
[(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_KSLRAW))]
""
"kslraw\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
(define_insn "unspec_kslrawu"
[(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_KSLRAWU))]
""
"kslraw.u\t%0, %1, %2"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
(define_insn "unspec_volatile_rdov"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_RDOV))]
""
"rdov\t%0"
[(set_attr "type" "misc")
(set_attr "length" "4")]
)
(define_insn "unspec_volatile_clrov"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLROV)]
""
"clrov"
[(set_attr "type" "misc")
(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")]
)
;; TLBOP Intrinsic
(define_insn "unspec_tlbop_trd"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TRD)]
""
"tlbop\t%0, TRD"
[(set_attr "type" "mmu")]
)
(define_insn "unspec_tlbop_twr"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TWR)]
""
"tlbop\t%0, TWR"
[(set_attr "type" "mmu")]
)
(define_insn "unspec_tlbop_rwr"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWR)]
""
"tlbop\t%0, RWR"
[(set_attr "type" "mmu")]
)
(define_insn "unspec_tlbop_rwlk"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWLK)]
""
"tlbop\t%0, RWLK"
[(set_attr "type" "mmu")]
)
(define_insn "unspec_tlbop_unlk"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_UNLK)]
""
"tlbop\t%0, UNLK"
[(set_attr "type" "mmu")]
)
(define_insn "unspec_tlbop_pb"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_PB))]
""
"tlbop\t%0, %1, PB"
[(set_attr "type" "mmu")]
)
(define_insn "unspec_tlbop_inv"
[(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_INV)]
""
"tlbop\t%0, INV"
[(set_attr "type" "mmu")]
)
(define_insn "unspec_tlbop_flua"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_TLBOP_FLUA)]
""
"tlbop\tFLUA"
[(set_attr "type" "mmu")]
)
;;Unaligned Load/Store
(define_expand "unaligned_load_hw"
[(set (match_operand:HI 0 "register_operand" "")
(unspec:HI [(mem:HI (match_operand:SI 1 "register_operand" ""))] UNSPEC_UALOAD_HW))]
""
{
operands[0] = simplify_gen_subreg (SImode, operands[0],
GET_MODE (operands[0]), 0);
if (TARGET_ISA_V3M)
{
nds32_expand_unaligned_load (operands, HImode);
}
else
{
emit_insn (gen_unaligned_load_w (operands[0],
gen_rtx_MEM (SImode, operands[1])));
if (WORDS_BIG_ENDIAN)
emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT(16)));
else
emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0xffff)));
}
DONE;
})
(define_expand "unaligned_loadsi"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_W))]
""
{
if (flag_unaligned_access)
{
rtx mem = gen_rtx_MEM (SImode, operands[1]);
emit_move_insn (operands[0], mem);
}
else
{
if (TARGET_ISA_V3M)
nds32_expand_unaligned_load (operands, SImode);
else
emit_insn (gen_unaligned_load_w (operands[0],
gen_rtx_MEM (SImode, (operands[1]))));
}
DONE;
})
(define_insn "unaligned_load_w"
[(set (match_operand:SI 0 "register_operand" "= r")
(unspec:SI [(match_operand:SI 1 "nds32_lmw_smw_base_operand" " Umw")] UNSPEC_UALOAD_W))]
""
{
return nds32_output_lmw_single_word (operands);
}
[(set_attr "type" "load")
(set_attr "length" "4")]
)
(define_expand "unaligned_loaddi"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))]
""
{
if (TARGET_ISA_V3M)
{
nds32_expand_unaligned_load (operands, DImode);
}
else
emit_insn (gen_unaligned_load_dw (operands[0], operands[1]));
DONE;
})
(define_insn "unaligned_load_dw"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))]
""
{
rtx otherops[3];
otherops[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
otherops[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
otherops[2] = operands[1];
output_asm_insn ("lmw.bi\t%0, [%2], %1, 0", otherops);
return "";
}
[(set_attr "type" "load")
(set_attr "length" "4")]
)
(define_expand "unaligned_store_hw"
[(set (mem:SI (match_operand:SI 0 "register_operand" ""))
(unspec:HI [(match_operand:HI 1 "register_operand" "")] UNSPEC_UASTORE_HW))]
""
{
operands[1] = simplify_gen_subreg (SImode, operands[1],
GET_MODE (operands[1]), 0);
nds32_expand_unaligned_store (operands, HImode);
DONE;
})
(define_expand "unaligned_storesi"
[(set (mem:SI (match_operand:SI 0 "register_operand" "r"))
(unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_UASTORE_W))]
""
{
if (flag_unaligned_access)
{
rtx mem = gen_rtx_MEM (SImode, operands[0]);
emit_move_insn (mem, operands[1]);
}
else
{
if (TARGET_ISA_V3M)
nds32_expand_unaligned_store (operands, SImode);
else
emit_insn (gen_unaligned_store_w (gen_rtx_MEM (SImode, operands[0]),
operands[1]));
}
DONE;
})
(define_insn "unaligned_store_w"
[(set (match_operand:SI 0 "nds32_lmw_smw_base_operand" "=Umw")
(unspec:SI [(match_operand:SI 1 "register_operand" " r")] UNSPEC_UASTORE_W))]
""
{
return nds32_output_smw_single_word (operands);
}
[(set_attr "type" "store")
(set_attr "length" "4")]
)
(define_expand "unaligned_storedi"
[(set (mem:DI (match_operand:SI 0 "register_operand" "r"))
(unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_UASTORE_DW))]
""
{
if (TARGET_ISA_V3M)
nds32_expand_unaligned_store (operands, DImode);
else
emit_insn (gen_unaligned_store_dw (gen_rtx_MEM (DImode, operands[0]),
operands[1]));
DONE;
})
(define_insn "unaligned_store_dw"
[(set (match_operand:DI 0 "nds32_lmw_smw_base_operand" "=Umw")
(unspec:DI [(match_operand:DI 1 "register_operand" " r")] UNSPEC_UASTORE_DW))]
""
{
return nds32_output_smw_double_word (operands);
}
[(set_attr "type" "store")
(set_attr "length" "4")]
)
(define_expand "unspec_unaligned_feature"
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE))]
""
{
/* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */
rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__);
rtx temp_reg = gen_reg_rtx (SImode);
rtx temp2_reg = gen_reg_rtx (SImode);
emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
emit_move_insn (temp_reg, operands[0]);
emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
emit_insn (gen_iorsi3 (operands[0], operands[0], temp2_reg));
emit_insn (gen_unspec_volatile_mtsr (operands[0], system_reg));
emit_insn (gen_unspec_dsb ());
emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (8)));
emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
DONE;
})
(define_expand "unspec_enable_unaligned"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)]
""
{
/* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */
rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__);
rtx temp_reg = gen_reg_rtx (SImode);
rtx temp2_reg = gen_reg_rtx (SImode);
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
emit_insn (gen_iorsi3 (temp_reg, temp_reg, temp2_reg));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
DONE;
})
(define_expand "unspec_disable_unaligned"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)]
""
{
/* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */
rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__);
rtx temp_reg = gen_reg_rtx (SImode);
rtx temp2_reg = gen_reg_rtx (SImode);
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
emit_insn (gen_one_cmplsi2 (temp2_reg, temp2_reg));
emit_insn (gen_andsi3 (temp_reg, temp_reg, temp2_reg));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
DONE;
})
;; abs alias kabs
(define_insn "unspec_kabs"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_KABS))]
""
"kabs\t%0, %1"
[(set_attr "type" "alu")
(set_attr "length" "4")]
)
;; ------------------------------------------------------------------------