Commit 7c32ef41 by Monk Chiang Committed by Chung-Ju Wu

[NDS32] Add DSP extension instructions.

gcc/
	* config.gcc (nds32be-*-*): Handle --with-ext-dsp.
	* config/nds32/constants.md (unspec_element, unspec_volatile_element):
	Add enum values for DSP extension instructions.
	* config/nds32/constraints.md (Iu06, IU06, CVp5, CVs5, CVs2, CVhi):
	New constraints.
	* config/nds32/iterators.md (shifts, shiftrt, sat_plus, all_plus,
	sat_minus, all_minus, plus_minus, extend, sumax, sumin, sumin_max):
	New code iterators.
	(su, zs, uk, opcode, add_rsub, add_sub): New code attributes.
	* config/nds32/nds32-dspext.md: New file for DSP implementation.
	* config/nds32/nds32-intrinsic.c: Implementation of DSP extension.
	* config/nds32/nds32-intrinsic.md: Likewise.
	* config/nds32/nds32_intrinsic.h: Likewise.
	* config/nds32/nds32-md-auxiliary.c: Likewise.
	* config/nds32/nds32-memory-manipulation.c: Consider DSP extension.
	* config/nds32/nds32-predicates.c (const_vector_to_hwint): New.
	(nds32_valid_CVp5_p, nds32_valid_CVs5_p): New.
	(nds32_valid_CVs2_p, nds32_valid_CVhi_p): New.
	* config/nds32/nds32-protos.h: New declarations for DSP extension.
	* config/nds32/nds32-utils.c (extract_mac_non_acc_rtx): New case
	TYPE_DMAC in switch statement.
	* config/nds32/nds32.c: New checking and implementation for DSP
	extension instructions.
	* config/nds32/nds32.h: Likewise.
	* config/nds32/nds32.md: Likewise.
	* config/nds32/nds32.opt (mhw-abs, mext-dsp): New options.
	* config/nds32/predicates.md: Implement new predicates for DSP
	extension.

Co-Authored-By: Chung-Ju Wu <jasonwucj@gmail.com>
Co-Authored-By: Kito Cheng <kito.cheng@gmail.com>

