===================================================================
@@ -0,0 +1,10 @@
+/* Test MIPS64 DSP instructions */
+/* { dg-do compile } */
+/* { dg-options "-mgp64 -mdsp" } */
+
+/* { dg-final { scan-assembler "\tldx\t" } } */
+
+NOMIPS16 signed long long test (signed long long *a, int index)
+{
+ return __builtin_mips_ldx (a, index);
+}
===================================================================
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=octeon2 -O -mgp64" } */
+
+#define TEST(N, R, T) \
+ T f##N (T j, R *b, long long i) { return j + b[i]; } \
+ T g##N (T j, unsigned R *b, long long i) { return j + b[i]; }
+
+TEST (1, char, int)
+TEST (2, char, long long)
+/* { dg-final { scan-assembler-times "\tlbx\t" 2 } } */
+/* { dg-final { scan-assembler-times "\tlbux\t" 2 } } */
+TEST (3, short, int)
+TEST (4, short, long long)
+/* { dg-final { scan-assembler-times "\tlhx\t" 2 } } */
+/* { dg-final { scan-assembler-times "\tlhux\t" 2 } } */
+TEST (5, int, long long)
+/* { dg-final { scan-assembler-times "\tlwx\t" 1 } } */
+/* { dg-final { scan-assembler-times "\tlwux\t" 1 } } */
===================================================================
@@ -0,0 +1,10 @@
+/* Test MIPS64 DSP instructions */
+/* { dg-do compile } */
+/* { dg-options "-mgp64 -mdsp -O" } */
+
+/* { dg-final { scan-assembler "\tldx\t" } } */
+
+NOMIPS16 signed long long test (signed long long *a, int index)
+{
+ return a[index];
+}
===================================================================
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=octeon2 -O -mgp64" } */
+
+#define TEST(N, T) \
+ T f##N (T *p, int i) { return p[i]; } \
+ unsigned T g##N (unsigned T *p, int i) { return p[i]; }
+
+TEST (1, char)
+/* { dg-final { scan-assembler-times "\tlbu?x\t" 2 } } */
+TEST (2, short)
+/* { dg-final { scan-assembler-times "\tlhu?x\t" 2 } } */
+TEST (3, int)
+/* { dg-final { scan-assembler-times "\tlwx\t" 2 } } */
+TEST (4, long long)
+/* { dg-final { scan-assembler-times "\tldx\t" 2 } } */
===================================================================
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=octeon2 -O -mgp32" } */
+
+#define TEST(N, T) \
+ T f##N (T *p, int i) { return p[i]; } \
+ unsigned T g##N (unsigned T *p, int i) { return p[i]; }
+
+TEST (1, char)
+/* { dg-final { scan-assembler-times "\tlbu?x\t" 2 } } */
+TEST (2, short)
+/* { dg-final { scan-assembler-times "\tlhu?x\t" 2 } } */
+TEST (3, int)
+/* { dg-final { scan-assembler-times "\tlwx\t" 2 } } */
===================================================================
@@ -1105,20 +1105,21 @@ (define_expand "mips_lbux"
"ISA_HAS_DSP"
{
operands[2] = convert_to_mode (Pmode, operands[2], false);
- emit_insn (PMODE_INSN (gen_mips_lbux,
+ emit_insn (PMODE_INSN (gen_mips_lbux_extsi,
(operands[0], operands[1], operands[2])));
DONE;
})
-(define_insn "mips_lbux_<mode>"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (zero_extend:SI
- (mem:QI (plus:P (match_operand:P 1 "register_operand" "d")
- (match_operand:P 2 "register_operand" "d")))))]
- "ISA_HAS_DSP"
- "lbux\t%0,%2(%1)"
+(define_insn "mips_l<SHORT:size><u>x_ext<GPR:mode>_<P:mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (any_extend:GPR
+ (mem:SHORT (plus:P (match_operand:P 1 "register_operand" "d")
+ (match_operand:P 2 "register_operand" "d")))))]
+ "ISA_HAS_L<SHORT:SIZE><U>X"
+ "l<SHORT:size><u>x\t%0,%2(%1)"
[(set_attr "type" "load")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<GPR:MODE>")
+ (set_attr "length" "4")])
(define_expand "mips_lhx"
[(match_operand:SI 0 "register_operand")
@@ -1127,21 +1128,11 @@ (define_expand "mips_lhx"
"ISA_HAS_DSP"
{
operands[2] = convert_to_mode (Pmode, operands[2], false);
- emit_insn (PMODE_INSN (gen_mips_lhx,
+ emit_insn (PMODE_INSN (gen_mips_lhx_extsi,
(operands[0], operands[1], operands[2])));
DONE;
})
-(define_insn "mips_lhx_<mode>"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (sign_extend:SI
- (mem:HI (plus:P (match_operand:P 1 "register_operand" "d")
- (match_operand:P 2 "register_operand" "d")))))]
- "ISA_HAS_DSP"
- "lhx\t%0,%2(%1)"
- [(set_attr "type" "load")
- (set_attr "mode" "SI")])
-
(define_expand "mips_lwx"
[(match_operand:SI 0 "register_operand")
(match_operand 1 "pmode_register_operand")
@@ -1154,14 +1145,38 @@ (define_expand "mips_lwx"
DONE;
})
-(define_insn "mips_lwx_<mode>"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (mem:SI (plus:P (match_operand:P 1 "register_operand" "d")
- (match_operand:P 2 "register_operand" "d"))))]
- "ISA_HAS_DSP"
- "lwx\t%0,%2(%1)"
+(define_expand "mips_ldx"
+ [(match_operand:DI 0 "register_operand")
+ (match_operand 1 "pmode_register_operand")
+ (match_operand:SI 2 "register_operand")]
+ "ISA_HAS_DSP && TARGET_64BIT"
+{
+ operands[2] = convert_to_mode (Pmode, operands[2], false);
+ emit_insn (PMODE_INSN (gen_mips_ldx,
+ (operands[0], operands[1], operands[2])));
+ DONE;
+})
+
+(define_insn "mips_l<GPR:size>x_<P:mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (mem:GPR (plus:P (match_operand:P 1 "register_operand" "d")
+ (match_operand:P 2 "register_operand" "d"))))]
+ "ISA_HAS_L<GPR:SIZE>X"
+ "l<GPR:size>x\t%0,%2(%1)"
+ [(set_attr "type" "load")
+ (set_attr "mode" "<GPR:MODE>")
+ (set_attr "length" "4")])
+
+(define_insn "*mips_lw<u>x_<P:mode>_ext"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (any_extend:DI
+ (mem:SI (plus:P (match_operand:P 1 "register_operand" "d")
+ (match_operand:P 2 "register_operand" "d")))))]
+ "ISA_HAS_LW<U>X && TARGET_64BIT"
+ "lw<u>x\t%0,%2(%1)"
[(set_attr "type" "load")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "DI")
+ (set_attr "length" "4")])
;; Table 2-8. MIPS DSP ASE Instructions: Branch
;; BPOSGE32
===================================================================
@@ -53,6 +53,7 @@ DEF_MIPS_FTYPE (4, (INT, V2SF, V2SF, V2S
DEF_MIPS_FTYPE (2, (SI, DI, SI))
DEF_MIPS_FTYPE (2, (SI, POINTER, SI))
+DEF_MIPS_FTYPE (2, (DI, POINTER, SI))
DEF_MIPS_FTYPE (1, (SI, SI))
DEF_MIPS_FTYPE (2, (SI, SI, SI))
DEF_MIPS_FTYPE (3, (SI, SI, SI, SI))
===================================================================
@@ -668,9 +668,10 @@ (define_mode_attr D [(SI "") (DI "D")
(HA "") (SA "") (DA "D")
(UHA "") (USA "") (UDA "D")])
-;; This attribute gives the length suffix for a sign- or zero-extension
-;; instruction.
-(define_mode_attr size [(QI "b") (HI "h")])
+;; This attribute gives the length suffix for a sign-, zero-extension
+;; load and store instruction.
+(define_mode_attr size [(QI "b") (HI "h") (SI "w") (DI "d")])
+(define_mode_attr SIZE [(QI "B") (HI "H") (SI "W") (DI "D")])
;; This attributes gives the mode mask of a SHORT.
(define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
@@ -790,6 +791,9 @@ (define_code_attr u [(sign_extend "") (z
(lt "") (ltu "u")
(le "") (leu "u")])
+;; <U> is like <u> except uppercase.
+(define_code_attr U [(sign_extend "") (zero_extend "U")])
+
;; <su> is like <u>, but the signed form expands to "s" rather than "".
(define_code_attr su [(sign_extend "s") (zero_extend "u")])
===================================================================
@@ -2159,6 +2159,29 @@ mips_lwxs_address_p (rtx addr)
}
return false;
}
+
+/* Return true if ADDR matches the pattern for the L{B,H,W,D}{,U}X load
+ indexed address instruction. Note that such addresses are
+ not considered legitimate in the TARGET_LEGITIMATE_ADDRESS_P
+ sense, because their use is so restricted. */
+
+static bool
+mips_loadindexed_address_p (rtx addr, enum machine_mode mode)
+{
+ if (GET_CODE (addr) != PLUS
+ || !REG_P (XEXP (addr, 0))
+ || !REG_P (XEXP (addr, 1)))
+ return false;
+ if (ISA_HAS_LBX && mode == QImode)
+ return true;
+ if (ISA_HAS_LHX && mode == HImode)
+ return true;
+ if (ISA_HAS_LWX && mode == SImode)
+ return true;
+ if (ISA_HAS_LDX && mode == DImode)
+ return true;
+ return false;
+}
/* Return true if a value at OFFSET bytes from base register BASE can be
accessed using an unextended MIPS16 instruction. MODE is the mode of
@@ -3552,6 +3575,11 @@ mips_rtx_costs (rtx x, int code, int out
*total = COSTS_N_INSNS (2);
return true;
}
+ if (mips_loadindexed_address_p (addr, mode))
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
/* Otherwise use the default handling. */
return false;
@@ -12627,6 +12655,7 @@ AVAIL_NON_MIPS16 (mips3d, TARGET_MIPS3D)
AVAIL_NON_MIPS16 (dsp, TARGET_DSP)
AVAIL_NON_MIPS16 (dspr2, TARGET_DSPR2)
AVAIL_NON_MIPS16 (dsp_32, !TARGET_64BIT && TARGET_DSP)
+AVAIL_NON_MIPS16 (dsp_64, TARGET_64BIT && TARGET_DSP)
AVAIL_NON_MIPS16 (dspr2_32, !TARGET_64BIT && TARGET_DSPR2)
AVAIL_NON_MIPS16 (loongson, TARGET_LOONGSON_VECTORS)
AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
@@ -12959,6 +12988,9 @@ static const struct mips_builtin_descrip
DIRECT_BUILTIN (mult, MIPS_DI_FTYPE_SI_SI, dsp_32),
DIRECT_BUILTIN (multu, MIPS_DI_FTYPE_USI_USI, dsp_32),
+ /* Built-in functions for the DSP ASE (64-bit only). */
+ DIRECT_BUILTIN (ldx, MIPS_DI_FTYPE_POINTER_SI, dsp_64),
+
/* 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),
===================================================================
@@ -996,6 +996,15 @@ struct mips_cpu_info {
/* ISA has lwxs instruction (load w/scaled index address. */
#define ISA_HAS_LWXS (TARGET_SMARTMIPS && !TARGET_MIPS16)
+/* ISA has lbx, lbux, lhx, lhx, lhux, lwx, lwux, or ldx instruction. */
+#define ISA_HAS_LBX (TARGET_OCTEON2)
+#define ISA_HAS_LBUX (ISA_HAS_DSP || TARGET_OCTEON2)
+#define ISA_HAS_LHX (ISA_HAS_DSP || TARGET_OCTEON2)
+#define ISA_HAS_LHUX (TARGET_OCTEON2)
+#define ISA_HAS_LWX (ISA_HAS_DSP || TARGET_OCTEON2)
+#define ISA_HAS_LWUX (TARGET_OCTEON2 && TARGET_64BIT)
+#define ISA_HAS_LDX ((ISA_HAS_DSP || TARGET_OCTEON2) && TARGET_64BIT)
+
/* The DSP ASE is available. */
#define ISA_HAS_DSP (TARGET_DSP && !TARGET_MIPS16)