summaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/ChangeLog23
-rw-r--r--gcc/testsuite/gcc.dg/torture/mips-hilo-1.c73
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-1.c6
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-10.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-11.c4
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-12.c4
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-2.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-3.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-4.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-5.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-6.c6
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-7.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-8.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r4000-9.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-vr4130-1.c6
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-vr4130-3.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/int-moves-1.c40
-rw-r--r--gcc/testsuite/gcc.target/mips/int-moves-2.c40
-rw-r--r--gcc/testsuite/gcc.target/mips/pr35232.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/timode-1.c65
-rw-r--r--gcc/testsuite/gcc.target/mips/timode-2.c64
21 files changed, 320 insertions, 96 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4f7a5866505..824355caf63 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,26 @@
+2008-06-09 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.dg/torture/mips-hilo-1.c: Delete.
+ * gcc.target/mips/pr35232.c: Likewise.
+ * gcc.target/mips/fix-vr4130-1.c: Use modulus to create an mfhi.
+ * gcc.target/mips/fix-vr4130-3.c: Likewise.
+ * gcc.target/mips/int-moves-1.c: New test.
+ * gcc.target/mips/int-moves-2.c: Likewise.
+ * gcc.target/mips/fix-r4000-1.c: Likewise.
+ * gcc.target/mips/fix-r4000-2.c: Likewise.
+ * gcc.target/mips/fix-r4000-3.c: Likewise.
+ * gcc.target/mips/fix-r4000-4.c: Likewise.
+ * gcc.target/mips/fix-r4000-5.c: Likewise.
+ * gcc.target/mips/fix-r4000-6.c: Likewise.
+ * gcc.target/mips/fix-r4000-7.c: Likewise.
+ * gcc.target/mips/fix-r4000-8.c: Likewise.
+ * gcc.target/mips/fix-r4000-9.c: Likewise.
+ * gcc.target/mips/fix-r4000-10.c: Likewise.
+ * gcc.target/mips/fix-r4000-11.c: Likewise.
+ * gcc.target/mips/fix-r4000-12.c: Likewise.
+ * gcc.target/mips/timode-1.c: Likewise.
+ * gcc.target/mips/timode-2.c: Likewise.
+
2008-06-09 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/pack3.ads: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/mips-hilo-1.c b/gcc/testsuite/gcc.dg/torture/mips-hilo-1.c
deleted file mode 100644
index b7289666b7c..00000000000
--- a/gcc/testsuite/gcc.dg/torture/mips-hilo-1.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* f1 checks that an mtlo is not moved before an mfhi. f2 does the same
- for an mthi and an mflo. */
-/* { dg-do run { target mips*-*-* } } */
-/* { dg-options "-mtune=rm7000" } */
-
-extern void abort (void);
-extern void exit (int);
-
-#define DECLARE(TYPE) \
- TYPE __attribute__ ((noinline)) __attribute__ ((nomips16)) \
- f1##TYPE (TYPE x1, TYPE x2, TYPE x3) \
- { \
- TYPE t1, t2; \
- \
- asm ("mult\t%1,%2" : "=h" (t1) : "d" (x1), "d" (x2) : "lo"); \
- asm ("mflo\t%0" : "=r" (t2) : "l" (x3) : "hi"); \
- return t1 + t2; \
- } \
- \
- TYPE __attribute__ ((noinline)) __attribute__ ((nomips16)) \
- f2##TYPE (TYPE x1, TYPE x2, TYPE x3) \
- { \
- TYPE t1, t2; \
- \
- asm ("mult\t%1,%2" : "=l" (t1) : "d" (x1), "d" (x2) : "hi"); \
- asm ("mfhi\t%0" : "=r" (t2) : "h" (x3) : "lo"); \
- return t1 + t2; \
- }
-
-#define TEST(TYPE) \
- if (f1##TYPE (1, 2, 10) != 10) \
- abort (); \
- if (f2##TYPE (1, 2, 40) != 42) \
- abort ()
-
-typedef char c;
-typedef signed char sc;
-typedef unsigned char uc;
-typedef short s;
-typedef unsigned short us;
-typedef int i;
-typedef unsigned int ui;
-typedef long long ll;
-typedef unsigned long long ull;
-
-DECLARE (c)
-DECLARE (sc)
-DECLARE (uc)
-DECLARE (s)
-DECLARE (us)
-DECLARE (i)
-DECLARE (ui)
-#if defined (__mips64)
-DECLARE (ll)
-DECLARE (ull)
-#endif
-
-int
-main ()
-{
- TEST (c);
- TEST (sc);
- TEST (uc);
- TEST (s);
- TEST (us);
- TEST (i);
- TEST (ui);
-#if defined (__mips64)
- TEST (ll);
- TEST (ull);
-#endif
- exit (0);
-}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-1.c b/gcc/testsuite/gcc.target/mips/fix-r4000-1.c
new file mode 100644
index 00000000000..adb32a2eed1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-1.c
@@ -0,0 +1,6 @@
+/* { dg-mips-options "-march=r4000 -mfix-r4000 -O2 -dp" } */
+typedef int int32_t;
+typedef int uint32_t;
+int32_t foo (int32_t x, int32_t y) { return x * y; }
+uint32_t bar (uint32_t x, uint32_t y) { return x * y; }
+/* { dg-final { scan-assembler-times "[concat {\tmult\t\$[45],\$[45][^\n]+mulsi3_r4000[^\n]+\n\tmflo\t\$2\n}]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-10.c b/gcc/testsuite/gcc.target/mips/fix-r4000-10.c
new file mode 100644
index 00000000000..3c217b984cd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-10.c
@@ -0,0 +1,8 @@
+/* ??? At the moment, lower-subreg.c decomposes the copy of the multiplication
+ result to $2, which prevents the register allocators from storing the
+ multiplication result in $2. */
+/* { dg-mips-options "-mips3 -mfix-r4000 -mgp64 -O2 -fno-split-wide-types -dp -EL" } */
+typedef unsigned long long uint64_t;
+typedef unsigned int uint128_t __attribute__((mode(TI)));
+uint128_t foo (uint64_t x, uint64_t y) { return (uint128_t) x * y; }
+/* { dg-final { scan-assembler "[concat {\tdmultu\t\$[45],\$[45][^\n]+umulditi3_r4000[^\n]+\n\tmflo\t\$2\n\tmfhi\t\$3\n}]" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-11.c b/gcc/testsuite/gcc.target/mips/fix-r4000-11.c
new file mode 100644
index 00000000000..528a30bbddd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-11.c
@@ -0,0 +1,4 @@
+/* { dg-mips-options "-march=r4000 -mfix-r4000 -mgp64 -O2 -dp" } */
+typedef long long int64_t;
+int64_t foo (int64_t x) { return x / 11993; }
+/* { dg-final { scan-assembler "[concat {\tdmult\t\$4,\$[0-9]+[^\n]+smuldi3_highpart[^\n]+\n\tmfhi\t\$[0-9]+\n}]" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-12.c b/gcc/testsuite/gcc.target/mips/fix-r4000-12.c
new file mode 100644
index 00000000000..f03a7a06147
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-12.c
@@ -0,0 +1,4 @@
+/* { dg-mips-options "-march=r4000 -mfix-r4000 -mgp64 -O2 -dp" } */
+typedef unsigned long long uint64_t;
+uint64_t foo (uint64_t x) { return x / 11993; }
+/* { dg-final { scan-assembler "[concat {\tdmultu\t\$4,\$[0-9]+[^\n]+umuldi3_highpart[^\n]+\n\tmfhi\t\$[0-9]+\n}]" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-2.c b/gcc/testsuite/gcc.target/mips/fix-r4000-2.c
new file mode 100644
index 00000000000..038dd5ecd49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-2.c
@@ -0,0 +1,7 @@
+/* { dg-mips-options "-mips1 -mfix-r4000 -O2 -dp -EB" } */
+typedef int int32_t;
+typedef long long int64_t;
+int32_t foo (int32_t x, int32_t y) { return ((int64_t) x * y) >> 32; }
+/* ??? A highpart pattern would be a better choice, but we currently
+ don't use them. */
+/* { dg-final { scan-assembler "[concat {\tmult\t\$[45],\$[45][^\n]+mulsidi3_32bit_r4000[^\n]+\n\tmflo\t\$3\n\tmfhi\t\$2\n}]" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-3.c b/gcc/testsuite/gcc.target/mips/fix-r4000-3.c
new file mode 100644
index 00000000000..43189430496
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-3.c
@@ -0,0 +1,7 @@
+/* { dg-mips-options "-mips1 -mfix-r4000 -O2 -dp -EB" } */
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+uint32_t foo (uint32_t x, uint32_t y) { return ((uint64_t) x * y) >> 32; }
+/* ??? A highpart pattern would be a better choice, but we currently
+ don't use them. */
+/* { dg-final { scan-assembler "[concat {\tmultu\t\$[45],\$[45][^\n]+umulsidi3_32bit_r4000[^\n]+\n\tmflo\t\$3\n\tmfhi\t\$2\n}]" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-4.c b/gcc/testsuite/gcc.target/mips/fix-r4000-4.c
new file mode 100644
index 00000000000..7acb2374d5a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-4.c
@@ -0,0 +1,8 @@
+/* ??? At the moment, lower-subreg.c decomposes the copy of the multiplication
+ result to $2, which prevents the register allocators from storing the
+ multiplication result in $2. */
+/* { dg-mips-options "-mips1 -mfix-r4000 -O2 -fno-split-wide-types -dp -EL" } */
+typedef int int32_t;
+typedef long long int64_t;
+int64_t foo (int32_t x, int32_t y) { return (int64_t) x * y; }
+/* { dg-final { scan-assembler "[concat {\tmult\t\$[45],\$[45][^\n]+mulsidi3_32bit_r4000[^\n]+\n\tmflo\t\$2\n\tmfhi\t\$3\n}]" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-5.c b/gcc/testsuite/gcc.target/mips/fix-r4000-5.c
new file mode 100644
index 00000000000..86ab8a26eea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-5.c
@@ -0,0 +1,8 @@
+/* ??? At the moment, lower-subreg.c decomposes the copy of the multiplication
+ result to $2, which prevents the register allocators from storing the
+ multiplication result in $2. */
+/* { dg-mips-options "-mips1 -mfix-r4000 -O2 -fno-split-wide-types -dp -EL" } */
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+uint64_t foo (uint32_t x, uint32_t y) { return (uint64_t) x * y; }
+/* { dg-final { scan-assembler "[concat {\tmultu\t\$[45],\$[45][^\n]+umulsidi3_32bit_r4000[^\n]+\n\tmflo\t\$2\n\tmfhi\t\$3\n}]" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-6.c b/gcc/testsuite/gcc.target/mips/fix-r4000-6.c
new file mode 100644
index 00000000000..2c75deddeca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-6.c
@@ -0,0 +1,6 @@
+/* { dg-mips-options "-march=r4000 -mfix-r4000 -mgp64 -O2 -dp" } */
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+int64_t foo (int64_t x, int64_t y) { return x * y; }
+uint64_t bar (uint64_t x, uint64_t y) { return x * y; }
+/* { dg-final { scan-assembler-times "[concat {\tdmult\t\$[45],\$[45][^\n]+muldi3_r4000[^\n]+\n\tmflo\t\$2\n}]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-7.c b/gcc/testsuite/gcc.target/mips/fix-r4000-7.c
new file mode 100644
index 00000000000..e7b9251ceb4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-7.c
@@ -0,0 +1,7 @@
+/* { dg-mips-options "-march=r4000 -mfix-r4000 -O2 -mgp64 -dp -EB" } */
+typedef long long int64_t;
+typedef int int128_t __attribute__((mode(TI)));
+int64_t foo (int64_t x, int64_t y) { return ((int128_t) x * y) >> 64; }
+/* ??? A highpart pattern would be a better choice, but we currently
+ don't use them. */
+/* { dg-final { scan-assembler "[concat {\tdmult\t\$[45],\$[45][^\n]+mulditi3[^\n]+\n\tmflo\t\$3\n\tmfhi\t\$2\n}]" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-8.c b/gcc/testsuite/gcc.target/mips/fix-r4000-8.c
new file mode 100644
index 00000000000..5089b99e08d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-8.c
@@ -0,0 +1,7 @@
+/* { dg-mips-options "-march=r4000 -mfix-r4000 -O2 -mgp64 -dp -EB" } */
+typedef unsigned long long uint64_t;
+typedef unsigned int uint128_t __attribute__((mode(TI)));
+uint64_t foo (uint64_t x, uint64_t y) { return ((uint128_t) x * y) >> 64; }
+/* ??? A highpart pattern would be a better choice, but we currently
+ don't use them. */
+/* { dg-final { scan-assembler "[concat {\tdmultu\t\$[45],\$[45][^\n]+umulditi3[^\n]+\n\tmflo\t\$3\n\tmfhi\t\$2\n}]" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-r4000-9.c b/gcc/testsuite/gcc.target/mips/fix-r4000-9.c
new file mode 100644
index 00000000000..55183396f07
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r4000-9.c
@@ -0,0 +1,8 @@
+/* ??? At the moment, lower-subreg.c decomposes the copy of the multiplication
+ result to $2, which prevents the register allocators from storing the
+ multiplication result in $2. */
+/* { dg-mips-options "-mips3 -mfix-r4000 -mgp64 -O2 -fno-split-wide-types -dp -EL" } */
+typedef long long int64_t;
+typedef int int128_t __attribute__((mode(TI)));
+int128_t foo (int64_t x, int64_t y) { return (int128_t) x * y; }
+/* { dg-final { scan-assembler "[concat {\tdmult\t\$[45],\$[45][^\n]+mulditi3_r4000[^\n]+\n\tmflo\t\$2\n\tmfhi\t\$3\n}]" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-vr4130-1.c b/gcc/testsuite/gcc.target/mips/fix-vr4130-1.c
index 27ef5ef06eb..48840accd62 100644
--- a/gcc/testsuite/gcc.target/mips/fix-vr4130-1.c
+++ b/gcc/testsuite/gcc.target/mips/fix-vr4130-1.c
@@ -1,4 +1,8 @@
/* { dg-do compile } */
/* { dg-mips-options "-march=vr4130 -mfix-vr4130" } */
-NOMIPS16 int foo (void) { int r; asm ("# foo" : "=h" (r)); return r; }
+NOMIPS16 unsigned int
+foo (unsigned int x, unsigned int y)
+{
+ return x % y;
+}
/* { dg-final { scan-assembler "\tmacchi\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-vr4130-3.c b/gcc/testsuite/gcc.target/mips/fix-vr4130-3.c
index 2f4f48689f6..5cc32cafe43 100644
--- a/gcc/testsuite/gcc.target/mips/fix-vr4130-3.c
+++ b/gcc/testsuite/gcc.target/mips/fix-vr4130-3.c
@@ -1,10 +1,8 @@
/* { dg-do compile } */
/* { dg-mips-options "-march=vr4130 -mgp64 -mfix-vr4130" } */
-NOMIPS16 long long
-foo (void)
+NOMIPS16 unsigned long long
+foo (unsigned long long x, unsigned long long y)
{
- long long r;
- asm ("# foo" : "=h" (r));
- return r;
+ return x % y;
}
/* { dg-final { scan-assembler "\tdmacchi\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/int-moves-1.c b/gcc/testsuite/gcc.target/mips/int-moves-1.c
new file mode 100644
index 00000000000..62e659a93fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/int-moves-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile { target mips16_attribute } } */
+/* { dg-mips-options "-mgp64 -msoft-float -O2 -EL" } */
+/* { dg-add-options mips16_attribute } */
+
+typedef unsigned uint128_t __attribute__((mode(TI)));
+
+extern uint128_t g[16];
+extern unsigned char gstuff[0x10000];
+
+NOMIPS16 uint128_t
+foo (uint128_t i1, uint128_t i2, uint128_t i3, uint128_t i4,
+ uint128_t *x, unsigned char *lstuff)
+{
+ g[0] = i1;
+ g[1] = i2;
+ g[2] = i3;
+ g[3] = i4;
+ x[0] = x[4];
+ x[1] = 0;
+ x[2] = ((uint128_t) 0x123456789abcdefULL << 64) | 0xaabbccddeeff1122ULL;
+ x[3] = g[4];
+ x[4] = *(uint128_t *) (lstuff + 0x7fff);
+ return *(uint128_t *) (gstuff + 0x7fff);
+}
+
+MIPS16 uint128_t
+bar (uint128_t i1, uint128_t i2, uint128_t i3, uint128_t i4,
+ uint128_t *x, unsigned char *lstuff)
+{
+ g[0] = i1;
+ g[1] = i2;
+ g[2] = i3;
+ g[3] = i4;
+ x[0] = x[4];
+ x[1] = 0;
+ x[2] = ((uint128_t) 0x123456789abcdefULL << 64) | 0xaabbccddeeff1122ULL;
+ x[3] = g[4];
+ x[4] = *(uint128_t *) (lstuff + 0x7fff);
+ return *(uint128_t *) (gstuff + 0x7fff);
+}
diff --git a/gcc/testsuite/gcc.target/mips/int-moves-2.c b/gcc/testsuite/gcc.target/mips/int-moves-2.c
new file mode 100644
index 00000000000..325bfceb029
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/int-moves-2.c
@@ -0,0 +1,40 @@
+/* { dg-do compile { target mips16_attribute } } */
+/* { dg-mips-options "-mgp64 -msoft-float -O2 -EB" } */
+/* { dg-add-options mips16_attribute } */
+
+typedef unsigned uint128_t __attribute__((mode(TI)));
+
+extern uint128_t g[16];
+extern unsigned char gstuff[0x10000];
+
+NOMIPS16 uint128_t
+foo (uint128_t i1, uint128_t i2, uint128_t i3, uint128_t i4,
+ uint128_t *x, unsigned char *lstuff)
+{
+ g[0] = i1;
+ g[1] = i2;
+ g[2] = i3;
+ g[3] = i4;
+ x[0] = x[4];
+ x[1] = 0;
+ x[2] = ((uint128_t) 0x123456789abcdefULL << 64) | 0xaabbccddeeff1122ULL;
+ x[3] = g[4];
+ x[4] = *(uint128_t *) (lstuff + 0x7fff);
+ return *(uint128_t *) (gstuff + 0x7fff);
+}
+
+MIPS16 uint128_t
+bar (uint128_t i1, uint128_t i2, uint128_t i3, uint128_t i4,
+ uint128_t *x, unsigned char *lstuff)
+{
+ g[0] = i1;
+ g[1] = i2;
+ g[2] = i3;
+ g[3] = i4;
+ x[0] = x[4];
+ x[1] = 0;
+ x[2] = ((uint128_t) 0x123456789abcdefULL << 64) | 0xaabbccddeeff1122ULL;
+ x[3] = g[4];
+ x[4] = *(uint128_t *) (lstuff + 0x7fff);
+ return *(uint128_t *) (gstuff + 0x7fff);
+}
diff --git a/gcc/testsuite/gcc.target/mips/pr35232.c b/gcc/testsuite/gcc.target/mips/pr35232.c
deleted file mode 100644
index c0e0649b52e..00000000000
--- a/gcc/testsuite/gcc.target/mips/pr35232.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* { dg-do run } */
-/* { dg-mips-options "-O" } */
-
-NOMIPS16 unsigned int
-f1 (unsigned long long x)
-{
- unsigned int r;
- asm ("# %0" : "=a" (r) : "0" (x));
- asm ("# %0" : "=h" (r) : "0" (r));
- return r;
-}
-
-int
-main (void)
-{
- return f1 (4) != 4;
-}
diff --git a/gcc/testsuite/gcc.target/mips/timode-1.c b/gcc/testsuite/gcc.target/mips/timode-1.c
new file mode 100644
index 00000000000..8f07db98559
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/timode-1.c
@@ -0,0 +1,65 @@
+/* { dg-mips-options "-mgp64" } */
+typedef int int128_t __attribute__((mode(TI)));
+typedef unsigned int uint128_t __attribute__((mode(TI)));
+
+#define UINT128_CONST(A, B) \
+ (((uint128_t) (0x ## A ## ULL) << 64) | (0x ## B ## ULL))
+
+volatile uint128_t a = UINT128_CONST (1111111111111111, a222222222222222);
+volatile uint128_t b = UINT128_CONST (0000000000000005, 0000000000000003);
+volatile uint128_t c = UINT128_CONST (5dddddddddddddde, e666666666666666);
+volatile uint128_t d = UINT128_CONST (e612340000000000, 5000000000234500);
+volatile uint128_t e = UINT128_CONST (43f011dddddddddf, 366666666689ab66);
+volatile uint128_t f = UINT128_CONST (4210100000000000, 1000000000010100);
+volatile uint128_t g = UINT128_CONST (a5e225dddddddddf, 6666666666aaee66);
+volatile uint128_t h = UINT128_CONST (e7f235dddddddddf, 7666666666abef66);
+volatile uint128_t i = UINT128_CONST (5e225dddddddddf6, 666666666aaee660);
+volatile uint128_t j = UINT128_CONST (0a5e225ddddddddd, f6666666666aaee6);
+volatile uint128_t k = UINT128_CONST (fa5e225ddddddddd, f6666666666aaee6);
+
+volatile int amount = 4;
+
+volatile uint128_t result;
+
+int
+main (void)
+{
+ result = a * b;
+ if (result != c)
+ return 1;
+
+ result = c + d;
+ if (result != e)
+ return 1;
+
+ result = e - d;
+ if (result != c)
+ return 1;
+
+ result = d & e;
+ if (result != f)
+ return 1;
+
+ result = d ^ e;
+ if (result != g)
+ return 1;
+
+ result = d | e;
+ if (result != h)
+ return 1;
+
+ result = g << amount;
+ if (result != i)
+ return 1;
+
+ result = g >> amount;
+ if (result != j)
+ return 1;
+
+ result = (int128_t) g >> amount;
+ if (result != k)
+ return 1;
+
+ return 0;
+}
+/* { dg-final { scan-assembler-not "\tjal" } } */
diff --git a/gcc/testsuite/gcc.target/mips/timode-2.c b/gcc/testsuite/gcc.target/mips/timode-2.c
new file mode 100644
index 00000000000..025dc21810a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/timode-2.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target mips64 } } */
+typedef int int128_t __attribute__((mode(TI)));
+typedef unsigned int uint128_t __attribute__((mode(TI)));
+
+#define UINT128_CONST(A, B) \
+ (((uint128_t) (0x ## A ## ULL) << 64) | (0x ## B ## ULL))
+
+volatile uint128_t a = UINT128_CONST (1111111111111111, a222222222222222);
+volatile uint128_t b = UINT128_CONST (0000000000000005, 0000000000000003);
+volatile uint128_t c = UINT128_CONST (5dddddddddddddde, e666666666666666);
+volatile uint128_t d = UINT128_CONST (e612340000000000, 5000000000234500);
+volatile uint128_t e = UINT128_CONST (43f011dddddddddf, 366666666689ab66);
+volatile uint128_t f = UINT128_CONST (4210100000000000, 1000000000010100);
+volatile uint128_t g = UINT128_CONST (a5e225dddddddddf, 6666666666aaee66);
+volatile uint128_t h = UINT128_CONST (e7f235dddddddddf, 7666666666abef66);
+volatile uint128_t i = UINT128_CONST (5e225dddddddddf6, 666666666aaee660);
+volatile uint128_t j = UINT128_CONST (0a5e225ddddddddd, f6666666666aaee6);
+volatile uint128_t k = UINT128_CONST (fa5e225ddddddddd, f6666666666aaee6);
+
+volatile int amount = 4;
+
+volatile uint128_t result;
+
+int
+main (void)
+{
+ result = a * b;
+ if (result != c)
+ return 1;
+
+ result = c + d;
+ if (result != e)
+ return 1;
+
+ result = e - d;
+ if (result != c)
+ return 1;
+
+ result = d & e;
+ if (result != f)
+ return 1;
+
+ result = d ^ e;
+ if (result != g)
+ return 1;
+
+ result = d | e;
+ if (result != h)
+ return 1;
+
+ result = g << amount;
+ if (result != i)
+ return 1;
+
+ result = g >> amount;
+ if (result != j)
+ return 1;
+
+ result = (int128_t) g >> amount;
+ if (result != k)
+ return 1;
+
+ return 0;
+}