From-SVN: r260206
parent ab22e6ce
2018-05-13 Monk Chiang <sh.chiang04@gmail.com>
Kito Cheng <kito.cheng@gmail.com>
Chung-Ju Wu <jasonwucj@gmail.com>
* config.gcc (nds32be-*-*): Handle --with-ext-dsp.
* config/nds32/constants.md (unspec_element, unspec_volatile_element):
Add enum values for DSP extension instructions.
* config/nds32/constraints.md (Iu06, IU06, CVp5, CVs5, CVs2, CVhi):
New constraints.
* config/nds32/iterators.md (shifts, shiftrt, sat_plus, all_plus,
sat_minus, all_minus, plus_minus, extend, sumax, sumin, sumin_max):
New code iterators.
(su, zs, uk, opcode, add_rsub, add_sub): New code attributes.
* config/nds32/nds32-dspext.md: New file for DSP implementation.
* config/nds32/nds32-intrinsic.c: Implementation of DSP extension.
* config/nds32/nds32-intrinsic.md: Likewise.
* config/nds32/nds32_intrinsic.h: Likewise.
* config/nds32/nds32-md-auxiliary.c: Likewise.
* config/nds32/nds32-memory-manipulation.c: Consider DSP extension.
* config/nds32/nds32-predicates.c (const_vector_to_hwint): New.
(nds32_valid_CVp5_p, nds32_valid_CVs5_p): New.
(nds32_valid_CVs2_p, nds32_valid_CVhi_p): New.
* config/nds32/nds32-protos.h: New declarations for DSP extension.
* config/nds32/nds32-utils.c (extract_mac_non_acc_rtx): New case
TYPE_DMAC in switch statement.
* config/nds32/nds32.c: New checking and implementation for DSP
extension instructions.
* config/nds32/nds32.h: Likewise.
* config/nds32/nds32.md: Likewise.
* config/nds32/nds32.opt (mhw-abs, mext-dsp): New options.
* config/nds32/predicates.md: Implement new predicates for DSP
extension.
2018-05-11 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.md (mov<mode>_softfloat, FMOVE32):
......
......@@ -2346,6 +2346,11 @@ nds32be-*-*)
tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} nds32/nds32_intrinsic.h"
tmake_file="nds32/t-nds32 nds32/t-mlibs"
# Handle --with-ext-dsp
if test x${with_ext_dsp} = xyes; then
tm_defines="${tm_defines} TARGET_DEFAULT_EXT_DSP=1"
fi
;;
nios2-*-*)
tm_file="elfos.h ${tm_file}"
......
......@@ -49,6 +49,16 @@
UNSPEC_FFB
UNSPEC_FFMISM
UNSPEC_FLMISM
UNSPEC_KDMBB
UNSPEC_KDMBT
UNSPEC_KDMTB
UNSPEC_KDMTT
UNSPEC_KHMBB
UNSPEC_KHMBT
UNSPEC_KHMTB
UNSPEC_KHMTT
UNSPEC_KSLRAW
UNSPEC_KSLRAWU
UNSPEC_SVA
UNSPEC_SVS
UNSPEC_WSBH
......@@ -62,6 +72,19 @@
UNSPEC_UASTORE_HW
UNSPEC_UASTORE_W
UNSPEC_UASTORE_DW
UNSPEC_ROUND
UNSPEC_VEC_COMPARE
UNSPEC_KHM
UNSPEC_KHMX
UNSPEC_CLIP_OV
UNSPEC_CLIPS_OV
UNSPEC_BITREV
UNSPEC_KABS
UNSPEC_LOOP_END
UNSPEC_TLS_DESC
UNSPEC_TLS_IE
UNSPEC_KADDH
UNSPEC_KSUBH
])
;; The unspec_volatile operation index.
......@@ -139,6 +162,8 @@
UNSPEC_VOLATILE_UNALIGNED_FEATURE
UNSPEC_VOLATILE_ENABLE_UNALIGNED
UNSPEC_VOLATILE_DISABLE_UNALIGNED
UNSPEC_VOLATILE_RDOV
UNSPEC_VOLATILE_CLROV
])
;; ------------------------------------------------------------------------
......@@ -127,6 +127,11 @@
(and (match_code "const_int")
(match_test "IN_RANGE (ival, -31, 0)")))
(define_constraint "Iu06"
"Unsigned immediate 6-bit value"
(and (match_code "const_int")
(match_test "ival < (1 << 6) && ival >= 0")))
;; Ip05 is special and dedicated for v3 movpi45 instruction.
;; movpi45 has imm5u field but the range is 16 ~ 47.
(define_constraint "Ip05"
......@@ -136,10 +141,10 @@
&& ival >= (0 + 16)
&& (TARGET_ISA_V3 || TARGET_ISA_V3M)")))
(define_constraint "Iu06"
(define_constraint "IU06"
"Unsigned immediate 6-bit value constraint for addri36.sp instruction"
(and (match_code "const_int")
(match_test "ival < (1 << 6)
(match_test "ival < (1 << 8)
&& ival >= 0
&& (ival % 4 == 0)
&& (TARGET_ISA_V3 || TARGET_ISA_V3M)")))
......@@ -302,6 +307,25 @@
(match_test "(TARGET_ISA_V3 || TARGET_ISA_V3M)
&& (IN_RANGE (exact_log2 (ival + 1), 1, 8))")))
(define_constraint "CVp5"
"Unsigned immediate 5-bit value for movpi45 instruction with range 16-47"
(and (match_code "const_vector")
(match_test "nds32_valid_CVp5_p (op)")))
(define_constraint "CVs5"
"Signed immediate 5-bit value"
(and (match_code "const_vector")
(match_test "nds32_valid_CVs5_p (op)")))
(define_constraint "CVs2"
"Signed immediate 20-bit value"
(and (match_code "const_vector")
(match_test "nds32_valid_CVs2_p (op)")))
(define_constraint "CVhi"
"The immediate value that can be simply set high 20-bit"
(and (match_code "const_vector")
(match_test "nds32_valid_CVhi_p (op)")))
(define_memory_constraint "U33"
"Memory constraint for 333 format"
......
......@@ -68,6 +68,28 @@
;; shifts
(define_code_iterator shift_rotate [ashift ashiftrt lshiftrt rotatert])
(define_code_iterator shifts [ashift ashiftrt lshiftrt])
(define_code_iterator shiftrt [ashiftrt lshiftrt])
(define_code_iterator sat_plus [ss_plus us_plus])
(define_code_iterator all_plus [plus ss_plus us_plus])
(define_code_iterator sat_minus [ss_minus us_minus])
(define_code_iterator all_minus [minus ss_minus us_minus])
(define_code_iterator plus_minus [plus minus])
(define_code_iterator extend [sign_extend zero_extend])
(define_code_iterator sumax [smax umax])
(define_code_iterator sumin [smin umin])
(define_code_iterator sumin_max [smax umax smin umin])
;;----------------------------------------------------------------------------
;; Code attributes.
;;----------------------------------------------------------------------------
......@@ -76,5 +98,23 @@
(define_code_attr shift
[(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr") (rotatert "rotr")])
(define_code_attr su
[(ashiftrt "") (lshiftrt "u") (sign_extend "s") (zero_extend "u")])
(define_code_attr zs
[(sign_extend "s") (zero_extend "z")])
(define_code_attr uk
[(plus "") (ss_plus "k") (us_plus "uk")
(minus "") (ss_minus "k") (us_minus "uk")])
(define_code_attr opcode
[(plus "add") (minus "sub") (smax "smax") (umax "umax") (smin "smin") (umin "umin")])
(define_code_attr add_rsub
[(plus "a") (minus "rs")])
(define_code_attr add_sub
[(plus "a") (minus "s")])
;;----------------------------------------------------------------------------
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1037,6 +1037,187 @@
(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"
......@@ -1495,4 +1676,15 @@
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")]
)
;; ------------------------------------------------------------------------
......@@ -449,29 +449,44 @@ nds32_gen_dup_4_byte_to_word_value (rtx value)
}
else
{
/* ! prepare word
andi $tmp1, $value, 0xff ! $tmp1 <- 0x000000ab
slli $tmp2, $tmp1, 8 ! $tmp2 <- 0x0000ab00
or $tmp3, $tmp1, $tmp2 ! $tmp3 <- 0x0000abab
slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000
or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab */
rtx tmp1, tmp2, tmp3, tmp4, final_value;
tmp1 = expand_binop (SImode, and_optab, value,
gen_int_mode (0xff, SImode),
NULL_RTX, 0, OPTAB_WIDEN);
tmp2 = expand_binop (SImode, ashl_optab, tmp1,
gen_int_mode (8, SImode),
NULL_RTX, 0, OPTAB_WIDEN);
tmp3 = expand_binop (SImode, ior_optab, tmp1, tmp2,
NULL_RTX, 0, OPTAB_WIDEN);
tmp4 = expand_binop (SImode, ashl_optab, tmp3,
gen_int_mode (16, SImode),
NULL_RTX, 0, OPTAB_WIDEN);
final_value = expand_binop (SImode, ior_optab, tmp3, tmp4,
NULL_RTX, 0, OPTAB_WIDEN);
emit_move_insn (value4word, final_value);
if (NDS32_EXT_DSP_P ())
{
/* ! prepare word
insb $tmp, $value, 1 ! $tmp <- 0x0000abab
pkbb16 $tmp6, $tmp2, $tmp2 ! $value4word <- 0xabababab */
rtx tmp = gen_reg_rtx (SImode);
convert_move (tmp, value, true);
emit_insn (
gen_insvsi_internal (tmp, gen_int_mode (0x8, SImode), tmp));
emit_insn (gen_pkbbsi_1 (value4word, tmp, tmp));
}
else
{
/* ! prepare word
andi $tmp1, $value, 0xff ! $tmp1 <- 0x000000ab
slli $tmp2, $tmp1, 8 ! $tmp2 <- 0x0000ab00
or $tmp3, $tmp1, $tmp2 ! $tmp3 <- 0x0000abab
slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000
or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab */
rtx tmp1, tmp2, tmp3, tmp4;
tmp1 = expand_binop (SImode, and_optab, value,
gen_int_mode (0xff, SImode),
NULL_RTX, 0, OPTAB_WIDEN);
tmp2 = expand_binop (SImode, ashl_optab, tmp1,
gen_int_mode (8, SImode),
NULL_RTX, 0, OPTAB_WIDEN);
tmp3 = expand_binop (SImode, ior_optab, tmp1, tmp2,
NULL_RTX, 0, OPTAB_WIDEN);
tmp4 = expand_binop (SImode, ashl_optab, tmp3,
gen_int_mode (16, SImode),
NULL_RTX, 0, OPTAB_WIDEN);
emit_insn (gen_iorsi3 (value4word, tmp3, tmp4));
}
}
return value4word;
......
......@@ -518,4 +518,81 @@ nds32_const_double_range_ok_p (rtx op, machine_mode mode,
return val >= lower && val < upper;
}
HOST_WIDE_INT
const_vector_to_hwint (rtx op)
{
HOST_WIDE_INT hwint = 0;
HOST_WIDE_INT mask;
int i;
int shift_adv;
int shift = 0;
int nelem;
switch (GET_MODE (op))
{
case V2HImode:
mask = 0xffff;
shift_adv = 16;
nelem = 2;
break;
case V4QImode:
mask = 0xff;
shift_adv = 8;
nelem = 4;
break;
default:
gcc_unreachable ();
}
if (TARGET_BIG_ENDIAN)
{
for (i = 0; i < nelem; ++i)
{
HOST_WIDE_INT val = XINT (XVECEXP (op, 0, nelem - i - 1), 0);
hwint |= (val & mask) << shift;
shift = shift + shift_adv;
}
}
else
{
for (i = 0; i < nelem; ++i)
{
HOST_WIDE_INT val = XINT (XVECEXP (op, 0, i), 0);
hwint |= (val & mask) << shift;
shift = shift + shift_adv;
}
}
return hwint;
}
bool
nds32_valid_CVp5_p (rtx op)
{
HOST_WIDE_INT ival = const_vector_to_hwint (op);
return (ival < ((1 << 5) + 16)) && (ival >= (0 + 16));
}
bool
nds32_valid_CVs5_p (rtx op)
{
HOST_WIDE_INT ival = const_vector_to_hwint (op);
return (ival < (1 << 4)) && (ival >= -(1 << 4));
}
bool
nds32_valid_CVs2_p (rtx op)
{
HOST_WIDE_INT ival = const_vector_to_hwint (op);
return (ival < (1 << 19)) && (ival >= -(1 << 19));
}
bool
nds32_valid_CVhi_p (rtx op)
{
HOST_WIDE_INT ival = const_vector_to_hwint (op);
return (ival != 0) && ((ival & 0xfff) == 0);
}
/* ------------------------------------------------------------------------ */
......@@ -73,6 +73,11 @@ extern unsigned int nds32_dbx_register_number (unsigned int);
extern bool nds32_valid_smw_lwm_base_p (rtx);
/* Auxiliary functions for manipulation DI mode. */
extern rtx nds32_di_high_part_subreg(rtx);
extern rtx nds32_di_low_part_subreg(rtx);
/* Auxiliary functions for expanding rtl used in nds32-multiple.md. */
extern rtx nds32_expand_load_multiple (int, int, rtx, rtx, bool, rtx *);
......@@ -159,6 +164,10 @@ extern void nds32_expand_float_cstore (rtx *);
extern enum nds32_expand_result_type nds32_expand_movcc (rtx *);
extern void nds32_expand_float_movcc (rtx *);
/* Auxiliary functions for expand extv/insv instruction. */
extern enum nds32_expand_result_type nds32_expand_extv (rtx *);
extern enum nds32_expand_result_type nds32_expand_insv (rtx *);
/* Auxiliary functions to identify long-call symbol. */
extern bool nds32_long_call_p (rtx);
......@@ -193,6 +202,8 @@ extern const char *nds32_output_cbranchsi4_equality_reg_or_const_int (rtx_insn *
rtx *);
extern const char *nds32_output_cbranchsi4_greater_less_zero (rtx_insn *, rtx *);
extern const char *nds32_output_unpkd8 (rtx, rtx, rtx, rtx, bool);
extern const char *nds32_output_call (rtx, rtx *, rtx,
const char *, const char *, bool);
......@@ -203,9 +214,19 @@ extern const char *nds32_output_stack_push (rtx);
extern const char *nds32_output_stack_pop (rtx);
extern const char *nds32_output_return (void);
/* Auxiliary functions to split/output sms pattern. */
extern bool nds32_need_split_sms_p (rtx, rtx, rtx, rtx);
extern const char *nds32_output_sms (rtx, rtx, rtx, rtx);
extern void nds32_split_sms (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
/* Auxiliary functions to split double word RTX pattern. */
extern void nds32_spilt_doubleword (rtx *, bool);
extern void nds32_split_ashiftdi3 (rtx, rtx, rtx);
extern void nds32_split_ashiftrtdi3 (rtx, rtx, rtx);
extern void nds32_split_lshiftrtdi3 (rtx, rtx, rtx);
extern void nds32_split_rotatertdi3 (rtx, rtx, rtx);
/* Auxiliary functions to split large constant RTX pattern. */
......@@ -246,6 +267,14 @@ extern int nds32_address_cost_impl (rtx, machine_mode, addr_space_t, bool);
/* Auxiliary functions for pre-define marco. */
extern void nds32_cpu_cpp_builtins(struct cpp_reader *);
/* Auxiliary functions for const_vector's constraints. */
extern HOST_WIDE_INT const_vector_to_hwint (rtx);
extern bool nds32_valid_CVp5_p (rtx);
extern bool nds32_valid_CVs5_p (rtx);
extern bool nds32_valid_CVs2_p (rtx);
extern bool nds32_valid_CVhi_p (rtx);
extern bool nds32_split_double_word_load_store_p (rtx *,bool);
namespace nds32 {
......
......@@ -413,6 +413,7 @@ extract_mac_non_acc_rtx (rtx_insn *insn)
switch (get_attr_type (insn))
{
case TYPE_MAC:
case TYPE_DMAC:
if (REG_P (XEXP (exp, 0)))
return XEXP (exp, 1);
else
......
......@@ -1987,6 +1987,16 @@ nds32_function_arg_boundary (machine_mode mode, const_tree type)
: PARM_BOUNDARY);
}
bool
nds32_vector_mode_supported_p (machine_mode mode)
{
if (mode == V4QImode
|| mode == V2HImode)
return NDS32_EXT_DSP_P ();
return false;
}
/* -- How Scalar Function Values Are Returned. */
static rtx
......@@ -2688,6 +2698,23 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict)
}
}
static machine_mode
nds32_vectorize_preferred_simd_mode (scalar_mode mode)
{
if (!NDS32_EXT_DSP_P ())
return word_mode;
switch (mode)
{
case E_QImode:
return V4QImode;
case E_HImode:
return V2HImode;
default:
return word_mode;
}
}
/* Condition Code Status. */
......@@ -2978,6 +3005,18 @@ nds32_print_operand (FILE *stream, rtx x, int code)
/* No need to handle following process, so return immediately. */
return;
case 'v':
gcc_assert (CONST_INT_P (x)
&& (INTVAL (x) == 0
|| INTVAL (x) == 8
|| INTVAL (x) == 16
|| INTVAL (x) == 24));
fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
/* No need to handle following process, so return immediately. */
return;
case 'B':
/* Use exact_log2() to search the 1-bit position. */
gcc_assert (CONST_INT_P (x));
......@@ -3168,6 +3207,10 @@ nds32_print_operand (FILE *stream, rtx x, int code)
output_addr_const (stream, x);
break;
case CONST_VECTOR:
fprintf (stream, HOST_WIDE_INT_PRINT_HEX, const_vector_to_hwint (x));
break;
default:
/* Generally, output_addr_const () is able to handle most cases.
We want to see what CODE could appear,
......@@ -3260,6 +3303,20 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x)
reg_names[REGNO (XEXP (op0, 0))],
sv);
}
else if (GET_CODE (op0) == ASHIFT && REG_P (op1))
{
/* [Ra + Rb << sv]
In normal, ASHIFT can be converted to MULT like above case.
But when the address rtx does not go through canonicalize_address
defined in fwprop, we'll need this case. */
int sv = INTVAL (XEXP (op0, 1));
gcc_assert (sv <= 3 && sv >=0);
fprintf (stream, "[%s + %s << %d]",
reg_names[REGNO (op1)],
reg_names[REGNO (XEXP (op0, 0))],
sv);
}
else
{
/* The control flow is not supposed to be here. */
......@@ -3770,6 +3827,8 @@ nds32_cpu_cpp_builtins(struct cpp_reader *pfile)
builtin_define ("__NDS32_GP_DIRECT__");
if (TARGET_VH)
builtin_define ("__NDS32_VH__");
if (NDS32_EXT_DSP_P ())
builtin_define ("__NDS32_EXT_DSP__");
if (TARGET_BIG_ENDIAN)
builtin_define ("__big_endian__");
......@@ -5010,6 +5069,9 @@ nds32_use_blocks_for_constant_p (machine_mode mode,
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P nds32_vector_mode_supported_p
/* -- How Scalar Function Values Are Returned. */
#undef TARGET_FUNCTION_VALUE
......@@ -5087,6 +5149,9 @@ nds32_use_blocks_for_constant_p (machine_mode mode,
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE nds32_vectorize_preferred_simd_mode
/* Anchored Addresses. */
......
......@@ -140,6 +140,9 @@ enum nds32_16bit_address_type
Check gcc/common/config/nds32/nds32-common.c for the optimizations that
apply -malways-align. */
#define NDS32_ALIGN_P() (TARGET_ALWAYS_ALIGN)
#define NDS32_EXT_DSP_P() (TARGET_EXT_DSP && !TARGET_FORCE_NO_EXT_DSP)
/* Get alignment according to mode or type information.
When 'type' is nonnull, there is no need to look at 'mode'. */
#define NDS32_MODE_TYPE_ALIGN(mode, type) \
......@@ -439,7 +442,30 @@ enum nds32_builtins
NDS32_BUILTIN_FFB,
NDS32_BUILTIN_FFMISM,
NDS32_BUILTIN_FLMISM,
NDS32_BUILTIN_KADDW,
NDS32_BUILTIN_KSUBW,
NDS32_BUILTIN_KADDH,
NDS32_BUILTIN_KSUBH,
NDS32_BUILTIN_KDMBB,
NDS32_BUILTIN_V_KDMBB,
NDS32_BUILTIN_KDMBT,
NDS32_BUILTIN_V_KDMBT,
NDS32_BUILTIN_KDMTB,
NDS32_BUILTIN_V_KDMTB,
NDS32_BUILTIN_KDMTT,
NDS32_BUILTIN_V_KDMTT,
NDS32_BUILTIN_KHMBB,
NDS32_BUILTIN_V_KHMBB,
NDS32_BUILTIN_KHMBT,
NDS32_BUILTIN_V_KHMBT,
NDS32_BUILTIN_KHMTB,
NDS32_BUILTIN_V_KHMTB,
NDS32_BUILTIN_KHMTT,
NDS32_BUILTIN_V_KHMTT,
NDS32_BUILTIN_KSLRAW,
NDS32_BUILTIN_KSLRAW_U,
NDS32_BUILTIN_RDOV,
NDS32_BUILTIN_CLROV,
NDS32_BUILTIN_ROTR,
NDS32_BUILTIN_SVA,
NDS32_BUILTIN_SVS,
......@@ -512,7 +538,295 @@ enum nds32_builtins
NDS32_BUILTIN_SET_TRIG_LEVEL,
NDS32_BUILTIN_SET_TRIG_EDGE,
NDS32_BUILTIN_GET_TRIG_TYPE,
NDS32_BUILTIN_DSP_BEGIN,
NDS32_BUILTIN_ADD16,
NDS32_BUILTIN_V_UADD16,
NDS32_BUILTIN_V_SADD16,
NDS32_BUILTIN_RADD16,
NDS32_BUILTIN_V_RADD16,
NDS32_BUILTIN_URADD16,
NDS32_BUILTIN_V_URADD16,
NDS32_BUILTIN_KADD16,
NDS32_BUILTIN_V_KADD16,
NDS32_BUILTIN_UKADD16,
NDS32_BUILTIN_V_UKADD16,
NDS32_BUILTIN_SUB16,
NDS32_BUILTIN_V_USUB16,
NDS32_BUILTIN_V_SSUB16,
NDS32_BUILTIN_RSUB16,
NDS32_BUILTIN_V_RSUB16,
NDS32_BUILTIN_URSUB16,
NDS32_BUILTIN_V_URSUB16,
NDS32_BUILTIN_KSUB16,
NDS32_BUILTIN_V_KSUB16,
NDS32_BUILTIN_UKSUB16,
NDS32_BUILTIN_V_UKSUB16,
NDS32_BUILTIN_CRAS16,
NDS32_BUILTIN_V_UCRAS16,
NDS32_BUILTIN_V_SCRAS16,
NDS32_BUILTIN_RCRAS16,
NDS32_BUILTIN_V_RCRAS16,
NDS32_BUILTIN_URCRAS16,
NDS32_BUILTIN_V_URCRAS16,
NDS32_BUILTIN_KCRAS16,
NDS32_BUILTIN_V_KCRAS16,
NDS32_BUILTIN_UKCRAS16,
NDS32_BUILTIN_V_UKCRAS16,
NDS32_BUILTIN_CRSA16,
NDS32_BUILTIN_V_UCRSA16,
NDS32_BUILTIN_V_SCRSA16,
NDS32_BUILTIN_RCRSA16,
NDS32_BUILTIN_V_RCRSA16,
NDS32_BUILTIN_URCRSA16,
NDS32_BUILTIN_V_URCRSA16,
NDS32_BUILTIN_KCRSA16,
NDS32_BUILTIN_V_KCRSA16,
NDS32_BUILTIN_UKCRSA16,
NDS32_BUILTIN_V_UKCRSA16,
NDS32_BUILTIN_ADD8,
NDS32_BUILTIN_V_UADD8,
NDS32_BUILTIN_V_SADD8,
NDS32_BUILTIN_RADD8,
NDS32_BUILTIN_V_RADD8,
NDS32_BUILTIN_URADD8,
NDS32_BUILTIN_V_URADD8,
NDS32_BUILTIN_KADD8,
NDS32_BUILTIN_V_KADD8,
NDS32_BUILTIN_UKADD8,
NDS32_BUILTIN_V_UKADD8,
NDS32_BUILTIN_SUB8,
NDS32_BUILTIN_V_USUB8,
NDS32_BUILTIN_V_SSUB8,
NDS32_BUILTIN_RSUB8,
NDS32_BUILTIN_V_RSUB8,
NDS32_BUILTIN_URSUB8,
NDS32_BUILTIN_V_URSUB8,
NDS32_BUILTIN_KSUB8,
NDS32_BUILTIN_V_KSUB8,
NDS32_BUILTIN_UKSUB8,
NDS32_BUILTIN_V_UKSUB8,
NDS32_BUILTIN_SRA16,
NDS32_BUILTIN_V_SRA16,
NDS32_BUILTIN_SRA16_U,
NDS32_BUILTIN_V_SRA16_U,
NDS32_BUILTIN_SRL16,
NDS32_BUILTIN_V_SRL16,
NDS32_BUILTIN_SRL16_U,
NDS32_BUILTIN_V_SRL16_U,
NDS32_BUILTIN_SLL16,
NDS32_BUILTIN_V_SLL16,
NDS32_BUILTIN_KSLL16,
NDS32_BUILTIN_V_KSLL16,
NDS32_BUILTIN_KSLRA16,
NDS32_BUILTIN_V_KSLRA16,
NDS32_BUILTIN_KSLRA16_U,
NDS32_BUILTIN_V_KSLRA16_U,
NDS32_BUILTIN_CMPEQ16,
NDS32_BUILTIN_V_SCMPEQ16,
NDS32_BUILTIN_V_UCMPEQ16,
NDS32_BUILTIN_SCMPLT16,
NDS32_BUILTIN_V_SCMPLT16,
NDS32_BUILTIN_SCMPLE16,
NDS32_BUILTIN_V_SCMPLE16,
NDS32_BUILTIN_UCMPLT16,
NDS32_BUILTIN_V_UCMPLT16,
NDS32_BUILTIN_UCMPLE16,
NDS32_BUILTIN_V_UCMPLE16,
NDS32_BUILTIN_CMPEQ8,
NDS32_BUILTIN_V_SCMPEQ8,
NDS32_BUILTIN_V_UCMPEQ8,
NDS32_BUILTIN_SCMPLT8,
NDS32_BUILTIN_V_SCMPLT8,
NDS32_BUILTIN_SCMPLE8,
NDS32_BUILTIN_V_SCMPLE8,
NDS32_BUILTIN_UCMPLT8,
NDS32_BUILTIN_V_UCMPLT8,
NDS32_BUILTIN_UCMPLE8,
NDS32_BUILTIN_V_UCMPLE8,
NDS32_BUILTIN_SMIN16,
NDS32_BUILTIN_V_SMIN16,
NDS32_BUILTIN_UMIN16,
NDS32_BUILTIN_V_UMIN16,
NDS32_BUILTIN_SMAX16,
NDS32_BUILTIN_V_SMAX16,
NDS32_BUILTIN_UMAX16,
NDS32_BUILTIN_V_UMAX16,
NDS32_BUILTIN_SCLIP16,
NDS32_BUILTIN_V_SCLIP16,
NDS32_BUILTIN_UCLIP16,
NDS32_BUILTIN_V_UCLIP16,
NDS32_BUILTIN_KHM16,
NDS32_BUILTIN_V_KHM16,
NDS32_BUILTIN_KHMX16,
NDS32_BUILTIN_V_KHMX16,
NDS32_BUILTIN_KABS16,
NDS32_BUILTIN_V_KABS16,
NDS32_BUILTIN_SMIN8,
NDS32_BUILTIN_V_SMIN8,
NDS32_BUILTIN_UMIN8,
NDS32_BUILTIN_V_UMIN8,
NDS32_BUILTIN_SMAX8,
NDS32_BUILTIN_V_SMAX8,
NDS32_BUILTIN_UMAX8,
NDS32_BUILTIN_V_UMAX8,
NDS32_BUILTIN_KABS8,
NDS32_BUILTIN_V_KABS8,
NDS32_BUILTIN_SUNPKD810,
NDS32_BUILTIN_V_SUNPKD810,
NDS32_BUILTIN_SUNPKD820,
NDS32_BUILTIN_V_SUNPKD820,
NDS32_BUILTIN_SUNPKD830,
NDS32_BUILTIN_V_SUNPKD830,
NDS32_BUILTIN_SUNPKD831,
NDS32_BUILTIN_V_SUNPKD831,
NDS32_BUILTIN_ZUNPKD810,
NDS32_BUILTIN_V_ZUNPKD810,
NDS32_BUILTIN_ZUNPKD820,
NDS32_BUILTIN_V_ZUNPKD820,
NDS32_BUILTIN_ZUNPKD830,
NDS32_BUILTIN_V_ZUNPKD830,
NDS32_BUILTIN_ZUNPKD831,
NDS32_BUILTIN_V_ZUNPKD831,
NDS32_BUILTIN_RADDW,
NDS32_BUILTIN_URADDW,
NDS32_BUILTIN_RSUBW,
NDS32_BUILTIN_URSUBW,
NDS32_BUILTIN_SRA_U,
NDS32_BUILTIN_KSLL,
NDS32_BUILTIN_PKBB16,
NDS32_BUILTIN_V_PKBB16,
NDS32_BUILTIN_PKBT16,
NDS32_BUILTIN_V_PKBT16,
NDS32_BUILTIN_PKTB16,
NDS32_BUILTIN_V_PKTB16,
NDS32_BUILTIN_PKTT16,
NDS32_BUILTIN_V_PKTT16,
NDS32_BUILTIN_SMMUL,
NDS32_BUILTIN_SMMUL_U,
NDS32_BUILTIN_KMMAC,
NDS32_BUILTIN_KMMAC_U,
NDS32_BUILTIN_KMMSB,
NDS32_BUILTIN_KMMSB_U,
NDS32_BUILTIN_KWMMUL,
NDS32_BUILTIN_KWMMUL_U,
NDS32_BUILTIN_SMMWB,
NDS32_BUILTIN_V_SMMWB,
NDS32_BUILTIN_SMMWB_U,
NDS32_BUILTIN_V_SMMWB_U,
NDS32_BUILTIN_SMMWT,
NDS32_BUILTIN_V_SMMWT,
NDS32_BUILTIN_SMMWT_U,
NDS32_BUILTIN_V_SMMWT_U,
NDS32_BUILTIN_KMMAWB,
NDS32_BUILTIN_V_KMMAWB,
NDS32_BUILTIN_KMMAWB_U,
NDS32_BUILTIN_V_KMMAWB_U,
NDS32_BUILTIN_KMMAWT,
NDS32_BUILTIN_V_KMMAWT,
NDS32_BUILTIN_KMMAWT_U,
NDS32_BUILTIN_V_KMMAWT_U,
NDS32_BUILTIN_SMBB,
NDS32_BUILTIN_V_SMBB,
NDS32_BUILTIN_SMBT,
NDS32_BUILTIN_V_SMBT,
NDS32_BUILTIN_SMTT,
NDS32_BUILTIN_V_SMTT,
NDS32_BUILTIN_KMDA,
NDS32_BUILTIN_V_KMDA,
NDS32_BUILTIN_KMXDA,
NDS32_BUILTIN_V_KMXDA,
NDS32_BUILTIN_SMDS,
NDS32_BUILTIN_V_SMDS,
NDS32_BUILTIN_SMDRS,
NDS32_BUILTIN_V_SMDRS,
NDS32_BUILTIN_SMXDS,
NDS32_BUILTIN_V_SMXDS,
NDS32_BUILTIN_KMABB,
NDS32_BUILTIN_V_KMABB,
NDS32_BUILTIN_KMABT,
NDS32_BUILTIN_V_KMABT,
NDS32_BUILTIN_KMATT,
NDS32_BUILTIN_V_KMATT,
NDS32_BUILTIN_KMADA,
NDS32_BUILTIN_V_KMADA,
NDS32_BUILTIN_KMAXDA,
NDS32_BUILTIN_V_KMAXDA,
NDS32_BUILTIN_KMADS,
NDS32_BUILTIN_V_KMADS,
NDS32_BUILTIN_KMADRS,
NDS32_BUILTIN_V_KMADRS,
NDS32_BUILTIN_KMAXDS,
NDS32_BUILTIN_V_KMAXDS,
NDS32_BUILTIN_KMSDA,
NDS32_BUILTIN_V_KMSDA,
NDS32_BUILTIN_KMSXDA,
NDS32_BUILTIN_V_KMSXDA,
NDS32_BUILTIN_SMAL,
NDS32_BUILTIN_V_SMAL,
NDS32_BUILTIN_BITREV,
NDS32_BUILTIN_WEXT,
NDS32_BUILTIN_BPICK,
NDS32_BUILTIN_INSB,
NDS32_BUILTIN_SADD64,
NDS32_BUILTIN_UADD64,
NDS32_BUILTIN_RADD64,
NDS32_BUILTIN_URADD64,
NDS32_BUILTIN_KADD64,
NDS32_BUILTIN_UKADD64,
NDS32_BUILTIN_SSUB64,
NDS32_BUILTIN_USUB64,
NDS32_BUILTIN_RSUB64,
NDS32_BUILTIN_URSUB64,
NDS32_BUILTIN_KSUB64,
NDS32_BUILTIN_UKSUB64,
NDS32_BUILTIN_SMAR64,
NDS32_BUILTIN_SMSR64,
NDS32_BUILTIN_UMAR64,
NDS32_BUILTIN_UMSR64,
NDS32_BUILTIN_KMAR64,
NDS32_BUILTIN_KMSR64,
NDS32_BUILTIN_UKMAR64,
NDS32_BUILTIN_UKMSR64,
NDS32_BUILTIN_SMALBB,
NDS32_BUILTIN_V_SMALBB,
NDS32_BUILTIN_SMALBT,
NDS32_BUILTIN_V_SMALBT,
NDS32_BUILTIN_SMALTT,
NDS32_BUILTIN_V_SMALTT,
NDS32_BUILTIN_SMALDA,
NDS32_BUILTIN_V_SMALDA,
NDS32_BUILTIN_SMALXDA,
NDS32_BUILTIN_V_SMALXDA,
NDS32_BUILTIN_SMALDS,
NDS32_BUILTIN_V_SMALDS,
NDS32_BUILTIN_SMALDRS,
NDS32_BUILTIN_V_SMALDRS,
NDS32_BUILTIN_SMALXDS,
NDS32_BUILTIN_V_SMALXDS,
NDS32_BUILTIN_SMUL16,
NDS32_BUILTIN_V_SMUL16,
NDS32_BUILTIN_SMULX16,
NDS32_BUILTIN_V_SMULX16,
NDS32_BUILTIN_UMUL16,
NDS32_BUILTIN_V_UMUL16,
NDS32_BUILTIN_UMULX16,
NDS32_BUILTIN_V_UMULX16,
NDS32_BUILTIN_SMSLDA,
NDS32_BUILTIN_V_SMSLDA,
NDS32_BUILTIN_SMSLXDA,
NDS32_BUILTIN_V_SMSLXDA,
NDS32_BUILTIN_UCLIP32,
NDS32_BUILTIN_SCLIP32,
NDS32_BUILTIN_KABS,
NDS32_BUILTIN_UALOAD_U16,
NDS32_BUILTIN_UALOAD_S16,
NDS32_BUILTIN_UALOAD_U8,
NDS32_BUILTIN_UALOAD_S8,
NDS32_BUILTIN_UASTORE_U16,
NDS32_BUILTIN_UASTORE_S16,
NDS32_BUILTIN_UASTORE_U8,
NDS32_BUILTIN_UASTORE_S8,
NDS32_BUILTIN_DSP_END,
NDS32_BUILTIN_UNALIGNED_FEATURE,
NDS32_BUILTIN_ENABLE_UNALIGNED,
NDS32_BUILTIN_DISABLE_UNALIGNED,
......@@ -576,6 +890,13 @@ enum nds32_builtins
#endif
#define TARGET_CONFIG_FPU_DEFAULT NDS32_CONFIG_FPU_2
#ifdef TARGET_DEFAULT_EXT_DSP
# define NDS32_EXT_DSP_SPEC " %{!mno-ext-dsp:-mext-dsp}"
#else
# define NDS32_EXT_DSP_SPEC ""
#endif
/* ------------------------------------------------------------------------ */
/* Controlling the Compilation Driver. */
......@@ -591,7 +912,7 @@ enum nds32_builtins
{"float", "%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}" }
#define CC1_SPEC \
""
NDS32_EXT_DSP_SPEC
#define ASM_SPEC \
" %{mbig-endian:-EB} %{mlittle-endian:-EL}" \
......@@ -603,7 +924,8 @@ enum nds32_builtins
" %{mext-fpu-sp:-mfpu-sp-ext}" \
" %{mno-ext-fpu-sp:-mno-fpu-sp-ext}" \
" %{mext-fpu-dp:-mfpu-dp-ext}" \
" %{mno-ext-fpu-sp:-mno-fpu-dp-ext}"
" %{mno-ext-fpu-sp:-mno-fpu-dp-ext}" \
" %{mext-dsp:-mdsp-ext}"
/* If user issues -mrelax, we need to pass '--relax' to linker. */
#define LINK_SPEC \
......
......@@ -68,12 +68,13 @@
;; Insn type, it is used to default other attribute values.
(define_attr "type"
"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"
falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore,\
dalu,dalu64,daluround,dcmp,dclip,dmul,dmac,dinsb,dpack,dbpick,dwext"
(const_string "unknown"))
;; Insn sub-type
(define_attr "subtype"
"simple,shift"
"simple,shift,saturation"
(const_string "simple"))
;; Length, in bytes, default is 4-bytes.
......@@ -133,6 +134,7 @@
;; ----------------------------------------------------------------------------
(include "nds32-dspext.md")
;; Move instructions.
......@@ -351,13 +353,58 @@
;; ----------------------------------------------------------------------------
(define_expand "extv"
[(set (match_operand 0 "register_operand" "")
(sign_extract (match_operand 1 "nonimmediate_operand" "")
(match_operand 2 "const_int_operand" "")
(match_operand 3 "const_int_operand" "")))]
""
{
enum nds32_expand_result_type result = nds32_expand_extv (operands);
switch (result)
{
case EXPAND_DONE:
DONE;
break;
case EXPAND_FAIL:
FAIL;
break;
case EXPAND_CREATE_TEMPLATE:
break;
default:
gcc_unreachable ();
}
})
(define_expand "insv"
[(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
(match_operand 1 "const_int_operand" "")
(match_operand 2 "const_int_operand" ""))
(match_operand 3 "register_operand" ""))]
""
{
enum nds32_expand_result_type result = nds32_expand_insv (operands);
switch (result)
{
case EXPAND_DONE:
DONE;
break;
case EXPAND_FAIL:
FAIL;
break;
case EXPAND_CREATE_TEMPLATE:
break;
default:
gcc_unreachable ();
}
})
;; Arithmetic instructions.
(define_insn "addsi3"
[(set (match_operand:SI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
(plus:SI (match_operand:SI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
(match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,Iu06, Is15, r")))]
(match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,IU06, Is15, r")))]
""
{
switch (which_alternative)
......
......@@ -90,6 +90,10 @@ mcmov
Target Report Mask(CMOV)
Generate conditional move instructions.
mhw-abs
Target Report Mask(HW_ABS)
Generate hardware abs instructions.
mext-perf
Target Report Mask(EXT_PERF)
Generate performance extension instructions.
......@@ -102,6 +106,10 @@ mext-string
Target Report Mask(EXT_STRING)
Generate string extension instructions.
mext-dsp
Target Report Mask(EXT_DSP)
Generate DSP extension instructions.
mv3push
Target Report Mask(V3PUSH)
Generate v3 push25/pop25 instructions.
......@@ -321,6 +329,10 @@ mext-fpu-dp
Target Report Mask(FPU_DOUBLE)
Generate double-precision floating-point instructions.
mforce-no-ext-dsp
Target Undocumented Report Mask(FORCE_NO_EXT_DSP)
Force disable hardware loop, even use -mext-dsp.
malways-save-lp
Target Var(flag_always_save_lp) Init(0)
Always save $lp in the stack.
......
......@@ -56,14 +56,51 @@
(and (match_operand 0 "const_int_operand")
(match_test "satisfies_constraint_Is11 (op)"))))
(define_predicate "nds32_imm_0_1_operand"
(and (match_operand 0 "const_int_operand")
(ior (match_test "satisfies_constraint_Iv00 (op)")
(match_test "satisfies_constraint_Iv01 (op)"))))
(define_predicate "nds32_imm_1_2_operand"
(and (match_operand 0 "const_int_operand")
(ior (match_test "satisfies_constraint_Iv01 (op)")
(match_test "satisfies_constraint_Iv02 (op)"))))
(define_predicate "nds32_imm_1_2_4_8_operand"
(and (match_operand 0 "const_int_operand")
(ior (ior (match_test "satisfies_constraint_Iv01 (op)")
(match_test "satisfies_constraint_Iv02 (op)"))
(ior (match_test "satisfies_constraint_Iv04 (op)")
(match_test "satisfies_constraint_Iv08 (op)")))))
(define_predicate "nds32_imm2u_operand"
(and (match_operand 0 "const_int_operand")
(match_test "satisfies_constraint_Iu02 (op)")))
(define_predicate "nds32_imm4u_operand"
(and (match_operand 0 "const_int_operand")
(match_test "satisfies_constraint_Iu04 (op)")))
(define_predicate "nds32_imm5u_operand"
(and (match_operand 0 "const_int_operand")
(match_test "satisfies_constraint_Iu05 (op)")))
(define_predicate "nds32_imm6u_operand"
(and (match_operand 0 "const_int_operand")
(match_test "satisfies_constraint_Iu06 (op)")))
(define_predicate "nds32_rimm4u_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "nds32_imm4u_operand")))
(define_predicate "nds32_rimm5u_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "nds32_imm5u_operand")))
(define_predicate "nds32_rimm6u_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "nds32_imm6u_operand")))
(define_predicate "nds32_move_operand"
(and (match_operand 0 "general_operand")
(not (match_code "high,const,symbol_ref,label_ref")))
......@@ -78,6 +115,20 @@
return true;
})
(define_predicate "nds32_vmove_operand"
(and (match_operand 0 "general_operand")
(not (match_code "high,const,symbol_ref,label_ref")))
{
/* If the constant op does NOT satisfy Is20 nor Ihig,
we can not perform move behavior by a single instruction. */
if (GET_CODE (op) == CONST_VECTOR
&& !satisfies_constraint_CVs2 (op)
&& !satisfies_constraint_CVhi (op))
return false;
return true;
})
(define_predicate "nds32_and_operand"
(match_operand 0 "nds32_reg_constant_operand")
{
......@@ -127,6 +178,15 @@
(ior (match_operand 0 "nds32_symbolic_operand")
(match_operand 0 "nds32_general_register_operand")))
(define_predicate "nds32_insv_operand"
(match_code "const_int")
{
return INTVAL (op) == 0
|| INTVAL (op) == 8
|| INTVAL (op) == 16
|| INTVAL (op) == 24;
})
(define_predicate "nds32_lmw_smw_base_operand"
(and (match_code "mem")
(match_test "nds32_valid_smw_lwm_base_p (op)")))
......
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