Index: gcc.target/mips/umips-movep-2.c =================================================================== --- gcc.target/mips/umips-movep-2.c (revision 0) +++ gcc.target/mips/umips-movep-2.c (revision 0) @@ -0,0 +1,12 @@ +/* Check that we can generate the MOVEP instruction. */ +/* { dg-options "-fpeephole2 (-mmicromips)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +int bar (int, int); + +int +foo (int n, int a) +{ + return bar (0, 0); +} +/* { dg-final { scan-assembler "\tmovep\t" } } */ Index: gcc.target/mips/umips-constraints-1.c =================================================================== --- gcc.target/mips/umips-constraints-1.c (revision 0) +++ gcc.target/mips/umips-constraints-1.c (revision 0) @@ -0,0 +1,14 @@ +/* { dg-options "(-mmicromips)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +MICROMIPS void +foo (int *x) +{ + asm volatile ("insn1\t%a0" :: "ZD" (&x[0])); + asm volatile ("insn2\t%a0" :: "ZD" (&x[511])); + asm volatile ("insn3\t%a0" :: "ZD" (&x[512])); +} + +/* { dg-final { scan-assembler "\tinsn1\t0\\(" } } */ +/* { dg-final { scan-assembler "\tinsn2\t2044\\(" } } */ +/* { dg-final { scan-assembler-not "\tinsn3\t2048\\(" } } */ Index: gcc.target/mips/mips.exp =================================================================== --- gcc.target/mips/mips.exp (revision 195578) +++ gcc.target/mips/mips.exp (working copy) @@ -238,6 +238,7 @@ set mips_option_groups { fp "-mfp(32|64)" gp "-mgp(32|64)" long "-mlong(32|64)" + micromips "-mmicromips|-mno-micromips" mips16 "-mips16|-mno-mips16|-mflip-mips16" mips3d "-mips3d|-mno-mips3d" pic "-f(no-|)(pic|PIC)" @@ -1246,6 +1247,10 @@ proc mips-dg-options { args } { append extra_tool_flags " -DMIPS16=__attribute__((mips16))" } + if { [mips_have_test_option_p options "-mmicromips"] } { + append extra_tool_flags " -DMICROMIPS=__attribute__((micromips))" + } + # Use our version of gcc-dg-test for this test. if { ![string equal [info procs "mips-gcc-dg-test"] ""] } { rename gcc-dg-test mips-old-gcc-dg-test @@ -1275,6 +1280,6 @@ proc mips-gcc-dg-test { prog do_what extra_tool_fl dg-init mips-dg-init gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] \ - "-DNOMIPS16=__attribute__((nomips16))" + "-DNOMIPS16=__attribute__((nomips16)) -DNOMICROMIPS=__attribute__((nomicromips)) -DNOCOMPRESSION=__attribute__((nocompression))" mips-dg-finish dg-finish Index: gcc.target/mips/umips-lwp-swp-1.c =================================================================== --- gcc.target/mips/umips-lwp-swp-1.c (revision 0) +++ gcc.target/mips/umips-lwp-swp-1.c (revision 0) @@ -0,0 +1,17 @@ +/* Test that an SWP can be generated when the instruction order is reversed: + + ie. ST $3, mem+4 + ST $2, mem +*/ + +/* { dg-options "-fpeephole2 -mgp32 (-mmicromips)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ +/* { dg-options "-fpeephole2 -mgp32 (-mmicromips)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +void MICROMIPS +foo (long long l1, long long *l2) +{ + *l2 = l1; +} +/* { dg-final { scan-assembler "\tswp\t\\\$4,0\\(\\\$6\\)" } }*/ Index: gcc.target/mips/umips-constraints-2.c =================================================================== --- gcc.target/mips/umips-constraints-2.c (revision 0) +++ gcc.target/mips/umips-constraints-2.c (revision 0) @@ -0,0 +1,14 @@ +/* { dg-options "(-mmicromips)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +MICROMIPS void +foo (int *x) +{ + asm volatile ("insn1\t%0" :: "ZC" (x[0])); + asm volatile ("insn2\t%0" :: "ZC" (x[511])); + asm volatile ("insn3\t%0" :: "ZC" (x[512])); +} + +/* { dg-final { scan-assembler "\tinsn1\t0\\(" } } */ +/* { dg-final { scan-assembler "\tinsn2\t2044\\(" } } */ +/* { dg-final { scan-assembler-not "\tinsn3\t2048\\(" } } */ Index: gcc.target/mips/umips-save-restore-1.c =================================================================== --- gcc.target/mips/umips-save-restore-1.c (revision 0) +++ gcc.target/mips/umips-save-restore-1.c (revision 0) @@ -0,0 +1,18 @@ +/* Check that we can use the swm/lwm instructions. */ +/* { dg-options "-mabi=32 (-mmicromips)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +int bar (int, int, int, int, int); + +MICROMIPS int +foo (int n, int a, int b, int c, int d) +{ + int i, j; + + i = bar (n, a, b, c, d); + j = bar (n, a, b, c, d); + return i + j; +} + +/* { dg-final { scan-assembler "\tswm\t\\\$16-\\\$2(0|1),\\\$31" } } */ +/* { dg-final { scan-assembler "\tlwm\t\\\$16-\\\$2(0|1),\\\$31" } } */ Index: gcc.target/mips/umips-lwp-swp-2.c =================================================================== --- gcc.target/mips/umips-lwp-swp-2.c (revision 0) +++ gcc.target/mips/umips-lwp-swp-2.c (revision 0) @@ -0,0 +1,176 @@ +/* Test that an SWP can be generated when the instruction order is not reversed: + + ie. ST $2, mem + ST $2, mem+4 +*/ + +/* { dg-options "-fpeephole2 -mgp32 (-mmicromips)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +#include + +void MICROMIPS s(int, ...); +void MICROMIPS z(int, ...); +void MICROMIPS c(int, ...); + +typedef int l[500]; + +void +MICROMIPS f (int n) +{ + int i; + l a0, a1, a2, a3, a4, a5, a6, a7, a8, a9; + l a10, a11, a12, a13, a14, a15, a16, a17, a18, a19; + l a20, a21, a22, a23, a24, a25, a26, a27, a28, a29; + l a30, a31, a32, a33, a34, a35, a36, a37, a38, a39; + int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; + int i10, i11, i12, i13, i14, i15, i16, i17, i18, i19; + int i20, i21, i22, i23, i24, i25, i26, i27, i28, i29; + int i30, i31, i32, i33, i34, i35, i36, i37, i38, i39; + + for (i = 0; i < n; i++) + { + s (40, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, + a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, + a30, a31, a32, a33, a34, a35, a36, a37, a38, a39); + i0 = a0[0]; + i1 = a1[0]; + i2 = a2[0]; + i3 = a3[0]; + i4 = a4[0]; + i5 = a5[0]; + i6 = a6[0]; + i7 = a7[0]; + i8 = a8[0]; + i9 = a9[0]; + i10 = a10[0]; + i11 = a11[0]; + i12 = a12[0]; + i13 = a13[0]; + i14 = a14[0]; + i15 = a15[0]; + i16 = a16[0]; + i17 = a17[0]; + i18 = a18[0]; + i19 = a19[0]; + i20 = a20[0]; + i21 = a21[0]; + i22 = a22[0]; + i23 = a23[0]; + i24 = a24[0]; + i25 = a25[0]; + i26 = a26[0]; + i27 = a27[0]; + i28 = a28[0]; + i29 = a29[0]; + i30 = a30[0]; + i31 = a31[0]; + i32 = a32[0]; + i33 = a33[0]; + i34 = a34[0]; + i35 = a35[0]; + i36 = a36[0]; + i37 = a37[0]; + i38 = a38[0]; + i39 = a39[0]; + z (40, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, + a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, + a30, a31, a32, a33, a34, a35, a36, a37, a38, a39); + a0[i0] = i0; + a1[i1] = i1; + a2[i2] = i2; + a3[i3] = i3; + a4[i4] = i4; + a5[i5] = i5; + a6[i6] = i6; + a7[i7] = i7; + a8[i8] = i8; + a9[i9] = i9; + a10[i10] = i10; + a11[i11] = i11; + a12[i12] = i12; + a13[i13] = i13; + a14[i14] = i14; + a15[i15] = i15; + a16[i16] = i16; + a17[i17] = i17; + a18[i18] = i18; + a19[i19] = i19; + a20[i20] = i20; + a21[i21] = i21; + a22[i22] = i22; + a23[i23] = i23; + a24[i24] = i24; + a25[i25] = i25; + a26[i26] = i26; + a27[i27] = i27; + a28[i28] = i28; + a29[i29] = i29; + a30[i30] = i30; + a31[i31] = i31; + a32[i32] = i32; + a33[i33] = i33; + a34[i34] = i34; + a35[i35] = i35; + a36[i36] = i36; + a37[i37] = i37; + a38[i38] = i38; + a39[i39] = i39; + c (40, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, + a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, + a30, a31, a32, a33, a34, a35, a36, a37, a38, a39); + } +} + +int +MICROMIPS main () +{ + f (1); +} + +void +MICROMIPS s (int n, ...) +{ + va_list list; + + va_start (list, n); + while (n--) + { + int *a = va_arg (list, int *); + a[0] = n; + } + va_end (list); +} + +void +MICROMIPS z (int n, ...) +{ + va_list list; + + va_start (list, n); + while (n--) + { + int *a = va_arg (list, int *); + __builtin_memset (a, 0, sizeof (l)); + } + va_end (list); +} + +void +MICROMIPS c (int n, ...) +{ + va_list list; + + va_start (list, n); + while (n--) + { + int *a = va_arg (list, int *); + if (a[n] != n) + ; + } + va_end (list); +} +/* { dg-final { scan-assembler "\tswp" } } */ Index: gcc.target/mips/umips-save-restore-2.c =================================================================== --- gcc.target/mips/umips-save-restore-2.c (revision 0) +++ gcc.target/mips/umips-save-restore-2.c (revision 0) @@ -0,0 +1,16 @@ +/* Check that we can use the save instruction to save spilled arguments. */ +/* { dg-options "-mabi=32 (-mmicromips)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +MICROMIPS void +foo (int *a, int b, int c) +{ + asm volatile ("" ::: "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16", + "$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24", + "$25", "$30", "memory"); + a[b] = 1; + a[c] = 1; +} +/* { dg-final { scan-assembler "\tswm\t\\\$16-\\\$23,\\\$fp" } } */ +/* { dg-final { scan-assembler "\tlwm\t\\\$16-\\\$23,\\\$fp" } } */ Index: gcc.target/mips/umips-lwp-swp-volatile.c =================================================================== --- gcc.target/mips/umips-lwp-swp-volatile.c (revision 0) +++ gcc.target/mips/umips-lwp-swp-volatile.c (revision 0) @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-mmicromips" } */ + +/* This test ensures that we do not generate microMIPS SWP or LWP + instructions when any component of the accessed memory is volatile; + they are unsafe for such since they might cause replay of partial + accesses if interrupted by an exception. */ + +static void set_csr (volatile void *p, int v) +{ + *(volatile int *) (p) = v; +} + +static int get_csr (volatile void *p) +{ + return *(volatile int *) (p); +} + +int main () +{ + int i, q = 0, p = 0, r = 0; + + for (i = 0; i < 20; i++) + { + set_csr ((volatile void *) 0xbf0100a8, 0xffff0002); + set_csr ((volatile void *) 0xbf0100a4, 0x80000008); + } + + for (i = 0; i < 20; i++) + { + register int k, j; + k = get_csr ((volatile void *) 0xbf0100b8); + p += k; + j = get_csr ((volatile void *) 0xbf0100b4); + r += j; + q = j + k; + } + return q + r + p; +} + +/* { dg-final { scan-assembler-not "\tswp" } } */ +/* { dg-final { scan-assembler-not "\tlwp" } } */ Index: gcc.target/mips/umips-save-restore-3.c =================================================================== --- gcc.target/mips/umips-save-restore-3.c (revision 0) +++ gcc.target/mips/umips-save-restore-3.c (revision 0) @@ -0,0 +1,14 @@ +/* Check that we can use the swm instruction to save $16, $17 and $31. */ +/* { dg-options "-mgp32 (-mmicromips)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +void bar (void); + +MICROMIPS void +foo (void) +{ + bar (); + asm volatile ("" ::: "$16", "$17"); +} +/* { dg-final { scan-assembler "\tswm\t\\\$16-\\\$17,\\\$31" } } */ +/* { dg-final { scan-assembler "\tlwm\t\\\$16-\\\$17,\\\$31" } } */ Index: gcc.target/mips/umips-movep-1.c =================================================================== --- gcc.target/mips/umips-movep-1.c (revision 0) +++ gcc.target/mips/umips-movep-1.c (revision 0) @@ -0,0 +1,16 @@ +/* Check that we can generate the MOVEP instruction. */ +/* { dg-options "-mgp32 -fpeephole2 (-mmicromips)" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +long long bar (long long, long long); + +MICROMIPS long long +foo (long long n, long long a) +{ + long long i, j; + + i = bar (n, a); + j = bar (n, a); + return i + j; +} +/* { dg-final { scan-assembler "\tmovep\t" } } */