+2009-05-20 Adam Nemet <anemet@caviumnetworks.com>
+
+ * config/mips/mips.md (*extenddi_truncate<mode>,
+ *extendsi_truncate<mode>): Emit exts if supported. Add attribute
+ defintions.
+ (*extendhi_truncateqi): New define_insn_and_sptit.
+
2009-05-20 Jakub Jelinek <jakub@redhat.com>
PR middle-end/40204
(sign_extend:DI
(truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
"TARGET_64BIT && !TARGET_MIPS16"
- "#"
- "&& reload_completed"
+{
+ if (!ISA_HAS_EXTS)
+ return "#";
+ operands[2] = GEN_INT (GET_MODE_BITSIZE (<SHORT:MODE>mode));
+ return "exts\t%0,%1,0,%m2";
+}
+ "&& reload_completed && !ISA_HAS_EXTS"
[(set (match_dup 2)
(ashift:DI (match_dup 1)
(match_dup 3)))
{
operands[2] = gen_lowpart (DImode, operands[0]);
operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
-})
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "DI")])
(define_insn_and_split "*extendsi_truncate<mode>"
[(set (match_operand:SI 0 "register_operand" "=d")
(sign_extend:SI
(truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
"TARGET_64BIT && !TARGET_MIPS16"
- "#"
- "&& reload_completed"
+{
+ if (!ISA_HAS_EXTS)
+ return "#";
+ operands[2] = GEN_INT (GET_MODE_BITSIZE (<SHORT:MODE>mode));
+ return "exts\t%0,%1,0,%m2";
+}
+ "&& reload_completed && !ISA_HAS_EXTS"
[(set (match_dup 2)
(ashift:DI (match_dup 1)
(match_dup 3)))
{
operands[2] = gen_lowpart (DImode, operands[0]);
operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
-})
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")])
+
+(define_insn_and_split "*extendhi_truncateqi"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (sign_extend:HI
+ (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
+ "TARGET_64BIT && !TARGET_MIPS16"
+{
+ return ISA_HAS_EXTS ? "exts\t%0,%1,0,7" : "#";
+}
+ "&& reload_completed && !ISA_HAS_EXTS"
+ [(set (match_dup 2)
+ (ashift:DI (match_dup 1)
+ (const_int 56)))
+ (set (match_dup 0)
+ (truncate:HI (ashiftrt:DI (match_dup 2)
+ (const_int 56))))]
+{
+ operands[2] = gen_lowpart (DImode, operands[0]);
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")])
(define_insn "extendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
+2009-05-20 Adam Nemet <anemet@caviumnetworks.com>
+
+ * gcc.target/mips/octeon-exts-6.c: New test.
+ * gcc.target/mips/extend-1.c: New test.
+ * gcc.target/mips/octeon-exts-2.c: Adjust to not match sign-extension
+ EXTS.
+ * gcc.target/mips/octeon-exts-5.c: Likewise.
+
2009-05-20 Jakub Jelinek <jakub@redhat.com>
PR middle-end/40204
--- /dev/null
+/* { dg-options "-O -mgp64 isa=!octeon" } */
+/* { dg-final { scan-assembler-times "\tdsll\t" 5 } } */
+/* { dg-final { scan-assembler-times "\tdsra\t" 5 } } */
+/* { dg-final { scan-assembler-not "\tsll\t" } } */
+
+#define TEST_CHAR(T, N) \
+ NOMIPS16 T f##N (long long d, T *a, T *r) { T b = (char) d; *r = b + *a; }
+#define TEST_SHORT(T, N) \
+ NOMIPS16 T g##N (long long d, T *a, T *r) { T b = (short) d; *r = b + *a; }
+#define TEST(T, N) TEST_CHAR (T, N) TEST_SHORT (T, N)
+
+TEST (int, 1);
+TEST (long long, 2);
+TEST_CHAR (short, 3);
/* { dg-do compile } */
-/* { dg-options "-O -march=octeon -meb" } */
-/* { dg-final { scan-assembler-times "\texts\t" 4 } } */
+/* { dg-options "-O -march=octeon -meb -dp" } */
+/* Don't match exts in sign-extension. */
+/* { dg-final { scan-assembler-times "\texts\t\[^\\n\]*extv" 4 } } */
struct bar
{
/* -mel version of octeon-exts-2.c. */
/* { dg-do compile } */
-/* { dg-options "-O -march=octeon -mel" } */
-/* { dg-final { scan-assembler-times "\texts\t" 4 } } */
+/* { dg-options "-O -march=octeon -mel -dp" } */
+/* Don't match exts in sign-extension. */
+/* { dg-final { scan-assembler-times "\texts\t\[^\\n\]*extv" 4 } } */
struct bar
{
--- /dev/null
+/* { dg-options "-O -march=octeon -mgp64" } */
+/* { dg-final { scan-assembler-times "\texts\t" 5 } } */
+/* { dg-final { scan-assembler-not "\t(dsll|dsra)\t" } } */
+/* { dg-final { scan-assembler-not "\tsll\t" } } */
+
+#define TEST_CHAR(T, N) \
+ NOMIPS16 T f##N (long long d, T *a, T *r) { T b = (char) d; *r = b + *a; }
+#define TEST_SHORT(T, N) \
+ NOMIPS16 T g##N (long long d, T *a, T *r) { T b = (short) d; *r = b + *a; }
+#define TEST(T, N) TEST_CHAR (T, N) TEST_SHORT (T, N)
+
+TEST (int, 1);
+TEST (long long, 2);
+TEST_CHAR (short, 3);