===================================================================
@@ -12928,17 +12928,17 @@ static const struct mips_builtin_descrip
DIRECT_BUILTIN (extpdp, MIPS_SI_FTYPE_DI_SI, dsp_32),
DIRECT_BUILTIN (shilo, MIPS_DI_FTYPE_DI_SI, dsp_32),
DIRECT_BUILTIN (mthlip, MIPS_DI_FTYPE_DI_SI, dsp_32),
+ DIRECT_BUILTIN (madd, MIPS_DI_FTYPE_DI_SI_SI, dsp_32),
+ DIRECT_BUILTIN (maddu, MIPS_DI_FTYPE_DI_USI_USI, dsp_32),
+ DIRECT_BUILTIN (msub, MIPS_DI_FTYPE_DI_SI_SI, dsp_32),
+ DIRECT_BUILTIN (msubu, MIPS_DI_FTYPE_DI_USI_USI, dsp_32),
+ DIRECT_BUILTIN (mult, MIPS_DI_FTYPE_SI_SI, dsp_32),
+ DIRECT_BUILTIN (multu, MIPS_DI_FTYPE_USI_USI, dsp_32),
/* The following are for the MIPS DSP ASE REV 2 (32-bit only). */
DIRECT_BUILTIN (dpa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
DIRECT_BUILTIN (dps_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
- DIRECT_BUILTIN (madd, MIPS_DI_FTYPE_DI_SI_SI, dspr2_32),
- DIRECT_BUILTIN (maddu, MIPS_DI_FTYPE_DI_USI_USI, dspr2_32),
- DIRECT_BUILTIN (msub, MIPS_DI_FTYPE_DI_SI_SI, dspr2_32),
- DIRECT_BUILTIN (msubu, MIPS_DI_FTYPE_DI_USI_USI, dspr2_32),
DIRECT_BUILTIN (mulsa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
- DIRECT_BUILTIN (mult, MIPS_DI_FTYPE_SI_SI, dspr2_32),
- DIRECT_BUILTIN (multu, MIPS_DI_FTYPE_USI_USI, dspr2_32),
DIRECT_BUILTIN (dpax_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
DIRECT_BUILTIN (dpsx_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
DIRECT_BUILTIN (dpaqx_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32),
===================================================================
@@ -1181,3 +1181,25 @@
"%*bposge%1\t%0%/"
[(set_attr "type" "branch")])
+(define_expand "mips_mult<u>"
+ [(set (match_operand:DI 0 "register_operand")
+ (mult:DI
+ (any_extend:DI (match_operand:SI 1 "register_operand"))
+ (any_extend:DI (match_operand:SI 2 "register_operand"))))]
+ "ISA_HAS_DSP && !TARGET_64BIT")
+
+(define_expand "mips_madd<u>"
+ [(set (match_operand:DI 0 "register_operand")
+ (plus:DI
+ (mult:DI (any_extend:DI (match_operand:SI 2 "register_operand"))
+ (any_extend:DI (match_operand:SI 3 "register_operand")))
+ (match_operand:DI 1 "register_operand")))]
+ "ISA_HAS_DSP && !TARGET_64BIT")
+
+(define_expand "mips_msub<u>"
+ [(set (match_operand:DI 0 "register_operand")
+ (minus:DI
+ (match_operand:DI 1 "register_operand")
+ (mult:DI (any_extend:DI (match_operand:SI 2 "register_operand"))
+ (any_extend:DI (match_operand:SI 3 "register_operand")))))]
+ "ISA_HAS_DSP && !TARGET_64BIT")
===================================================================
@@ -86,8 +86,8 @@
;; Registers that can be used as the target of multiply-accumulate
;; instructions. The core MIPS32 ISA provides a hi/lo madd,
-;; but the DSPr2 version allows any accumulator target.
-(define_register_constraint "ka" "ISA_HAS_DSPR2 ? ACC_REGS : MD_REGS")
+;; but the DSP version allows any accumulator target.
+(define_register_constraint "ka" "ISA_HAS_DSP_MULT ? ACC_REGS : MD_REGS")
(define_constraint "kf"
"@internal"
===================================================================
@@ -224,22 +224,6 @@
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
-(define_expand "mips_madd<u>"
- [(set (match_operand:DI 0 "register_operand")
- (plus:DI
- (mult:DI (any_extend:DI (match_operand:SI 2 "register_operand"))
- (any_extend:DI (match_operand:SI 3 "register_operand")))
- (match_operand:DI 1 "register_operand")))]
- "ISA_HAS_DSPR2 && !TARGET_64BIT")
-
-(define_expand "mips_msub<u>"
- [(set (match_operand:DI 0 "register_operand")
- (minus:DI
- (match_operand:DI 1 "register_operand")
- (mult:DI (any_extend:DI (match_operand:SI 2 "register_operand"))
- (any_extend:DI (match_operand:SI 3 "register_operand")))))]
- "ISA_HAS_DSPR2 && !TARGET_64BIT")
-
(define_insn "mulv2hi3"
[(parallel
[(set (match_operand:V2HI 0 "register_operand" "=d")
@@ -320,26 +304,6 @@
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
-(define_insn "mips_mult"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (mult:DI
- (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
- (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "mult\t%q0,%1,%2"
- [(set_attr "type" "imul")
- (set_attr "mode" "SI")])
-
-(define_insn "mips_multu"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (mult:DI
- (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
- (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
- "ISA_HAS_DSPR2 && !TARGET_64BIT"
- "multu\t%q0,%1,%2"
- [(set_attr "type" "imul")
- (set_attr "mode" "SI")])
-
(define_insn "mips_precr_qb_ph"
[(set (match_operand:V4QI 0 "register_operand" "=d")
(unspec:V4QI [(match_operand:V2HI 1 "reg_or_0_operand" "dYG")
===================================================================
@@ -1732,11 +1732,16 @@
})
(define_insn "<u>mulsidi3_32bit"
- [(set (match_operand:DI 0 "register_operand" "=x")
+ [(set (match_operand:DI 0 "register_operand" "=ka")
(mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
(any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
- "!TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DSPR2"
- "mult<u>\t%1,%2"
+ "!TARGET_64BIT && !TARGET_FIX_R4000"
+{
+ if (ISA_HAS_DSP_MULT)
+ return "mult<u>\t%q0,%1,%2";
+ else
+ return "mult<u>\t%1,%2";
+}
[(set_attr "type" "imul")
(set_attr "mode" "SI")])
@@ -1863,9 +1868,9 @@
(mult:DI
(any_extend:DI (match_operand:SI 1 "register_operand" "d"))
(any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
- "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSPR2)"
+ "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSP)"
{
- if (ISA_HAS_DSPR2)
+ if (ISA_HAS_DSP_MULT)
return "msub<u>\t%q0,%1,%2";
else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
return "msub<u>\t%1,%2";
@@ -2042,12 +2047,12 @@
(mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
(any_extend:DI (match_operand:SI 2 "register_operand" "d")))
(match_operand:DI 3 "register_operand" "0")))]
- "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSPR2)
+ "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSP)
&& !TARGET_64BIT"
{
if (TARGET_MAD)
return "mad<u>\t%1,%2";
- else if (ISA_HAS_DSPR2)
+ else if (ISA_HAS_DSP_MULT)
return "madd<u>\t%q0,%1,%2";
else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
return "madd<u>\t%1,%2";
===================================================================
@@ -92,6 +92,12 @@
/* { dg-final { scan-assembler "lhx?" } } */
/* { dg-final { scan-assembler "lwx?" } } */
/* { dg-final { scan-assembler "bposge32" } } */
+/* { dg-final { scan-assembler "madd" } } */
+/* { dg-final { scan-assembler "maddu" } } */
+/* { dg-final { scan-assembler "msub" } } */
+/* { dg-final { scan-assembler "msubu" } } */
+/* { dg-final { scan-assembler "mult" } } */
+/* { dg-final { scan-assembler "multu" } } */
#include <stdlib.h>
#include <stdio.h>
@@ -101,6 +107,7 @@ typedef short v2q15 __attribute__ ((vect
typedef int q31;
typedef int i32;
+typedef unsigned int ui32;
typedef long long a64;
NOMIPS16 void test_MIPS_DSP (void);
@@ -150,6 +157,7 @@ NOMIPS16 void test_MIPS_DSP ()
v2q15 v2q15_a,v2q15_b,v2q15_c,v2q15_r,v2q15_s;
q31 q31_a,q31_b,q31_c,q31_r,q31_s;
i32 i32_a,i32_b,i32_c,i32_r,i32_s;
+ ui32 ui32_a,ui32_b,ui32_c;
a64 a64_a,a64_b,a64_c,a64_r,a64_s;
void *ptr_a;
@@ -1088,5 +1096,63 @@ NOMIPS16 void test_MIPS_DSP ()
i32_r = __builtin_mips_bposge32 ();
if (i32_r != i32_s)
abort ();
+
+#ifndef __mips64
+ a64_a = 0x12345678;
+ i32_b = 0x80000000;
+ i32_c = 0x11112222;
+ a64_s = 0xF7776EEF12345678LL;
+ a64_r = __builtin_mips_madd (a64_a, i32_b, i32_c);
+ if (a64_r != a64_s)
+ abort ();
+#endif
+
+#ifndef __mips64
+ a64_a = 0x12345678;
+ ui32_b = 0x80000000;
+ ui32_c = 0x11112222;
+ a64_s = 0x0888911112345678LL;
+ a64_r = __builtin_mips_maddu (a64_a, ui32_b, ui32_c);
+ if (a64_r != a64_s)
+ abort ();
+#endif
+
+#ifndef __mips64
+ a64_a = 0x12345678;
+ i32_b = 0x80000000;
+ i32_c = 0x11112222;
+ a64_s = 0x0888911112345678LL;
+ a64_r = __builtin_mips_msub (a64_a, i32_b, i32_c);
+ if (a64_r != a64_s)
+ abort ();
+#endif
+
+#ifndef __mips64
+ a64_a = 0x12345678;
+ ui32_b = 0x80000000;
+ ui32_c = 0x11112222;
+ a64_s = 0xF7776EEF12345678LL;
+ a64_r = __builtin_mips_msubu (a64_a, ui32_b, ui32_c);
+ if (a64_r != a64_s)
+ abort ();
+#endif
+
+#ifndef __mips64
+ i32_a = 0x80000000;
+ i32_b = 0x11112222;
+ a64_s = 0xF7776EEF00000000LL;
+ a64_r = __builtin_mips_mult (i32_a, i32_b);
+ if (a64_r != a64_s)
+ abort ();
+#endif
+
+#ifndef __mips64
+ ui32_a = 0x80000000;
+ ui32_b = 0x11112222;
+ a64_s = 0x888911100000000LL;
+ a64_r = __builtin_mips_multu (ui32_a, ui32_b);
+ if (a64_r != a64_s)
+ abort ();
+#endif
}
===================================================================
@@ -10,6 +10,7 @@ typedef short v2q15 __attribute__ ((vect
typedef int q31;
typedef int i32;
+typedef unsigned int ui32;
typedef long long a64;
NOMIPS16 void test_MIPS_DSP (void);
@@ -59,6 +60,7 @@ NOMIPS16 void test_MIPS_DSP ()
v2q15 v2q15_a,v2q15_b,v2q15_c,v2q15_r,v2q15_s;
q31 q31_a,q31_b,q31_c,q31_r,q31_s;
i32 i32_a,i32_b,i32_c,i32_r,i32_s;
+ ui32 ui32_a,ui32_b,ui32_c;
a64 a64_a,a64_b,a64_c,a64_r,a64_s;
void *ptr_a;
@@ -997,5 +999,63 @@ NOMIPS16 void test_MIPS_DSP ()
i32_r = __builtin_mips_bposge32 ();
if (i32_r != i32_s)
abort ();
+
+#ifndef __mips64
+ a64_a = 0x12345678;
+ i32_b = 0x80000000;
+ i32_c = 0x11112222;
+ a64_s = 0xF7776EEF12345678LL;
+ a64_r = __builtin_mips_madd (a64_a, i32_b, i32_c);
+ if (a64_r != a64_s)
+ abort ();
+#endif
+
+#ifndef __mips64
+ a64_a = 0x12345678;
+ ui32_b = 0x80000000;
+ ui32_c = 0x11112222;
+ a64_s = 0x0888911112345678LL;
+ a64_r = __builtin_mips_maddu (a64_a, ui32_b, ui32_c);
+ if (a64_r != a64_s)
+ abort ();
+#endif
+
+#ifndef __mips64
+ a64_a = 0x12345678;
+ i32_b = 0x80000000;
+ i32_c = 0x11112222;
+ a64_s = 0x0888911112345678LL;
+ a64_r = __builtin_mips_msub (a64_a, i32_b, i32_c);
+ if (a64_r != a64_s)
+ abort ();
+#endif
+
+#ifndef __mips64
+ a64_a = 0x12345678;
+ ui32_b = 0x80000000;
+ ui32_c = 0x11112222;
+ a64_s = 0xF7776EEF12345678LL;
+ a64_r = __builtin_mips_msubu (a64_a, ui32_b, ui32_c);
+ if (a64_r != a64_s)
+ abort ();
+#endif
+
+#ifndef __mips64
+ i32_a = 0x80000000;
+ i32_b = 0x11112222;
+ a64_s = 0xF7776EEF00000000LL;
+ a64_r = __builtin_mips_mult (i32_a, i32_b);
+ if (a64_r != a64_s)
+ abort ();
+#endif
+
+#ifndef __mips64
+ ui32_a = 0x80000000;
+ ui32_b = 0x11112222;
+ a64_s = 0x888911100000000LL;
+ a64_r = __builtin_mips_multu (ui32_a, ui32_b);
+ if (a64_r != a64_s)
+ abort ();
+#endif
}
===================================================================
@@ -9628,6 +9628,12 @@ i32 __builtin_mips_lbux (void *, i32)
i32 __builtin_mips_lhx (void *, i32)
i32 __builtin_mips_lwx (void *, i32)
i32 __builtin_mips_bposge32 (void)
+a64 __builtin_mips_madd (a64, i32, i32);
+a64 __builtin_mips_maddu (a64, ui32, ui32);
+a64 __builtin_mips_msub (a64, i32, i32);
+a64 __builtin_mips_msubu (a64, ui32, ui32);
+a64 __builtin_mips_mult (i32, i32);
+a64 __builtin_mips_multu (ui32, ui32);
@end smallexample
The following built-in functions map directly to a particular MIPS DSP REV 2
@@ -9647,18 +9653,12 @@ i32 __builtin_mips_cmpgdu_lt_qb (v4i8, v
i32 __builtin_mips_cmpgdu_le_qb (v4i8, v4i8);
a64 __builtin_mips_dpa_w_ph (a64, v2i16, v2i16);
a64 __builtin_mips_dps_w_ph (a64, v2i16, v2i16);
-a64 __builtin_mips_madd (a64, i32, i32);
-a64 __builtin_mips_maddu (a64, ui32, ui32);
-a64 __builtin_mips_msub (a64, i32, i32);
-a64 __builtin_mips_msubu (a64, ui32, ui32);
v2i16 __builtin_mips_mul_ph (v2i16, v2i16);
v2i16 __builtin_mips_mul_s_ph (v2i16, v2i16);
q31 __builtin_mips_mulq_rs_w (q31, q31);
v2q15 __builtin_mips_mulq_s_ph (v2q15, v2q15);
q31 __builtin_mips_mulq_s_w (q31, q31);
a64 __builtin_mips_mulsa_w_ph (a64, v2i16, v2i16);
-a64 __builtin_mips_mult (i32, i32);
-a64 __builtin_mips_multu (ui32, ui32);
v4i8 __builtin_mips_precr_qb_ph (v2i16, v2i16);
v2i16 __builtin_mips_precr_sra_ph_w (i32, i32, imm0_31);
v2i16 __builtin_mips_precr_sra_r_ph_w (i32, i32, imm0_31);
===================================================================
@@ -24391,6 +24391,45 @@ $as_echo "#define HAVE_AS_DTPRELWORD 1"
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for DSP Rev1 mult with four accumulators support" >&5
+$as_echo_n "checking assembler for DSP Rev1 mult with four accumulators support... " >&6; }
+if test "${gcc_cv_as_mips_dsp_rev1_mult+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_mips_dsp_rev1_mult=no
+ if test x$gcc_cv_as != x; then
+ echo ' .set mips32r2
+ .set nodspr2
+ .set dsp
+ madd $ac3,$4,$5
+ maddu $ac3,$4,$5
+ msub $ac3,$4,$5
+ msubu $ac3,$4,$5
+ mult $ac3,$4,$5
+ multu $ac3,$4,$5' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ gcc_cv_as_mips_dsp_rev1_mult=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_dsp_rev1_mult" >&5
+$as_echo "$gcc_cv_as_mips_dsp_rev1_mult" >&6; }
+if test $gcc_cv_as_mips_dsp_rev1_mult = yes; then
+
+$as_echo "#define HAVE_AS_DSP_REV1_MULT 1" >>confdefs.h
+
+fi
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler and linker for explicit JALR relocation" >&5
$as_echo_n "checking assembler and linker for explicit JALR relocation... " >&6; }
gcc_cv_as_ld_jalr_reloc=no
===================================================================
@@ -3658,6 +3658,20 @@ x:
[AC_DEFINE(HAVE_AS_DTPRELWORD, 1,
[Define if your assembler supports .dtprelword.])])
+ gcc_GAS_CHECK_FEATURE([DSP Rev1 mult with four accumulators support],
+ gcc_cv_as_mips_dsp_rev1_mult,,,
+[ .set mips32r2
+ .set nodspr2
+ .set dsp
+ madd $ac3,$4,$5
+ maddu $ac3,$4,$5
+ msub $ac3,$4,$5
+ msubu $ac3,$4,$5
+ mult $ac3,$4,$5
+ multu $ac3,$4,$5],,
+ [AC_DEFINE(HAVE_AS_DSP_REV1_MULT, 1,
+ [Define if your assembler supports DSP Rev1 mult.])])
+
AC_MSG_CHECKING(assembler and linker for explicit JALR relocation)
gcc_cv_as_ld_jalr_reloc=no
if test $gcc_cv_as_mips_explicit_relocs = yes; then
===================================================================
@@ -180,6 +180,13 @@ enum mips_code_readable_setting {
#define TARGET_WRITABLE_EH_FRAME (flag_pic && TARGET_SHARED)
#endif
+/* Test the assembler to set ISA_HAS_DSP_MULT to DSP Rev 1 or 2. */
+#ifdef HAVE_AS_DSP_REV1_MULT
+#define ISA_HAS_DSP_MULT ISA_HAS_DSP
+#else
+#define ISA_HAS_DSP_MULT ISA_HAS_DSPR2
+#endif
+
/* Generate mips16 code */
#define TARGET_MIPS16 ((target_flags & MASK_MIPS16) != 0)
/* Generate mips16e code. Default 16bit ASE for mips32* and mips64* */
===================================================================
@@ -229,6 +229,12 @@
#endif
+/* Define if your assembler supports DSP Rev1 mult. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_DSP_REV1_MULT
+#endif
+
+
/* Define if your assembler supports .dtprelword. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_DTPRELWORD