diff options
author | Ben Cheng <bccheng@google.com> | 2014-03-25 22:37:19 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2014-03-25 22:37:19 -0700 |
commit | 1bc5aee63eb72b341f506ad058502cd0361f0d10 (patch) | |
tree | c607e8252f3405424ff15bc2d00aa38dadbb2518 /gcc-4.9/gcc/testsuite/gcc.target/sh | |
parent | 283a0bf58fcf333c58a2a92c3ebbc41fb9eb1fdb (diff) | |
download | toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.zip toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.gz toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.bz2 |
Initial checkin of GCC 4.9.0 from trunk (r208799).
Change-Id: I48a3c08bb98542aa215912a75f03c0890e497dba
Diffstat (limited to 'gcc-4.9/gcc/testsuite/gcc.target/sh')
160 files changed, 7011 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/20080410-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/20080410-1.c new file mode 100644 index 0000000..c398674 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/20080410-1.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ +/* { dg-skip-if "" { "sh*-*-*" } "-mb" "" } */ +/* { dg-final { scan-assembler-not "add\tr0,r0" } } */ + +/* This test checks chain reloads conflicts. If they don't + conflict, the same hard register R0 is used for the both reloads + but in this case the second reload needs an intermediate register + (which is the reload register). As the result we have the + following code + + mov #4,r0 -- first reload + mov r14,r0 -- second reload + add r0,r0 -- second reload + + The right code should be + + mov #4,r0 -- first reload + mov r14,r1 -- second reload + add r0,r1 -- second reload + +*/ + +_Complex float foo_float (); + +void bar_float () +{ + __real foo_float (); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/attr-isr-nosave_low_regs.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/attr-isr-nosave_low_regs.c new file mode 100644 index 0000000..2f1d518 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/attr-isr-nosave_low_regs.c @@ -0,0 +1,32 @@ +/* A call will clobber all call-saved registers. + If #pragma nosave_low_regs is specified, do not save/restore r0..r7. + (On SH3* and SH4* r0..r7 are banked) + One of these registers will also do fine to hold the function address. + Call-saved registers r8..r13 also don't need to be restored. */ +/* { dg-do compile { target { { "sh*-*-*" } && nonpic } } } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1*" "-m2*" "-m5*" } { "" } } */ +/* { dg-options "-O" } */ +/* { dg-final { scan-assembler-times "rte" 1 } } */ +/* { dg-final { scan-assembler-not "\[^f\]r\[0-9\]\[ \t\]*," } } */ +/* { dg-final { scan-assembler-not "\[^f\]r\[89\]" } } */ +/* { dg-final { scan-assembler-not "\[^f\]r1\[,0-3\]" } } */ +/* { dg-final { scan-assembler-times "macl" 2 } } */ + +extern void bar (void); + +void +foo (void) +{ +} + +#pragma interrupt +void +( __attribute__ ((nosave_low_regs)) isr) (void) +{ + bar (); +} + +void +delay (int a) +{ +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/attr-isr-trap_exit.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/attr-isr-trap_exit.c new file mode 100644 index 0000000..a45e92f --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/attr-isr-trap_exit.c @@ -0,0 +1,31 @@ +/* Check that trapa / interrput_handler attributes can paired in + either order. */ +/* { dg-do compile } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-options "-O" } */ +/* { dg-final { scan-assembler "trapa\[ \t\]\[ \t\]*#4"} } */ +/* { dg-final { scan-assembler-times "trapa" 1 } } */ + +void h0 (void) __attribute__ ((trap_exit (4))) __attribute__ ((interrupt_handler)); +void h1 (void) __attribute__ ((interrupt_handler)) __attribute__ ((trap_exit (5))); + +void +foo (void) +{ +} + +void +h0 (void) +{ +} + +void delay +(int a) +{ +} + +int +main (void) +{ + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/attr-isr-trapa.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/attr-isr-trapa.c new file mode 100644 index 0000000..e1bc8a4 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/attr-isr-trapa.c @@ -0,0 +1,18 @@ +/* Check that no interrupt-specific register saves are generated. */ +/* { dg-do compile { target { { "sh*-*-*" } && nonpic } } } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-options "-O" } */ +/* { dg-final { scan-assembler-times "rte" 1 } } */ +/* { dg-final { scan-assembler-not "r\[0-7\]\[ \t,\]\[^\n\]*r15" } } */ +/* { dg-final { scan-assembler-not "@r15\[^\n\]*r\[0-7\]\n" } } */ +/* { dg-final { scan-assembler-not "r\[8-9\]" } } */ +/* { dg-final { scan-assembler-not "r1\[,0-3\]" } } */ +/* { dg-final { scan-assembler-not "macl" } } */ + +extern void foo (void); + +void +(__attribute__ ((trapa_handler)) isr) (void) +{ + foo (); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/cmpstr.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/cmpstr.c new file mode 100644 index 0000000..4d638cc --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/cmpstr.c @@ -0,0 +1,27 @@ +/* Check that the __builtin_strcmp function is inlined with cmp/str + when optimizing for speed. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "jmp" } } */ +/* { dg-final { scan-assembler-times "cmp/str" 3 } } */ +/* { dg-final { scan-assembler-times "tst\t#3" 2 } } */ + +test00 (const char *s1, const char *s2) +{ + return __builtin_strcmp (s1, s2); +} + +/* NB: This might change as further optimisation might detect the + max length and fallback to cmpstrn. */ +test01(const char *s2) +{ + return __builtin_strcmp ("abc", s2); +} + +/* Check that no test for alignment is needed. */ +test03(const char *s1, const char *s2) +{ + return __builtin_strcmp (__builtin_assume_aligned (s1, 4), + __builtin_assume_aligned (s2, 4)); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/cmpstrn.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/cmpstrn.c new file mode 100644 index 0000000..3a1d0d1 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/cmpstrn.c @@ -0,0 +1,28 @@ +/* Check that the __builtin_strncmp function is inlined + when optimizing for speed. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "jmp" } } */ +/* { dg-final { scan-assembler-times "cmp/str" 1 } } */ + +/* Test that cmp/str is not used for small lengths. */ +test01(const char *s1) +{ + return __builtin_strncmp (s1, "abcde", 3); +} + +/* Test that the cmp/str loop is used. */ +test02(const char *s1) +{ + return __builtin_strncmp (s1, "abcdefghi", 8); +} + +/* Test that no call is generated */ +test03(const char *s1, int n) +{ + return __builtin_strncmp (s1, "abcde", n); +} + + + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/fpul-usage-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/fpul-usage-1.c new file mode 100644 index 0000000..5c3bb19 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/fpul-usage-1.c @@ -0,0 +1,24 @@ +/* Check that the FPUL register is used when reading a float as an int and + vice versa, as opposed to pushing and popping the values over the stack. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler "fpul" } } */ +/* { dg-final { scan-assembler-not "r15" } } */ + +int +float_as_int (float val) +{ + union { float f; int i; } u; + u.f = val; + return u.i; +} + +float +int_as_float (int val) +{ + union { float f; int i; } u; + u.i = val; + return u.f; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/mfmovd.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/mfmovd.c new file mode 100644 index 0000000..ce3e993 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/mfmovd.c @@ -0,0 +1,22 @@ +/* Verify that we generate fmov.d instructions to move doubles when -mfmovd + option is enabled. */ +/* { dg-do compile } */ +/* { dg-require-effective-target hard_float } */ +/* { dg-options "-mfmovd" } */ +/* { dg-skip-if "" { *-*-* } { "*-single-only" } { "" } } */ +/* { dg-final { scan-assembler "fmov.d" } } */ + +extern double g; + +void +f (double d) +{ + g = d; +} + +extern float h; + +void f2 () +{ + h = g; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-1.c new file mode 100644 index 0000000..3e9b785 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fomit-frame-pointer" } */ +/* { dg-final { scan-assembler "mov fr4,fr.; mov fr5,fr." { target sh-*-* } } } */ +/* { dg-final { scan-assembler "mov fr4,fr.; mov fr5,fr." { target sh[1234lb]*-*-* } } } */ +/* { dg-final { scan-assembler "mov fr0,fr.; mov fr1,fr." { target sh[56]*-*-* } } } */ +double +f (double d) +{ + double r; + +#if defined (__SH_FPU_DOUBLE__) + asm ("mov %S1,%S0; mov %R1,%R0" : "=f" (r) : "f" (d)); +#else + asm ("mov fr4,fr4; mov fr5,fr5"); +#endif + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-2-mb.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-2-mb.c new file mode 100644 index 0000000..531ed39 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-2-mb.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-mb -O2 -fomit-frame-pointer" } */ +/* { dg-final { scan-assembler "mov @r.,r.; mov @\\(4,r.\\),r." } } */ +double d; + +double +f (void) +{ + double r; + +/* If -ml from the target options is passed after -mb from dg-options, we + end up with th reverse endianness. */ +#if TARGET_SHMEDIA || defined (__LITTLE_ENDIAN__) + asm ("mov @r1,r3; mov @(4,r1),r4"); +#else + asm ("mov %S1,%S0; mov %R1,%R0" : "=&r" (r) : "m" (d)); +#endif + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-2-ml.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-2-ml.c new file mode 100644 index 0000000..6948f47 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-2-ml.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fomit-frame-pointer" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-mb" && "-m5*"} { "" } } */ +/* { dg-final { scan-assembler "mov @\\(4,r.\\),r.; mov @r.,r." } } */ +double d; + +double +f (void) +{ + double r; + asm ("mov %S1,%S0; mov %R1,%R0" : "=&r" (r) : "m" (d)); + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-3.c new file mode 100644 index 0000000..a672784 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-3.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fomit-frame-pointer" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m2e" "-m3e" "*single-only" } { "" } } */ +/* { dg-final { scan-assembler "mov #?0,r.*; mov #?20,r" } } */ +/* { dg-final { scan-assembler "mov #?1077149696,r.*; mov #?0,r" } } */ +double +f () +{ + double r; + + asm ("mov %S1,%S0; mov %R1,%R0" : "=r" (r) : "i" (20)); + asm ("mov %S1,%S0; mov %R1,%R0" : "+r" (r) : "i" (20.)); + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-4.c new file mode 100644 index 0000000..c848c26 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr21255-4.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { sh*-*-* && nonpic } } } */ +/* { dg-options "-O2 -fomit-frame-pointer" } */ + +double +f () +{ + double r; + + asm ("mov %S1,%S0; mov %R1,%R0" : "=r" (r) : "i" (f)); +/* { dg-error "invalid operand to %S" "" {target "sh*-*-*" } 9 } */ +/* { dg-error "invalid operand to %R" "" {target "sh*-*-*" } 9 } */ + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-1.c new file mode 100644 index 0000000..cc6a3f9 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-1.c @@ -0,0 +1,32 @@ +/* Check that fcmp/eq and fcmp/gt instructions are generated by default + (implicit -mieee). */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fcmp/eq" 4 } } */ +/* { dg-final { scan-assembler-times "fcmp/gt" 4 } } */ + +int +test_00 (float a, float b) +{ + return a <= b; +} + +int +test_01 (float a, float b) +{ + return a >= b; +} + +int +test_02 (double a, double b) +{ + return a <= b; +} + +int +test_03 (double a, double b) +{ + return a >= b; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-2.c new file mode 100644 index 0000000..b93ecb8 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-2.c @@ -0,0 +1,32 @@ +/* Check that only the fcmp/gt instruction is generated when specifying + -ffinite-math-only (implicit -mno-ieee). */ +/* { dg-do compile } */ +/* { dg-options "-O1 -ffinite-math-only" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "fcmp/eq" } } */ +/* { dg-final { scan-assembler-times "fcmp/gt" 4 } } */ + +int +test_00 (float a, float b) +{ + return a <= b; +} + +int +test_01 (float a, float b) +{ + return a >= b; +} + +int +test_02 (double a, double b) +{ + return a <= b; +} + +int +test_03 (double a, double b) +{ + return a >= b; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-3.c new file mode 100644 index 0000000..f5f9a5b --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-3.c @@ -0,0 +1,32 @@ +/* Check that fcmp/eq and fcmp/gt instructions are generated when specifying + -ffinite-math-only and -mieee. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -ffinite-math-only -mieee" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fcmp/eq" 4 } } */ +/* { dg-final { scan-assembler-times "fcmp/gt" 4 } } */ + +int +test_00 (float a, float b) +{ + return a <= b; +} + +int +test_01 (float a, float b) +{ + return a >= b; +} + +int +test_02 (double a, double b) +{ + return a <= b; +} + +int +test_03 (double a, double b) +{ + return a >= b; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-4.c new file mode 100644 index 0000000..20178d7 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr33135-4.c @@ -0,0 +1,32 @@ +/* Check that only the fcmp/gt instruction is generated when specifying + -fno-finite-math-only and -mno-ieee. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-finite-math-only -mno-ieee" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "fcmp/eq" } } */ +/* { dg-final { scan-assembler-times "fcmp/gt" 4 } } */ + +int +test_00 (float a, float b) +{ + return a <= b; +} + +int +test_01 (float a, float b) +{ + return a >= b; +} + +int +test_02 (double a, double b) +{ + return a <= b; +} + +int +test_03 (double a, double b) +{ + return a >= b; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr39423-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr39423-1.c new file mode 100644 index 0000000..1e02937 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr39423-1.c @@ -0,0 +1,48 @@ +/* Check that displacement addressing is used for indexed addresses with a + small offset, instead of re-calculating the index. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-not "add\t#1" } } */ + +int +test_00 (int tab[], int index) +{ + return tab[index + 1]; +} + +int +test_01 (short tab[], int index) +{ + return tab[index + 1]; +} + +int +test_02 (unsigned short tab[], int index) +{ + return tab[index + 1]; +} + +int +test_03 (long long tab[], int index) +{ + return (int)tab[index + 1]; +} + +void +test_04 (int tab[], int index, int val) +{ + tab[index + 1] = val; +} + +void +test_05 (short tab[], int index, int val) +{ + tab[index + 1] = (short)val; +} + +void +test_06 (unsigned short tab[], int index, int val) +{ + tab[index + 1] = (unsigned short)val; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr39423-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr39423-2.c new file mode 100644 index 0000000..702384d --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr39423-2.c @@ -0,0 +1,14 @@ +/* Check that displacement addressing is used for indexed addresses with a + small offset, instead of re-calculating the index and that the movu.w + instruction is used on SH2A. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-not "add\t#1" } } */ +/* { dg-final { scan-assembler "movu.w" } } */ + +int +test_00 (unsigned short tab[], int index) +{ + return tab[index + 1]; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr43417.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr43417.c new file mode 100644 index 0000000..081ff46 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr43417.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -m4" } */ + +int pid_count = 0; +main (int argc, char *argv[]) +{ + unsigned int c; + unsigned long long maxbytes = 0; + extern char *optarg; + int i; + int pid_cntr; + int pid; + int pid_list[1000]; + while ((c = getopt (argc, argv, "c:b:p:wvh")) != (-1)) + { + switch ((char) c) + { + case 'b': + maxbytes = atoll (optarg); + } + } + pid = fork (); + while ((pid != 0) && (maxbytes > 1024 * 1024 * 1024)) + { + maxbytes = maxbytes - (1024 * 1024 * 1024); + pid = fork (); + if (pid != 0) + pid_cntr++; + pid_list[i] = pid; + } + while ((pid_count < pid_cntr)) + { + } + kill (pid_list[i], 9); +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49263.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49263.c new file mode 100644 index 0000000..783d865 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49263.c @@ -0,0 +1,86 @@ +/* Verify that TST #imm, R0 instruction is generated if the constant + allows it. Under some circumstances another compare instruction might + be selected, which is also fine. Any AND instructions are considered + counter productive and fail the test. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "and" } } */ + +#define make_func(__valtype__, __valget__, __tstval__, __suff__)\ + int test_imm_##__tstval__##__suff__ (__valtype__ val) \ + {\ + return ((__valget__) & (0x##__tstval__ << 0)) ? -20 : -40;\ + } + +#define make_func_0_F(__valtype__, __valget__, __y__, __suff__)\ + make_func (__valtype__, __valget__, __y__##0, __suff__)\ + make_func (__valtype__, __valget__, __y__##1, __suff__)\ + make_func (__valtype__, __valget__, __y__##2, __suff__)\ + make_func (__valtype__, __valget__, __y__##3, __suff__)\ + make_func (__valtype__, __valget__, __y__##4, __suff__)\ + make_func (__valtype__, __valget__, __y__##5, __suff__)\ + make_func (__valtype__, __valget__, __y__##6, __suff__)\ + make_func (__valtype__, __valget__, __y__##7, __suff__)\ + make_func (__valtype__, __valget__, __y__##8, __suff__)\ + make_func (__valtype__, __valget__, __y__##9, __suff__)\ + make_func (__valtype__, __valget__, __y__##A, __suff__)\ + make_func (__valtype__, __valget__, __y__##B, __suff__)\ + make_func (__valtype__, __valget__, __y__##C, __suff__)\ + make_func (__valtype__, __valget__, __y__##D, __suff__)\ + make_func (__valtype__, __valget__, __y__##E, __suff__)\ + make_func (__valtype__, __valget__, __y__##F, __suff__)\ + +#define make_funcs_0_FF(__valtype__, __valget__, __suff__)\ + make_func_0_F (__valtype__, __valget__, 0, __suff__)\ + make_func_0_F (__valtype__, __valget__, 1, __suff__)\ + make_func_0_F (__valtype__, __valget__, 2, __suff__)\ + make_func_0_F (__valtype__, __valget__, 3, __suff__)\ + make_func_0_F (__valtype__, __valget__, 4, __suff__)\ + make_func_0_F (__valtype__, __valget__, 5, __suff__)\ + make_func_0_F (__valtype__, __valget__, 6, __suff__)\ + make_func_0_F (__valtype__, __valget__, 7, __suff__)\ + make_func_0_F (__valtype__, __valget__, 8, __suff__)\ + make_func_0_F (__valtype__, __valget__, 9, __suff__)\ + make_func_0_F (__valtype__, __valget__, A, __suff__)\ + make_func_0_F (__valtype__, __valget__, B, __suff__)\ + make_func_0_F (__valtype__, __valget__, C, __suff__)\ + make_func_0_F (__valtype__, __valget__, D, __suff__)\ + make_func_0_F (__valtype__, __valget__, E, __suff__)\ + make_func_0_F (__valtype__, __valget__, F, __suff__)\ + +make_funcs_0_FF (signed char*, *val, int8_mem) +make_funcs_0_FF (signed char, val, int8_reg) + +make_funcs_0_FF (unsigned char*, *val, uint8_mem) +make_funcs_0_FF (unsigned char, val, uint8_reg) + +make_funcs_0_FF (short*, *val, int16_mem) +make_funcs_0_FF (short, val, int16_reg) + +make_funcs_0_FF (unsigned short*, *val, uint16_mem) +make_funcs_0_FF (unsigned short, val, uint16_reg) + +make_funcs_0_FF (int*, *val, int32_mem) +make_funcs_0_FF (int, val, int32_reg) + +make_funcs_0_FF (unsigned int*, *val, uint32_mem) +make_funcs_0_FF (unsigned int, val, uint32_reg) + +make_funcs_0_FF (long long*, *val, int64_lowword_mem) +make_funcs_0_FF (long long, val, int64_lowword_reg) + +make_funcs_0_FF (unsigned long long*, *val, uint64_lowword_mem) +make_funcs_0_FF (unsigned long long, val, uint64_lowword_reg) + +make_funcs_0_FF (long long*, *val >> 32, int64_highword_mem) +make_funcs_0_FF (long long, val >> 32, int64_highword_reg) + +make_funcs_0_FF (unsigned long long*, *val >> 32, uint64_highword_mem) +make_funcs_0_FF (unsigned long long, val >> 32, uint64_highword_reg) + +make_funcs_0_FF (long long*, *val >> 16, int64_midword_mem) +make_funcs_0_FF (long long, val >> 16, int64_midword_reg) + +make_funcs_0_FF (unsigned long long*, *val >> 16, uint64_midword_mem) +make_funcs_0_FF (unsigned long long, val >> 16, uint64_midword_reg) + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49468-di.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49468-di.c new file mode 100644 index 0000000..4b17fce --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49468-di.c @@ -0,0 +1,23 @@ +/* Check that 64 bit integer abs is generated as negc instruction pairs + and conditional branch instead of default branch-free code. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "negc" 4 } } */ + + +/* Normal integer absolute value. */ +long long +abs_0 (long long i) +{ + return (i < 0) ? -i : i; +} + +/* Negated integer absolute value. + The generated code should be the same, except that the branch + condition is inverted. */ +long long +abs_1 (long long i) +{ + return (i > 0) ? -i : i; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49468-si.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49468-si.c new file mode 100644 index 0000000..8c771ed --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49468-si.c @@ -0,0 +1,23 @@ +/* Check that 32 bit integer abs is generated as neg instruction and + conditional branch instead of default branch-free code. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "neg" 2 } } */ + + +/* Normal integer absolute value. */ +int +abs_0 (int i) +{ + return (i < 0) ? -i : i; +} + +/* Negated integer absolute value. + The generated code should be the same, except that the branch + condition is inverted. */ +int +abs_1 (int i) +{ + return (i > 0) ? -i : i; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-1.c new file mode 100644 index 0000000..249fae0 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-1.c @@ -0,0 +1,22 @@ +/* Check that the option -mdiv=call-div1 works. */ +/* { dg-do link } */ +/* { dg-options "-mdiv=call-div1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ + +int +test00 (int a, int b) +{ + return a / b; +} + +unsigned int +test01 (unsigned int a, unsigned b) +{ + return a / b; +} + +int +main (int argc, char** argv) +{ + return test00 (argc, 123) + test01 (argc, 123); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-2.c new file mode 100644 index 0000000..35e23de --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-2.c @@ -0,0 +1,22 @@ +/* Check that the option -mdiv=call-fp works. */ +/* { dg-do link } */ +/* { dg-options "-mdiv=call-fp" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ + +int +test00 (int a, int b) +{ + return a / b; +} + +unsigned int +test01 (unsigned int a, unsigned b) +{ + return a / b; +} + +int +main (int argc, char** argv) +{ + return test00 (argc, 123) + test01 (argc, 123); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-3.c new file mode 100644 index 0000000..be6ea52 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-3.c @@ -0,0 +1,22 @@ +/* Check that the option -mdiv=call-table works. */ +/* { dg-do link } */ +/* { dg-options "-mdiv=call-table" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ + +int +test00 (int a, int b) +{ + return a / b; +} + +unsigned int +test01 (unsigned int a, unsigned b) +{ + return a / b; +} + +int +main (int argc, char** argv) +{ + return test00 (argc, 123) + test01 (argc, 123); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-4.c new file mode 100644 index 0000000..5b5af1e --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-4.c @@ -0,0 +1,19 @@ +/* Check that the option -mdiv=call-fp does not produce calls to the + library function that uses FPU to implement integer division if FPU insns + are not supported or are disabled. */ +/* { dg-do compile } */ +/* { dg-options "-mdiv=call-fp" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*"} { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" } } */ +/* { dg-final { scan-assembler-not "sdivsi3_i4\n|udivsi3_i4\n" } } */ + +int +test00 (int a, int b) +{ + return a / b; +} + +unsigned int +test01 (unsigned int a, unsigned b) +{ + return a / b; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-5.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-5.c new file mode 100644 index 0000000..bff9f33 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr49880-5.c @@ -0,0 +1,19 @@ +/* Check that the option -mdiv=call-fp results in the corresponding library + function calls on targets that have a double precision FPU. */ +/* { dg-do compile } */ +/* { dg-options "-mdiv=call-fp" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*"} { "-m2a" "-m4" "-m4a" "*single-only" } } */ +/* { dg-final { scan-assembler "sdivsi3_i4\n" } } */ +/* { dg-final { scan-assembler "udivsi3_i4\n" } } */ + +int +test00 (int a, int b) +{ + return a / b; +} + +unsigned int +test01 (unsigned int a, unsigned b) +{ + return a / b; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-1.c new file mode 100644 index 0000000..90db97a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-1.c @@ -0,0 +1,34 @@ +/* PR target/50749: Verify that post-increment addressing is generated. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "mov.b\t@r\[0-9]\+\\+,r\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "mov.w\t@r\[0-9]\+\\+,r\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "mov.l\t@r\[0-9]\+\\+,r\[0-9]\+" 1 } } */ + +char* +test_func_00 (char* p, int* x) +{ + int r = 0; + r += *p++; + *x = r; + return p; +} + +short* +test_func_01 (short* p, int* x) +{ + int r = 0; + r += *p++; + *x = r; + return p; +} + +int* +test_func_02 (int* p, int* x) +{ + int r = 0; + r += *p++; + *x = r; + return p; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-2.c new file mode 100644 index 0000000..b695db1 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-2.c @@ -0,0 +1,70 @@ +/* PR target/50749: Verify that subsequent post-increment addressings + are generated. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "mov.b\t@r\[0-9]\+\\+,r\[0-9]\+" 5 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-times "mov.w\t@r\[0-9]\+\\+,r\[0-9]\+" 5 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-times "mov.l\t@r\[0-9]\+\\+,r\[0-9]\+" 5 { xfail *-*-*} } } */ + +char* +test_func_00 (char* p, int* x) +{ + int r = 0; + r += *p++; + r += *p++; + *x = r; + return p; +} + +char* +test_func_01 (char* p, int* x) +{ + int r = 0; + r += *p++; + r += *p++; + r += *p++; + *x = r; + return p; +} + +short* +test_func_02 (short* p, int* x) +{ + int r = 0; + r += *p++; + r += *p++; + *x = r; + return p; +} + +short* +test_func_03 (short* p, int* x) +{ + int r = 0; + r += *p++; + r += *p++; + r += *p++; + *x = r; + return p; +} + +int* +test_func_04 (int* p, int* x) +{ + int r = 0; + r += *p++; + r += *p++; + *x = r; + return p; +} + +int* +test_func_05 (int* p, int* x) +{ + int r = 0; + r += *p++; + r += *p++; + r += *p++; + *x = r; + return p; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-3.c new file mode 100644 index 0000000..6e54d4d --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-3.c @@ -0,0 +1,40 @@ +/* PR target/50749: Verify that post-increment addressing is generated + inside a loop. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "mov.b\t@r\[0-9]\+\\+,r\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "mov.w\t@r\[0-9]\+\\+,r\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "mov.l\t@r\[0-9]\+\\+,r\[0-9]\+" 1 } } */ + +int +test_func_00 (char* p, int c) +{ + int r = 0; + do + { + r += *p++; + } while (--c); + return r; +} + +int +test_func_01 (short* p, int c) +{ + int r = 0; + do + { + r += *p++; + } while (--c); + return r; +} + +int +test_func_02 (int* p, int c) +{ + int r = 0; + do + { + r += *p++; + } while (--c); + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-4.c new file mode 100644 index 0000000..fc6fa8d --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-postinc-4.c @@ -0,0 +1,46 @@ +/* PR target/50749: Verify that post-increment addressing is generated + inside a loop. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "mov.b\t@r\[0-9]\+\\+,r\[0-9]\+" 3 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-times "mov.w\t@r\[0-9]\+\\+,r\[0-9]\+" 3 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-times "mov.l\t@r\[0-9]\+\\+,r\[0-9]\+" 3 { xfail *-*-*} } } */ + +int +test_func_00 (char* p, int c) +{ + int r = 0; + do + { + r += *p++; + r += *p++; + r += *p++; + } while (--c); + return r; +} + +int +test_func_01 (short* p, int c) +{ + int r = 0; + do + { + r += *p++; + r += *p++; + r += *p++; + } while (--c); + return r; +} + +int +test_func_02 (int* p, int c) +{ + int r = 0; + do + { + r += *p++; + r += *p++; + r += *p++; + } while (--c); + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-1.c new file mode 100644 index 0000000..4f45574 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-1.c @@ -0,0 +1,28 @@ +/* PR target/50749: Verify that pre-decrement addressing is generated. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "mov.b\tr\[0-9]\+,@-r\[0-9]\+" 1 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-times "mov.w\tr\[0-9]\+,@-r\[0-9]\+" 1 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-times "mov.l\tr\[0-9]\+,@-r\[0-9]\+" 1 { xfail *-*-*} } } */ + +char* +test_func_00 (char* p, int c) +{ + *--p = (char)c; + return p; +} + +short* +test_func_01 (short* p, int c) +{ + *--p = (short)c; + return p; +} + +int* +test_func_02 (int* p, int c) +{ + *--p = c; + return p; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-2.c new file mode 100644 index 0000000..beda957 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-2.c @@ -0,0 +1,58 @@ +/* PR target/50749: Verify that subsequent pre-decrement addressings + are generated. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "mov.b\tr\[0-9]\+,@-r\[0-9]\+" 5 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-times "mov.w\tr\[0-9]\+,@-r\[0-9]\+" 5 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-times "mov.l\tr\[0-9]\+,@-r\[0-9]\+" 5 { xfail *-*-*} } } */ + +char* +test_func_00 (char* p, int c) +{ + *--p = (char)c; + *--p = (char)c; + return p; +} + +char* +test_func_01 (char* p, int c) +{ + *--p = (char)c; + *--p = (char)c; + *--p = (char)c; + return p; +} + +short* +test_func_02 (short* p, int c) +{ + *--p = (short)c; + *--p = (short)c; + return p; +} + +short* +test_func_03 (short* p, int c) +{ + *--p = (short)c; + *--p = (short)c; + *--p = (short)c; + return p; +} + +int* +test_func_04 (int* p, int c) +{ + *--p = c; + *--p = c; + return p; +} + +int* +test_func_05 (int* p, int c) +{ + *--p = c; + *--p = c; + *--p = c; + return p; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-3.c new file mode 100644 index 0000000..5417497 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-3.c @@ -0,0 +1,37 @@ +/* PR target/50749: Verify that pre-decrement addressing is generated + inside a loop. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "mov.b\tr\[0-9]\+,@-r\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "mov.w\tr\[0-9]\+,@-r\[0-9]\+" 1 } } */ +/* { dg-final { scan-assembler-times "mov.l\tr\[0-9]\+,@-r\[0-9]\+" 1 } } */ + +char* +test_func_00 (char* p, int c, int x) +{ + do + { + *--p = (char)x; + } while (--c); + return p; +} + +short* +test_func_01 (short* p, int c, int x) +{ + do + { + *--p = (short)x; + } while (--c); + return p; +} + +int* +test_func_02 (int* p, int c, int x) +{ + do + { + *--p = x; + } while (--c); + return p; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-4.c new file mode 100644 index 0000000..e8c0348 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-qihisi-predec-4.c @@ -0,0 +1,43 @@ +/* PR target/50749: Verify that pre-decrement addressing is generated + inside a loop. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "mov.b\tr\[0-9]\+,@-r\[0-9]\+" 3 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-times "mov.w\tr\[0-9]\+,@-r\[0-9]\+" 3 { xfail *-*-*} } } */ +/* { dg-final { scan-assembler-times "mov.l\tr\[0-9]\+,@-r\[0-9]\+" 3 { xfail *-*-*} } } */ + +char* +test_func_00 (char* p, int c, int x) +{ + do + { + *--p = (char)x; + *--p = (char)x; + *--p = (char)x; + } while (--c); + return p; +} + +short* +test_func_01 (short* p, int c, int x) +{ + do + { + *--p = (short)x; + *--p = (short)x; + *--p = (short)x; + } while (--c); + return p; +} + +int* +test_func_02 (int* p, int c, int x) +{ + do + { + *--p = x; + *--p = x; + *--p = x; + } while (--c); + return p; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-1.c new file mode 100644 index 0000000..41e3bdd --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-1.c @@ -0,0 +1,15 @@ +/* PR target/50749: Verify that post-increment addressing is generated. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmov.s\t@r\[0-9]\+\\+,fr\[0-9]\+" 1 } } */ + +float* +test_func_00 (float* p, float* x) +{ + float r = 0; + r += *p++; + *x = r; + return p; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-2.c new file mode 100644 index 0000000..304ed11 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-2.c @@ -0,0 +1,27 @@ +/* PR target/50749: Verify that subsequent post-increment addressings + are generated. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmov.s\t@r\[0-9]\+\\+,fr\[0-9]\+" 5 { xfail *-*-*} } } */ + +float* +test_func_00 (float* p, float* x) +{ + float r = 0; + r += *p++; + r += *p++; + *x = r; + return p; +} + +float* +test_func_01 (float* p, float* x) +{ + float r = 0; + r += *p++; + r += *p++; + r += *p++; + *x = r; + return p; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-3.c new file mode 100644 index 0000000..7461bed --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-3.c @@ -0,0 +1,17 @@ +/* PR target/50749: Verify that post-increment addressing is generated + inside a loop. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmov.s\t@r\[0-9]\+\\+,fr\[0-9]\+" 1 } } */ + +float +test_func_00 (float* p, int c) +{ + float r = 0; + do + { + r += *p++; + } while (--c); + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-4.c new file mode 100644 index 0000000..b6dce42 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-postinc-4.c @@ -0,0 +1,19 @@ +/* PR target/50749: Verify that post-increment addressing is generated + inside a loop. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmov.s\t@r\[0-9]\+\\+,fr\[0-9]\+" 3 { xfail *-*-*} } } */ + +float +test_func_00 (float* p, int c) +{ + float r = 0; + do + { + r += *p++; + r += *p++; + r += *p++; + } while (--c); + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-1.c new file mode 100644 index 0000000..d51aa9e --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-1.c @@ -0,0 +1,13 @@ +/* PR target/50749: Verify that pre-decrement addressing is generated. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmov.s\tfr\[0-9]\+,@-r\[0-9]\+" 1 } } */ + +float* +test_func_00 (float* p, float c) +{ + *--p = c; + return p; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-2.c new file mode 100644 index 0000000..cd87ce9 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-2.c @@ -0,0 +1,23 @@ +/* PR target/50749: Verify that subsequent pre-decrement addressings + are generated. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmov.s\tfr\[0-9]\+,@-r\[0-9]\+" 5 { xfail *-*-*} } } */ + +float* +test_func_00 (float* p, float c) +{ + *--p = c; + *--p = c; + return p; +} + +float* +test_func_01 (float* p, float c) +{ + *--p = c; + *--p = c; + *--p = c; + return p; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-3.c new file mode 100644 index 0000000..a772b23 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-3.c @@ -0,0 +1,16 @@ +/* PR target/50749: Verify that pre-decrement addressing is generated + inside a loop. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmov.s\tfr\[0-9]\+,@-r\[0-9]\+" 1 } } */ + +float* +test_func_00 (float* p, int c, float x) +{ + do + { + *--p = x; + } while (--c); + return p; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-4.c new file mode 100644 index 0000000..9d08038 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50749-sf-predec-4.c @@ -0,0 +1,18 @@ +/* PR target/50749: Verify that pre-decrement addressing is generated + inside a loop. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmov.s\tfr\[0-9]\+,@-r\[0-9]\+" 3 { xfail *-*-*} } } */ + +float* +test_func_00 (float* p, int c, float x) +{ + do + { + *--p = x; + *--p = x; + *--p = x; + } while (--c); + return p; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-1.c new file mode 100644 index 0000000..80c63fb --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-1.c @@ -0,0 +1,30 @@ +/* Check that the mov.b displacement addressing insn is generated. + If the insn is generated as expected, there should be no address + calculations outside the mov insns. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-not "add|sub" } } */ + +void +testfunc_00 (const char* ap, char* bp, char val) +{ + bp[0] = ap[15]; + bp[2] = ap[5]; + bp[9] = ap[7]; + bp[0] = ap[15]; + bp[4] = val; + bp[14] = val; +} + +void +testfunc_01 (volatile const char* ap, volatile char* bp, char val) +{ + bp[0] = ap[15]; + bp[2] = ap[5]; + bp[9] = ap[7]; + bp[0] = ap[15]; + bp[4] = val; + bp[14] = val; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-2.c new file mode 100644 index 0000000..cd71642 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-2.c @@ -0,0 +1,27 @@ +/* Check that the mov.b displacement addressing insn is generated and the + base address is adjusted only once. On SH2A this test is skipped because + there is a 4 byte mov.b insn that can handle larger displacements. Thus + on SH2A the base address will not be adjusted in this case. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" "-m2a*" } { "" } } */ +/* { dg-final { scan-assembler-times "add" 2 } } */ + +void +testfunc_00 (const char* ap, char* bp) +{ + bp[0] = ap[15]; + bp[2] = ap[5]; + bp[9] = ap[7]; + bp[0] = ap[25]; +} + +void +testfunc_01 (volatile const char* ap, volatile char* bp) +{ + bp[0] = ap[15]; + bp[2] = ap[5]; + bp[9] = ap[7]; + bp[0] = ap[25]; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-3.c new file mode 100644 index 0000000..5b8d351 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-3.c @@ -0,0 +1,26 @@ +/* Check that on SH2A the 4 byte mov.b displacement insn is generated to + handle larger displacements. If it is generated correctly, there should + be no base address adjustments outside the mov.b insns. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-not "add|sub" } } */ + +void +testfunc_00 (const char* ap, char* bp) +{ + bp[100] = ap[15]; + bp[200] = ap[50]; + bp[900] = ap[71]; + bp[0] = ap[25]; +} + +void +testfunc_01 (volatile const char* ap, volatile char* bp) +{ + bp[100] = ap[15]; + bp[200] = ap[50]; + bp[900] = ap[71]; + bp[0] = ap[25]; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-4.c new file mode 100644 index 0000000..e0f3ab7 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-4.c @@ -0,0 +1,30 @@ +/* Check that the mov.w displacement addressing insn is generated. + If the insn is generated as expected, there should be no address + calculations outside the mov insns. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-not "add|sub" } } */ + +void +testfunc_00 (const short* ap, short* bp, short val) +{ + bp[0] = ap[15]; + bp[2] = ap[5]; + bp[9] = ap[7]; + bp[0] = ap[15]; + bp[4] = val; + bp[14] = val; +} + +void +testfunc_01 (volatile const short* ap, volatile short* bp, short val) +{ + bp[0] = ap[15]; + bp[2] = ap[5]; + bp[9] = ap[7]; + bp[0] = ap[15]; + bp[4] = val; + bp[14] = val; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-5.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-5.c new file mode 100644 index 0000000..5da9ac2 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-5.c @@ -0,0 +1,27 @@ +/* Check that the mov.w displacement addressing insn is generated and the + base address is adjusted only once. On SH2A this test is skipped because + there is a 4 byte mov.w insn that can handle larger displacements. Thus + on SH2A the base address will not be adjusted in this case. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" "-m2a*" } { "" } } */ +/* { dg-final { scan-assembler-times "add" 2 } } */ + +void +testfunc_00 (const short* ap, short* bp) +{ + bp[0] = ap[15]; + bp[2] = ap[5]; + bp[9] = ap[7]; + bp[0] = ap[25]; +} + +void +testfunc_01 (volatile const short* ap, volatile short* bp) +{ + bp[0] = ap[15]; + bp[2] = ap[5]; + bp[9] = ap[7]; + bp[0] = ap[25]; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-6.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-6.c new file mode 100644 index 0000000..1297290 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-6.c @@ -0,0 +1,26 @@ +/* Check that on SH2A the 4 byte mov.w displacement insn is generated to + handle larger displacements. If it is generated correctly, there should + be no base address adjustments outside the mov.w insns. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-not "add|sub" } } */ + +void +testfunc_00 (const short* ap, short* bp) +{ + bp[100] = ap[15]; + bp[200] = ap[50]; + bp[900] = ap[71]; + bp[0] = ap[25]; +} + +void +testfunc_01 (volatile const short* ap, volatile short* bp) +{ + bp[100] = ap[15]; + bp[200] = ap[50]; + bp[900] = ap[71]; + bp[0] = ap[25]; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-7.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-7.c new file mode 100644 index 0000000..014575a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-7.c @@ -0,0 +1,35 @@ +/* Check that mov.b and mov.w displacement insns are generated. + If this is working properly, there should be no base address adjustments + outside the mov insns. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-not "add|sub" } } */ + +typedef struct +{ + char a; + char b; + char c; + char d; + + short e; + short f; + + int g; + int h; +} X; + +void +testfunc_00 (X* x) +{ + x->g = x->b | x->c; + x->h = x->e | x->f; + x->d = x->g; + x->f = x->h; +} + +int testfunc_01 (X* x) +{ + return x->b | x->e | x->g; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-8.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-8.c new file mode 100644 index 0000000..d9eda44 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr50751-8.c @@ -0,0 +1,100 @@ +/* Check that on SH2A the 4 byte movu.b and movu.w displacement insns are + generated. This has to be checked with -O2 because some of the patterns + rely on peepholes. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-times "movu.b" 4 } } */ +/* { dg-final { scan-assembler-times "movu.w" 3 } } */ + +int +test_00 (unsigned char* x) +{ + /* 1x movu.b */ + return x[0]; +} + +int +test_01 (unsigned short* x) +{ + /* 1x movu.w */ + return x[0]; +} + +int +test_02 (unsigned char* x) +{ + /* 1x movu.b */ + return x[1]; +} + +int +test_03 (unsigned char* x) +{ + /* 1x movu.b */ + return x[32]; +} + +int +test_04 (unsigned char* x) +{ + /* 1x movu.b */ + return x[9000]; +} + +int +test_05 (unsigned short* x) +{ + /* 1x movu.w */ + return x[9000]; +} + +int +test_06 (unsigned char* x, int i) +{ + /* No movu.b expected here. Should use mov.b (r0,r4) + extu.b instead. */ + return x[i]; +} + +int +test_07 (unsigned short* x, int i) +{ + /* No movu.w expected here. Should use mov.w (r0,r4) + extu.w instead. */ + return x[i]; +} + +int +test_08 (unsigned char* x, int c) +{ + /* No movu.b expected here. Should use post-inc addressing instead. */ + int s = 0; + int i; + for (i = 0; i < c; ++i) + s += x[i]; + return s; +} + +void +test_09 (unsigned char* x, unsigned char* y) +{ + /* No movu.b expected here, since the zero-extension is irrelevant. */ + x[1] = y[1]; + x[2] = y[2]; +} + +void +test_10 (unsigned char* x, unsigned short* y) +{ + /* No movu.w expected here, since the zero-extension is irrelevant. */ + x[1] = y[1]; + x[2] = y[2]; +} + +int +test_11 (unsigned char* x, unsigned short* y) +{ + /* 1x movu.w */ + int yy = y[1]; + x[1] = yy; + return yy; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-1.c new file mode 100644 index 0000000..15e2ebd --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-1.c @@ -0,0 +1,32 @@ +/* Check that inverted conditional branch logic does not generate + unnecessary explicit T bit extractions, inversions and + test instructions. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -mbranch-cost=2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-not "movt|tst|negc|extu" } } */ + +int +testfunc_00 (int a, int b, int c, int d) +{ + return (a != b || a != d) ? b : c; +} + +int +testfunc_01 (int a, int b, int c, int d) +{ + return (a == b || a == d) ? b : c; +} + +int +testfunc_02 (int a, int b, int c, int d) +{ + return (a == b && a == d) ? b : c; +} + +int +testfunc_03 (int a, int b, int c, int d) +{ + return (a != b && a != d) ? b : c; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-10.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-10.c new file mode 100644 index 0000000..ef16b75 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-10.c @@ -0,0 +1,27 @@ +/* Check that compare-branch is inverted properly. + In this case the improved bit test is a side effect of compare-branch + inversion patterns, even though the branch condition does not get + inverted here. + Example: + mov.b @(14,r9),r0 -> mov.b @(14,r9),r0 + shll r0 cmp/pz r0 + subc r0,r0 bt .L192 + and #1,r0 + tst r0,r0 + bt .L195 +*/ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "shll|subc|and" } } */ +int +test_00 (int* p) +{ + int nr = 15; + volatile char* addr = (volatile char*)&p[1]; + + if ((addr[(nr >> 3) ^ 7] & (1 << (nr & 7))) == 0) + return 40; + else + return 50; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-11.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-11.c new file mode 100644 index 0000000..b673e9a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-11.c @@ -0,0 +1,24 @@ +/* Check that zero-displacement branches are used instead of branch-free + execution patterns. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -mzdcbranch" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "subc|and" } } */ + +int* +test_00 (int* s) +{ + if (s[0] == 0) + if (!s[3]) + s = 0; + return s; +} + +int* +test_01 (int* s) +{ + if (s[0] == 0) + if (s[3]) + s = 0; + return s; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-12.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-12.c new file mode 100644 index 0000000..da94101 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-12.c @@ -0,0 +1,68 @@ +/* Check that the negc instruction is generated as expected for the cases + below. If we see a movrt or #-1 negc sequence it means that the pattern + which handles the inverted case does not work properly. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "negc" 10 } } */ +/* { dg-final { scan-assembler-not "movrt|#-1|add|sub" } } */ + +int +test00 (int a, int b, int* x) +{ + return (a == b) ? 0x7FFFFFFF : 0x80000000; +} + +int +test00_inv (int a, int b) +{ + return (a != b) ? 0x80000000 : 0x7FFFFFFF; +} + +int +test01 (int a, int b) +{ + return (a >= b) ? 0x7FFFFFFF : 0x80000000; +} + +int +test01_inv (int a, int b) +{ + return (a < b) ? 0x80000000 : 0x7FFFFFFF; +} + +int +test02 (int a, int b) +{ + return (a > b) ? 0x7FFFFFFF : 0x80000000; +} + +int +test02_inv (int a, int b) +{ + return (a <= b) ? 0x80000000 : 0x7FFFFFFF; +} + +int +test03 (int a, int b) +{ + return ((a & b) == 0) ? 0x7FFFFFFF : 0x80000000; +} + +int +test03_inv (int a, int b) +{ + return ((a & b) != 0) ? 0x80000000 : 0x7FFFFFFF; +} + +int +test04 (int a) +{ + return ((a & 0x55) == 0) ? 0x7FFFFFFF : 0x80000000; +} + +int +test04_inv (int a) +{ + return ((a & 0x55) != 0) ? 0x80000000 : 0x7FFFFFFF; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-13.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-13.c new file mode 100644 index 0000000..41d23eb --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-13.c @@ -0,0 +1,85 @@ +/* This is a case extracted from CSiBE which contained the following + sequence: + shll r0 + movt r0 + tst r0,r0 + bf .L11 + where the 'tst r0,r0' before the branch can be omitted by inverting the + branch condition. The tested function contains two other tst insns. If + everything goes as expected we will be seeing only those other two tst + insns. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "tst" 2 } } */ + +static __inline__ int +__test_bit (unsigned long nr, volatile void * addr) +{ + /* This is on purpose. */ + int oldbit; + return oldbit & 1; +} + +static __inline__ int +__constant_test_bit (unsigned long nr, volatile void * addr) +{ + return (((volatile char *) addr)[(nr>>3)^7] & (1<<(nr&7))) != 0; +} + +struct list_head +{ + struct list_head *next, *prev; +}; + +static inline void +__list_del (struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +static inline void +list_del (struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = 0; + entry->prev = 0; +} + +extern int nr_active_pages; +extern int nr_inactive_pages; +extern struct list_head active_list; + +typedef struct page +{ + unsigned long flags; + struct list_head lru; +} mem_map_t; + +void +activate_page_nolock (struct page * page) +{ + if ((__builtin_constant_p((6)) + ? __constant_test_bit((6),(&(page)->flags)) + : __test_bit((6),(&(page)->flags)) ) + && !(__builtin_constant_p((7)) + ? __constant_test_bit((7),(&(page)->flags)) + : __test_bit((7),(&(page)->flags)) )) + { + list_del(&(page)->lru); + nr_inactive_pages--; + if (!(__builtin_constant_p(6) ? __constant_test_bit((6),(&(page)->flags)) + : __test_bit((6),(&(page)->flags)))) + printk("", "", 43); + + if ((__builtin_constant_p(7) ? __constant_test_bit((7),(&(page)->flags)) + : __test_bit((7),(&(page)->flags)))) + printk("", "", 43); + + (__builtin_constant_p(7) ? __constant_set_bit((7),(&(page)->flags)) + : __set_bit((7),(&(page)->flags)) ); + list_add(&(page)->lru, &active_list); + nr_active_pages++; + } +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-14.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-14.c new file mode 100644 index 0000000..844eb3a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-14.c @@ -0,0 +1,107 @@ +/* This is a case extracted from CSiBE which would sometimes contain the + following sequence: + cmp/eq r12,r13 + movt r0 + xor #1,r0 + extu.b r0,r0 + movt r3 + tst r0,r0 + bf/s .L35 + where the negated T bit store did not combine properly. Since there are + other movt insns we only check for the xor and the extu. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "xor|extu" } } */ + +typedef struct transaction_s transaction_t; + +struct journal_head +{ + transaction_t * b_transaction; + struct journal_head *b_cpnext, *b_cpprev; +}; + +struct transaction_s +{ + struct journal_head * t_checkpoint_list; + transaction_t *t_cpnext, *t_cpprev; +}; + +struct journal_s +{ + transaction_t * j_checkpoint_transactions; + unsigned long j_first, j_last; +}; + +typedef struct journal_s journal_t; + +extern int __try_to_free_cp_buf (struct journal_head *jh); +extern int __cleanup_transaction (journal_t *journal, transaction_t *transaction); +extern void __flush_batch (void **bhs, int *batch_count); +extern void* jh2bh (void*); + +static int +__flush_buffer (journal_t *journal, struct journal_head *jh, + void **bhs, int *batch_count, int *drop_count) +{ + void *bh = jh2bh (jh); + int ret = 0; + if (bh) + { + bhs[*batch_count] = bh; + (*batch_count)++; + if (*batch_count == 64) + ret = 1; + } + else + { + int last_buffer = 0; + if (jh->b_cpnext == jh) + last_buffer = 1; + if (__try_to_free_cp_buf (jh)) + { + (*drop_count)++; + ret = last_buffer; + } + } + return ret; +} + +int +log_do_checkpoint (journal_t *journal, int nblocks) +{ + transaction_t *transaction, *last_transaction, *next_transaction; + int batch_count = 0; + void *bhs[64]; + +repeat: + transaction = journal->j_checkpoint_transactions; + if (transaction == ((void *)0)) + return 0; + last_transaction = transaction->t_cpprev; + next_transaction = transaction; + do + { + struct journal_head *jh, *last_jh, *next_jh; + int drop_count = 0; + int cleanup_ret, retry = 0; + transaction = next_transaction; + next_transaction = transaction->t_cpnext; + jh = transaction->t_checkpoint_list; + last_jh = jh->b_cpprev; + next_jh = jh; + do + { + jh = next_jh; + next_jh = jh->b_cpnext; + retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count); + } while (jh != last_jh && !retry); + + if (retry) + goto repeat; + + cleanup_ret = __cleanup_transaction(journal, transaction); + goto repeat; + } while (transaction != last_transaction); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-15.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-15.c new file mode 100644 index 0000000..e99963f --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-15.c @@ -0,0 +1,71 @@ +/* Check that the redundant test removal code in the *cbranch_t split works + as expected on non-SH2A targets. Because on SH2A the movrt instruction + is used, this test is re-used and checked differently in pr51244-16.c. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" "-m2a*" } { "" } } */ +/* { dg-final { scan-assembler-times "tst" 6 } } */ +/* { dg-final { scan-assembler-times "movt" 6 } } */ +/* { dg-final { scan-assembler-times "xor" 3 } } */ +/* { dg-final { scan-assembler-not "extu|exts|negc" } } */ + +typedef char bool; + +int +test_0 (int a, int b, int c, int* d) +{ + /* non SH2A: 1x tst, 1x movt, 1x xor + SH2A: 1x tst, 1x movrt */ + bool x = a == 0; + d[2] = !x; + return x ? b : c; +} + +int +test_1 (int a, int b, int c, int* d) +{ + /* 1x tst, 1x movt */ + bool x = a != 0; + d[2] = !x; + return x ? b : c; +} + +int +test_2 (int a, int b, int c, char* d) +{ + /* Check that there is no sign/zero-extension before the store. + non SH2A: 1x tst, 1x movt, 1x xor + SH2A: 1x tst, 1x movrt */ + bool x = a == 0; + d[2] = !x; + return x ? b : c; +} + +int +test_3 (int a, int b, int c, char* d) +{ + /* Check that there is no sign/zero-extension before the store. + 1x tst, 1x movt */ + bool x = a != 0; + d[2] = !x; + return x ? b : c; +} + +int +test_4 (int a, int b, int c, char* d) +{ + /* 1x tst, 1x movt */ + bool x = a != 0; + d[2] = !x; + return !x ? b : c; +} + +int +test_5 (int a, int b, int c, char* d) +{ + /* non SH2A: 1x tst, 1x movt, 1x xor + SH2A: 1x tst, 1x movrt */ + bool x = a == 0; + d[2] = !x; + return !x ? b : c; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-16.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-16.c new file mode 100644 index 0000000..5132f74 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-16.c @@ -0,0 +1,11 @@ +/* Check that the redundant test removal code in the *cbranch_t split works + as expected on SH2A targets. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-times "tst" 6 } } */ +/* { dg-final { scan-assembler-times "movt" 3 } } */ +/* { dg-final { scan-assembler-times "movrt" 3 } } */ +/* { dg-final { scan-assembler-not "extu|exts|negc" } } */ + +#include "pr51244-15.c" diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-17.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-17.c new file mode 100644 index 0000000..621abb7 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-17.c @@ -0,0 +1,297 @@ +/* Check that no unnecessary zero extensions are done on values that are + results of arithmetic with T bit inputs. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "extu|exts" } } */ + +int +test00 (int a, int b, int c, int d) +{ + int x = a == b; + int y = c == 0; + return x == y; +} + +int +test01 (int a, int b, int c, int d) +{ + int x = a == b; + int y = c == d; + return x == y; +} + +int +test02 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c == d; + return x == y; +} + +int +test03 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c != d; + return x == y; +} + +int +test04 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c != d; + return x == y; +} + +int +test05 (int a, int b, int c, int d) +{ + int x = a == b; + int y = c == 0; + return x != y; +} + +int +test06 (int a, int b, int c, int d) +{ + int x = a == b; + int y = c == 0; + return x ^ y; +} + +int +test07 (int a, int b, int c, int d) +{ + int x = a == b; + int y = c == 0; + return x | y; +} + +int +test08 (int a, int b, int c, int d) +{ + int x = a == b; + int y = c == 0; + return x & y; +} + +int +test09 (int a, int b, int c, int d) +{ + int x = a == b; + int y = c == d; + return x != y; +} + +int +test10 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c == d; + return x != y; +} + +int +test11 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c != d; + return x != y; +} + +int +test12 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c != d; + return x != y; +} + +int +test13 (int a, int b, int c, int d, int e, int f) +{ + int x = a == b; + int y = c == 0; + int z = d == e; + return x == y || x == z; +} + +int +test14 (int a, int b, int c, int d, int e, int f) +{ + int x = a == b; + int y = c == 0; + int z = d == e; + return x == y && x == z; +} + +int +test15 (int a, int b, int c, int d, int e, int f) +{ + int x = a != b; + int y = c == 0; + int z = d == e; + return x == y || x == z; +} + +int +test16 (int a, int b, int c, int d, int e, int f) +{ + int x = a != b; + int y = c == 0; + int z = d == e; + return x == y && x == z; +} + +int +test17 (int a, int b, int c, int d, int e, int f) +{ + int x = a != b; + int y = c != 0; + int z = d == e; + return x == y || x == z; +} + +int +test18 (int a, int b, int c, int d, int e, int f) +{ + int x = a != b; + int y = c != 0; + int z = d == e; + return x == y && x == z; +} + +int +test19 (int a, int b, int c, int d, int e, int f) +{ + int x = a != b; + int y = c != 0; + int z = d == e; + return x == y || x == z; +} + +int +test20 (int a, int b, int c, int d, int e, int f) +{ + int x = a != b; + int y = c != 0; + int z = d != e; + return x == y && x == z; +} + +int +test21 (int a, int b, int c, int d) +{ + int x = a == b; + int y = c == 0; + return x + y; +} + +int +test22 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c == 0; + return x + y; +} + +int +test23 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c != 0; + return x + y; +} + +int +test24 (int a, int b, int c, int d) +{ + int x = a == b; + int y = c == 0; + return x - y; +} + +int +test25 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c == 0; + return x - y; +} + +int +test26 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c != 0; + return x - y; +} + +int +test27 (int a, int b, int c, int d) +{ + int x = a == b; + int y = c == 0; + return x * y; +} + +int +test28 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c == 0; + return x * y; +} + +int +test29 (int a, int b, int c, int d) +{ + int x = a != b; + int y = c != 0; + return x * y; +} + +int +test30 (int a, int b) +{ + return ((a & 0x7F) == 1) + | ((a & 0xFF00) == 0x0200) + | ((a & 0xFF0000) == 0x030000); +} + +int +test31 (int a, int b) +{ + return ((a & 0x7F) == 1) + | ((a & 0xFF00) == 0x0200) + | ((a & 0xFF0000) == 0x030000) + | ((a & 0xFF000000) == 0x04000000); +} + +int +test32 (int* a, int b, int c, volatile char* d) +{ + d[1] = a[0] != 0; + return b; +} + +int +test33 (int* a, int b, int c, volatile char* d) +{ + d[1] = a[0] == 0; + return b; +} + +char +test34 (int a, int* b) +{ + return (b[4] & b[0] & a) == a; +} + +unsigned char +test35 (int a, int* b) +{ + return (b[4] & b[0] & a) == a; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-18.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-18.c new file mode 100644 index 0000000..19b244c --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-18.c @@ -0,0 +1,102 @@ +/* Check that no unnecessary T bit stores are done before conditional + branches. + This case was extracted from the CSiBE set and contained the following + sequence: + cmp/hi r1,r0 + movt r1 + tst r1,r1 + bt .L12 + mov.l @r10,r1 + In this reduced code the movt and tst insns were only present in the + unwanted sequence. Thus, if we see any tst or movt insns, something is + not working as expected. This test requires -O2 because the T bit stores + in question will be eliminated in additional insn split passes after + reload. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "movt|tst" } } */ + +typedef char Char; +typedef unsigned char Bool; +typedef unsigned char UChar; +typedef int Int32; +typedef unsigned int UInt32; +typedef short Int16; +typedef unsigned short UInt16; + +static inline Bool +mainGtU (UInt32 i1, UInt32 i2, UChar* block, UInt16* quadrant, UInt32 nblock, + Int32* budget) +{ + Int32 k; + UChar c1, c2; + UInt16 s1, s2; + k = nblock + 8; + do + { + c1 = block[i1]; + c2 = block[i2]; + if (c1 != c2) + return (c1 > c2); + s1 = quadrant[i1]; + s2 = quadrant[i2]; + if (s1 != s2) + return (s1 > s2); + + i1++; i2++; + k -= 8; + } while (k >= 0); + + return 0; +} + +static inline void +mainSimpleSort (UInt32* ptr, UChar* block, UInt16* quadrant, Int32 nblock, + Int32 lo, Int32 hi, Int32 d, Int32* budget) +{ + Int32 i, j, h, bigN, hp; + UInt32 v; + bigN = hi - lo + 1; + hp = 0; + h = 1; + j = lo + h; + v = ptr[j]; + + while (mainGtU (ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) + { + ptr[j] = ptr[j-h]; + j = j - h; + } +} + +static inline void +mainQSort3 (UInt32* ptr, UChar* block, UInt16* quadrant, Int32 nblock, + Int32 loSt, Int32 hiSt, Int32 dSt, Int32* budget) +{ + Int32 unLo, unHi, ltLo, gtHi; + Int32 sp, lo, hi, d; + + Int32 stackLo[100]; + Int32 stackHi[100]; + Int32 stackD [100]; + + sp = 0; + stackLo[sp] = loSt; + stackHi[sp] = hiSt; + stackD [sp] = dSt; + lo = stackLo[sp]; + hi = stackHi[sp]; + d = stackD [sp]; + mainSimpleSort (ptr, block, quadrant, nblock, lo, hi, d, budget); +} + +void +mainSort (UInt32* ptr, UChar* block, UInt16* quadrant, UInt32* ftab, + Int32 nblock, Int32 verb, Int32* budget) +{ + Int32 sb = 0; + Int32 lo = ftab[sb] & (~((1 << 21))); + Int32 hi = (ftab[sb+1] & (~((1 << 21)))) - 1; + mainQSort3 (ptr, block, quadrant, nblock, lo, hi, 2, budget); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-19.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-19.c new file mode 100644 index 0000000..5845d93 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-19.c @@ -0,0 +1,75 @@ +/* Check that no unnecessary T bit stores are done before conditional + branches. + This case was extracted from the CSiBE set and contained the following + sequence: + mov.l @(8,r4),r2 + mov.l @(4,r4),r3 + cmp/gt r2,r3 + movt r2 +.L3: + tst r2,r2 + bt/s .L12 + mov #-1,r0 + + ..... + + mov.l @r4,r2 + tst r2,r2 + bra .L3 + movt r2 + + In this reduced code the movt insns were only present in the + unwanted sequences. Thus, if we see any movt insns, something is not + working as expected. This test requires -O2 because the T bit stores + in question will be eliminated in additional insn split passes after + reload. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "movt" } } */ + +struct request +{ + unsigned long nr_sectors; +}; + +struct request_list +{ + int count; +}; + +struct request_queue +{ + struct request_list rq; + volatile int nr_sectors; + int max_queue_sectors; + int can_throttle; + unsigned long bounce_pfn; +}; + +typedef struct request_queue request_queue_t; + +static inline int +blk_oversized_queue (request_queue_t* q) +{ + if (q->can_throttle) + return q->nr_sectors > q->max_queue_sectors; + return q->rq.count == 0; +} + +struct request* +get_request (request_queue_t* q, int rw) +{ + struct request* rq = ((void*)0); + struct request_list *rl = &q->rq; + + if (blk_oversized_queue (q)) + { + if ((rw == 1) || (rw == 0)) + return ((void*)0); + if (blk_oversized_queue (q)) + return ((void*)0); + } + + return (void*)-100; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-2.c new file mode 100644 index 0000000..a81ee7e --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-2.c @@ -0,0 +1,18 @@ +/* Check that when taking the complement of the T bit using the negc + instruction pattern, the constant -1 is loaded only once. + On SH2A this test is skipped because the movrt instruction is used + to get the complement of the T bit. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -mbranch-cost=2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" "-m2a*" } { "" } } */ +/* { dg-final { scan-assembler-times "mov\t#-1" 1 } } */ + +void +testfunc_00 (int* a, int* b, int c, int d) +{ + b[0] = a[0] != c; + b[1] = a[1] != d; + b[2] = a[2] != c; + b[3] = a[3] != d; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c new file mode 100644 index 0000000..f2cd2de --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c @@ -0,0 +1,14 @@ +/* Check that the SH specific sh_treg_combine RTL optimization pass works as + expected. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-times "tst" 5 } } */ +/* { dg-final { scan-assembler-times "movt" 0 } } */ +/* { dg-final { scan-assembler-times "nott" 1 } } */ +/* { dg-final { scan-assembler-times "cmp/eq" 2 } } */ +/* { dg-final { scan-assembler-times "cmp/hi" 4 } } */ +/* { dg-final { scan-assembler-times "cmp/gt" 3 } } */ +/* { dg-final { scan-assembler-times "not\t" 1 } } */ + +#include "pr51244-20.c" diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-20.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-20.c new file mode 100644 index 0000000..a9ded46 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-20.c @@ -0,0 +1,103 @@ +/* Check that the SH specific sh_treg_combine RTL optimization pass works as + expected. On SH2A the expected insns are slightly different, see + pr51244-21.c. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" "-m2a*" } { "" } } */ +/* { dg-final { scan-assembler-times "tst" 6 } } */ +/* { dg-final { scan-assembler-times "movt" 1 } } */ +/* { dg-final { scan-assembler-times "cmp/eq" 2 } } */ +/* { dg-final { scan-assembler-times "cmp/hi" 4 } } */ +/* { dg-final { scan-assembler-times "cmp/gt" 2 } } */ +/* { dg-final { scan-assembler-times "not\t" 1 } } */ + + +/* non-SH2A: 2x tst, 1x movt, 2x cmp/eq, 1x cmp/hi + SH2A: 1x tst, 1x nott, 2x cmp/eq, 1x cmp/hi */ +static inline int +blk_oversized_queue_0 (int* q) +{ + if (q[2]) + return q[1] == 5; + return (q[0] != 5); +} + +int __attribute__ ((noinline)) +get_request_0 (int* q, int rw) +{ + if (blk_oversized_queue_0 (q)) + { + if ((rw == 1) || (rw == 0)) + return -33; + return 0; + } + return -100; +} + + +/* 1x tst, 1x cmp/gt, 1x cmp/hi + On SH2A mem loads/stores have a wrong length of 4 bytes and thus will + not be placed in a delay slot. This introduces an extra cmp/gt insn. */ +static inline int +blk_oversized_queue_1 (int* q) +{ + if (q[2]) + return q[1] > 5; + return (q[0] > 5); +} + +int __attribute__ ((noinline)) +get_request_1 (int* q, int rw) +{ + if (blk_oversized_queue_1 (q)) + { + if ((rw == 1) || (rw == 0)) + return -33; + return 0; + } + return -100; +} + + +/* 1x tst, 1x cmp/gt, 1x cmp/hi, 1x cmp/hi */ +static inline int +blk_oversized_queue_2 (int* q) +{ + if (q[2]) + return q[1] > 5; + return (q[0] < 5); +} + +int __attribute__ ((noinline)) +get_request_2 (int* q, int rw) +{ + if (blk_oversized_queue_2 (q)) + { + if ((rw == 1) || (rw == 0)) + return -33; + return 0; + } + return -100; +} + + +/* 2x tst, 1x cmp/hi, 1x not */ +static inline int +blk_oversized_queue_5 (int* q) +{ + if (q[2]) + return q[1] != 0; + return q[0] == 0; +} + +int __attribute__ ((noinline)) +get_request_5 (int* q, int rw) +{ + if (blk_oversized_queue_5 (q)) + { + if ((rw == 1) || (rw == 0)) + return -33; + return 0; + } + return -100; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-3.c new file mode 100644 index 0000000..92963c4 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-3.c @@ -0,0 +1,16 @@ +/* Check that when taking the complement of the T bit on SH2A, + the movrt instruction is being generated. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -mbranch-cost=2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-times "movrt" 4 } } */ + +void +testfunc_00 (int* a, int* b, int c, int d) +{ + b[0] = a[0] != c; + b[1] = a[1] != d; + b[2] = a[2] != c; + b[3] = a[3] != d; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-4.c new file mode 100644 index 0000000..a11429b --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-4.c @@ -0,0 +1,19 @@ +/* Check that storing the (negated) T bit as all ones or zeros in a reg + uses the subc instruction. On SH2A a sequence with the movrt instruction + is also OK instead of subc. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -mbranch-cost=2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-not "movt|tst|negc" } } */ +/* { dg-final { scan-assembler "subc|movrt|neg|not" } } */ + +int test_00 (int x, int y) +{ + return x != y ? -1 : 0; +} + +int test_01 (int x, int y) +{ + return x == y ? -1 : 0; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-5.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-5.c new file mode 100644 index 0000000..c0f05a1 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-5.c @@ -0,0 +1,50 @@ +/* Check that no unnecessary sign or zero extension insn is generated after + a negc or movrt insn that stores the inverted T bit in a reg. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "extu|exts" } } */ + +int +test_00 (int a, int b, int* c, short* d, int x) +{ + *d = x != 0; + *c = -1; + + if (x != 0) + return a > 0; + + return 0; +} + +unsigned char +test_01 (int x) +{ + if (x < 58 && x > 47) + return 1; + return 0; +} + +char +test_02 (int x) +{ + if (x < 58 && x > 47) + return 1; + return 0; +} + +unsigned short +test_03 (int x) +{ + if (x < 58 && x > 47) + return 1; + return 0; +} + +short +test_04 (int x) +{ + if (x < 58 && x > 47) + return 1; + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-6.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-6.c new file mode 100644 index 0000000..3f9aafb --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-6.c @@ -0,0 +1,15 @@ +/* Check that no unnecessary sign or zero extension insn is generated after + a negc or movrt insn that stores the inverted T bit in a reg. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "extu|exts" } } */ + +float +test_00 (float q[4], float m[9]) +{ + float s0 = m[0] + m[1]; + float s1 = m[0] - m[1]; + + return q[s0 > s1 ? 0 : 1]; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-7.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-7.c new file mode 100644 index 0000000..d4d3974 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-7.c @@ -0,0 +1,26 @@ +/* Check that compare-branch is inverted properly. + Example: + clrt -> clrt + subc r0,r6 subc r0,r6 + mov r3,r7 mov r3,r7 + subc r1,r7 subc r1,r7 + mov #0,r1 tst r7,r7 + cmp/hi r1,r7 bf .L111 + bt .L111 bra .L197 + bra .L197 + nop +*/ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "cmp/hi" } } */ +/* { dg-final { scan-assembler-not "mov\t#0" } } */ + +int other_func (long long); +int +test_00 (unsigned long long a, unsigned long long b) +{ + if ((a - b) > 0xFFFFFFFFLL) + return other_func (a - b); + return 20; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-8.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-8.c new file mode 100644 index 0000000..d8c1269 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-8.c @@ -0,0 +1,27 @@ +/* Check that compare-branch is inverted properly. + Example: + mov #1,r0 -> tst r8,r8 + neg r8,r1 bt .L47 + shad r1,r0 + tst #1,r0 + bf .L47 +*/ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "shad|neg" } } */ + +int test_01_00 (int*, void*); +int +test_01 (int* m, void* v) +{ + unsigned long n = (unsigned long)v - 1; + + if (!n) + return 50; + + if (1 & (1 << n)) /* if n == 0: 1 & (1 << 0) -> true */ + return 60; + else /* if n != 0: 1 & (1 << n) -> false */ + return -8; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-9.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-9.c new file mode 100644 index 0000000..cca90a8 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51244-9.c @@ -0,0 +1,35 @@ +/* Check that compare-branch is inverted properly. + Example: + mov.w .L566,r2 -> mov.w .L566,r2 + add r11,r2 add r11,r2 + mov.l @(12,r2),r7 mov.l @(8,r2),r5 + mov.l @(8,r2),r5 mov.l @(12,r2),r2 + mov #0,r2 tst r2,r2 + cmp/hi r2,r7 bt .L534 + bf .L534 +*/ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "mov\t#0" } } */ +static inline unsigned int +test_03_00 (unsigned int x) +{ + /* Return unassigned value on purpose. */ + unsigned int res; + return res; +} + +struct S +{ + unsigned int a; + unsigned int b; +}; + +int test_03 (struct S* i) +{ + if ((i->a != 2 && i->a != 3) || i->a > test_03_00 (i->b)) + return -5; + + return -55; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51697.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51697.c new file mode 100644 index 0000000..d63e329 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr51697.c @@ -0,0 +1,21 @@ +/* Check that DImode comparisons are optimized as expected when compiling + with -Os. */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "tst" 2 } } */ +/* { dg-final { scan-assembler-not "cmp" } } */ + +int +test_00 (long long* x) +{ + /* 1x tst, no cmp/* insns. */ + return *x & 0xFFFFFFFF ? -20 : -40; +} + +int +test_01 (unsigned long long x) +{ + /* 1x tst, no cmp/* insns. */ + return x >= 0x100000000LL ? -20 : -40; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-1.c new file mode 100644 index 0000000..ca64a0a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-1.c @@ -0,0 +1,54 @@ +/* Check that loads/stores from/to volatile mems don't result in redundant + sign/zero extensions. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-not "exts|extu" } } */ + +int +test_00 (volatile char* x) +{ + return *x; +} + +void +test_100 (volatile char* x, char y) +{ + *x = y; +} + +int +test_01 (volatile short* x) +{ + return *x; +} + +void +test_101 (volatile unsigned char* x, unsigned char y) +{ + *x = y; +} + +int +test_02 (volatile unsigned char* x) +{ + return *x == 0x80; +} + +void +test_102 (volatile short* x, short y) +{ + *x = y; +} + +int +test_03 (volatile unsigned short* x) +{ + return *x == 0xFF80; +} + +void +test_103 (volatile unsigned short* x, unsigned short y) +{ + *x = y; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-2.c new file mode 100644 index 0000000..68e7f8e --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-2.c @@ -0,0 +1,110 @@ +/* Check that loads/stores from/to volatile mems utilize displacement + addressing modes and do not result in redundant sign/zero extensions. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "@\\(5," 4 } } */ +/* { dg-final { scan-assembler-times "@\\(10," 4 } } */ +/* { dg-final { scan-assembler-times "@\\(20," 4 } } */ +/* { dg-final { scan-assembler-times "@\\(40," 4 } } */ +/* { dg-final { scan-assembler-times "@\\(44," 4 } } */ +/* { dg-final { scan-assembler-not "exts" } } */ +/* { dg-final { scan-assembler-times "extu|movu" 2 } } */ + +int +test_00 (volatile char* x) +{ + return x[5]; +} + +void +test_100 (volatile char* x, char y) +{ + x[5] = y; +} + +int +test_01 (volatile short* x) +{ + return x[5]; +} + +void +test_101 (volatile short* x, short y) +{ + x[5] = y; +} + +int +test_02 (volatile int* x) +{ + return x[5]; +} + +void +test_102 (volatile int* x, int y) +{ + x[5] = y; +} + +long long +test_03 (volatile long long* x) +{ + return x[5]; +} + +void +test_103 (volatile long long* x, long long y) +{ + x[5] = y; +} + +unsigned int +test_04 (volatile unsigned char* x) +{ + // expected 1x extu.b or movu.b + return x[5]; +} + +void +test_104 (volatile unsigned char* x, unsigned char y) +{ + x[5] = y; +} + +unsigned int +test_05 (volatile unsigned short* x) +{ + // expected 1x extu.w or movu.w + return x[5]; +} + +void +test_105 (volatile unsigned short* x, unsigned short y) +{ + x[5] = y; +} + +unsigned int +test_06 (volatile unsigned int* x) +{ + return x[5]; +} + +void +test_106 (volatile unsigned int* x, unsigned int y) +{ + x[5] = y; +} + +unsigned long long +test_07 (volatile unsigned long long* x) +{ + return x[5]; +} + +void +test_107 (volatile unsigned long long* x, unsigned long long y) +{ + x[5] = y; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-3.c new file mode 100644 index 0000000..baeec33 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-3.c @@ -0,0 +1,43 @@ +/* Check that loads/stores from/to volatile mems utilize indexed addressing + modes and do not result in redundant sign/zero extensions. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "@\\(r0," 6 } } */ +/* { dg-final { scan-assembler-not "exts|extu" } } */ + +int +test_00 (volatile char* x, unsigned int y) +{ + return x[y]; +} + +void +test_100 (volatile char* x, unsigned int y, char z) +{ + x[y] = z; +} + +int +test_01 (volatile short* x, unsigned int y) +{ + return x[y]; +} + +void +test_101 (volatile short* x, unsigned int y, short z) +{ + x[y] = z; +} + +int +test_02 (volatile int* x, unsigned int y) +{ + return x[y]; +} + +int +test_102 (volatile int* x, unsigned int y, int z) +{ + x[y] = z; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-4.c new file mode 100644 index 0000000..743e8dc --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-4.c @@ -0,0 +1,18 @@ +/* Check that loads/stores from/to volatile floating point mems utilize + indexed addressing modes. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "@\\(r0," 2 } } */ + +float +test_00 (volatile float* x, unsigned int y) +{ + return x[y]; +} + +void +test_100 (volatile float* x, unsigned int y, float z) +{ + x[y] = z; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-5.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-5.c new file mode 100644 index 0000000..50aefe2 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52483-5.c @@ -0,0 +1,28 @@ +/* Check that loads from volatile mems utilize post-increment addressing + modes and do not result in redundant sign extensions. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "@r\[0-9\]\+\\+," 3 } } */ +/* { dg-final { scan-assembler-not "exts" } } */ + +volatile char* +test_00 (volatile char* x) +{ + int xx = *x++; + return x; +} + +volatile short* +test_01 (volatile short* x) +{ + int xx = *x++; + return x; +} + +volatile int* +test_02 (volatile int* x) +{ + int xx = *x++; + return x; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52933-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52933-1.c new file mode 100644 index 0000000..b65707e --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52933-1.c @@ -0,0 +1,168 @@ +/* Check that the div0s instruction is used for integer sign comparisons. + Each test case is expected to emit at least one div0s insn. + Problems when combining the div0s comparison result with surrounding + logic usually show up as redundant tst insns. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "div0s" 25 } } */ +/* { dg-final { scan-assembler-not "tst" } } */ + +typedef unsigned char bool; + +int other_func_a (int, int); +int other_func_b (int, int); + +bool +test_00 (int a, int b) +{ + return (a ^ b) >= 0; +} + +bool +test_01 (int a, int b) +{ + return (a ^ b) < 0; +} + +int +test_02 (int a, int b, int c, int d) +{ + if ((a ^ b) < 0) + return other_func_a (a, c); + else + return other_func_b (d, b); +} + +int +test_03 (int a, int b, int c, int d) +{ + if ((a ^ b) >= 0) + return other_func_a (a, c); + else + return other_func_b (d, b); +} + +int +test_04 (int a, int b) +{ + return (a ^ b) >= 0 ? -20 : -40; +} + +bool +test_05 (int a, int b) +{ + return (a ^ b) < 0; +} + +int +test_06 (int a, int b) +{ + return (a ^ b) < 0 ? -20 : -40; +} + +bool +test_07 (int a, int b) +{ + return (a < 0) == (b < 0); +} + +int +test_08 (int a, int b) +{ + return (a < 0) == (b < 0) ? -20 : -40; +} + +bool +test_09 (int a, int b) +{ + return (a < 0) != (b < 0); +} + +int +test_10 (int a, int b) +{ + return (a < 0) != (b < 0) ? -20 : -40; +} + +bool +test_11 (int a, int b) +{ + return (a >= 0) ^ (b < 0); +} + +int +test_12 (int a, int b) +{ + return (a >= 0) ^ (b < 0) ? -20 : -40; +} + +bool +test_13 (int a, int b) +{ + return !((a >= 0) ^ (b < 0)); +} + +int +test_14 (int a, int b) +{ + return !((a >= 0) ^ (b < 0)) ? -20 : -40; +} + +bool +test_15 (int a, int b) +{ + return (a & 0x80000000) == (b & 0x80000000); +} + +int +test_16 (int a, int b) +{ + return (a & 0x80000000) == (b & 0x80000000) ? -20 : -40; +} + +bool +test_17 (int a, int b) +{ + return (a & 0x80000000) != (b & 0x80000000); +} + +int +test_18 (int a, int b) +{ + return (a & 0x80000000) != (b & 0x80000000) ? -20 : -40; +} + +int +test_19 (unsigned int a, unsigned int b) +{ + return (a ^ b) >> 31; +} + +int +test_20 (unsigned int a, unsigned int b) +{ + return (a >> 31) ^ (b >> 31); +} + +int +test_21 (int a, int b) +{ + return ((a & 0x80000000) ^ (b & 0x80000000)) >> 31 ? -30 : -10; +} + +int +test_22 (int a, int b, int c, int d) +{ + if ((a < 0) == (b < 0)) + return other_func_a (a, b); + else + return other_func_b (c, d); +} + +bool +test_23 (int a, int b, int c, int d) +{ + /* Should emit 2x div0s. */ + return ((a < 0) == (b < 0)) | ((c < 0) == (d < 0)); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52933-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52933-2.c new file mode 100644 index 0000000..865cb37 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr52933-2.c @@ -0,0 +1,12 @@ +/* Check that the div0s instruction is used for integer sign comparisons + when -mpretend-cmove is enabled. + Each test case is expected to emit at least one div0s insn. + Problems when combining the div0s comparison result with surrounding + logic usually show up as redundant tst insns. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mpretend-cmove" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "div0s" 25 } } */ +/* { dg-final { scan-assembler-not "tst" } } */ + +#include "pr52933-1.c" diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53511-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53511-1.c new file mode 100644 index 0000000..d58a72c --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53511-1.c @@ -0,0 +1,14 @@ +/* Verify that the fmac insn is used for the standard fmaf function. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler "fmac" } } */ + +#include <math.h> + +float +test_func_00 (float a, float b, float c) +{ + return fmaf (a, b, c); +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-1.c new file mode 100644 index 0000000..c54671b --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-1.c @@ -0,0 +1,26 @@ +/* Verify that the fsca insn is used when specifying -mfsca and + -funsafe-math-optimizations. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -mfsca -funsafe-math-optimizations" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m3*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fsca" 3 } } */ + +#include <math.h> + +float +test_func_00 (float x) +{ + return sinf (x) + cosf (x); +} + +float +test_func_01 (float x) +{ + return sinf (x); +} + +float +test_func_02 (float x) +{ + return cosf (x); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-2.c new file mode 100644 index 0000000..ed41011 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-2.c @@ -0,0 +1,26 @@ +/* Verify that the fsca insn is not used when specifying -mno-fsca and + -funsafe-math-optimizations. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -mno-fsca -funsafe-math-optimizations" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "fsca" } } */ + +#include <math.h> + +float +test_func_00 (float x) +{ + return sinf (x) + cosf (x); +} + +float +test_func_01 (float x) +{ + return sinf (x); +} + +float +test_func_02 (float x) +{ + return cosf (x); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-3.c new file mode 100644 index 0000000..71522c8 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-3.c @@ -0,0 +1,15 @@ +/* Verify that the fsrra insn is used when specifying -mfsrra and + -funsafe-math-optimizations and -ffinite-math-only. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -mfsrra -funsafe-math-optimizations -ffinite-math-only" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m3*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler "fsrra" } } */ + +#include <math.h> + +float +test_func_00 (float x) +{ + return 1 / sqrtf (x); +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-4.c new file mode 100644 index 0000000..1645eed --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53512-4.c @@ -0,0 +1,15 @@ +/* Verify that the fsrra insn is not used when specifying -mno-fsrra and + -funsafe-math-optimizations and -ffinite-math-only. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -mno-fsrra -funsafe-math-optimizations -ffinite-math-only" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "fsrra" } } */ + +#include <math.h> + +float +test_func_00 (float x) +{ + return 1 / sqrtf (x); +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53568-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53568-1.c new file mode 100644 index 0000000..e274170 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53568-1.c @@ -0,0 +1,82 @@ +/* Check that the bswap32 pattern is generated as swap.b and swap.w + instructions. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "swap.w" 7 } } */ +/* { dg-final { scan-assembler-times "swap.b" 16 } } */ +/* { dg-final { scan-assembler-times "extu.w" 2 } } */ +/* { dg-final { scan-assembler-times "mov" 1 } } */ +/* { dg-final { scan-assembler-not "{shll8|shlr8|shld|shad}" } } */ + +int +test_func_00 (int a) +{ + /* 1x swap.w + 2x swap.b */ + return __builtin_bswap32 (a); +} + +unsigned int +test_func_01 (unsigned int a) +{ + /* 1x swap.w + 2x swap.b */ + return __builtin_bswap32 (a); +} + +int +test_func_02 (int a) +{ + /* 1x swap.w + 2x swap.b */ + return (((a >> 0) & 0xFF) << 24) + | (((a >> 8) & 0xFF) << 16) + | (((a >> 16) & 0xFF) << 8) + | (((a >> 24) & 0xFF) << 0); +} + +unsigned int +test_func_03 (unsigned int a) +{ + /* 1x swap.w + 2x swap.b */ + return (((a >> 0) & 0xFF) << 24) + | (((a >> 8) & 0xFF) << 16) + | (((a >> 16) & 0xFF) << 8) + | (((a >> 24) & 0xFF) << 0); +} + +int +test_func_04 (int a) +{ + /* 1x swap.b + 1x extu.w */ + return __builtin_bswap32 (a) >> 16; +} + +unsigned short +test_func_05 (unsigned short a) +{ + /* 1x swap.b + 1x extu.w */ + return __builtin_bswap32 (a) >> 16; +} + +long long +test_func_06 (long long a) +{ + /* 2x swap.w + 4x swap.b */ + return __builtin_bswap64 (a); +} + +long long +test_func_07 (long long a) +{ + /* 1x swap.w + 2x swap.b + 1x mov #0,Rn */ + return __builtin_bswap64 (a) >> 32; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53976-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53976-1.c new file mode 100644 index 0000000..4893b06 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53976-1.c @@ -0,0 +1,41 @@ +/* Check that the SH specific sh_optimize_sett_clrt RTL optimization pass + works as expected. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "clrt" 2 } } */ +/* { dg-final { scan-assembler-times "sett" 1 } } */ + +long long +test_00 (long long a, long long b, long long c, int d) +{ + /* One of the blocks should have a clrt and the other one should not. */ + if (d > 5) + return a + b; + else + return a + c; +} + +long long +test_01 (long long a, long long b) +{ + /* Must see a clrt because T bit is undefined at function entry. */ + return a + b; +} + +int +test_02 (const char* a) +{ + /* Must not see a sett after the inlined strlen. */ + return __builtin_strlen (a); +} + +int +test_03 (int a, int b, int c, int d) +{ + /* One of the blocks should have a sett and the other one should not. */ + if (d > 4) + return a + b + 1; + else + return a + c + 1; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53988.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53988.c new file mode 100644 index 0000000..a2e7213 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr53988.c @@ -0,0 +1,74 @@ +/* Check that the tst Rm,Rn instruction is generated for QImode and HImode + values loaded from memory. If everything goes as expected we won't see + any sign/zero extensions or and ops. On SH2A we don't expect to see the + movu insn. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "tst\tr" 8 } } */ +/* { dg-final { scan-assembler-not "tst\t#255" } } */ +/* { dg-final { scan-assembler-not "exts|extu|and|movu" } } */ + +int +test00 (char* a, char* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test01 (unsigned char* a, unsigned char* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test02 (short* a, short* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test03 (unsigned short* a, unsigned short* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test04 (char* a, short* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test05 (short* a, char* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test06 (int* a, char* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} + +int +test07 (int* a, short* b, int c, int d) +{ + if (*a & *b) + return c; + return d; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-1.c new file mode 100644 index 0000000..3eb700a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-1.c @@ -0,0 +1,174 @@ +/* Check that the rotcr instruction is generated. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "rotcr" 24 } } */ +/* { dg-final { scan-assembler-times "shll\t" 1 } } */ + +typedef char bool; + +long long +test_00 (long long a) +{ + return a >> 1; +} + +unsigned int +test_01 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a >> 1) | (r << 31)); +} + +unsigned int +test_02 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a >> 2) | (r << 31)); +} + +unsigned int +test_03 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a >> 3) | (r << 31)); +} + +unsigned int +test_04 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a >> 4) | (r << 31)); +} + +unsigned int +test_05 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a >> 5) | (r << 31)); +} + +unsigned int +test_06 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a >> 6) | (r << 31)); +} + +unsigned int +test_07 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a >> 7) | (r << 31)); +} + +unsigned int +test_08 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a >> 8) | (r << 31)); +} + +unsigned int +test_09 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a >> 31) | (r << 31)); +} + +int +test_10 (int a, int b) +{ + bool r = a == b; + return r << 31; +} + +unsigned int +test_11 (unsigned int a, int b) +{ + /* 1x shlr, 1x rotcr */ + return (a >> 1) | (b << 31); +} + +unsigned int +test_12 (unsigned int a, int b) +{ + return (a >> 2) | (b << 31); +} + +unsigned int +test_13 (unsigned int a, int b) +{ + return (a >> 3) | (b << 31); +} + +unsigned int +test_14 (unsigned int a, int b) +{ + /* 1x shll, 1x rotcr */ + bool r = b < 0; + return ((a >> 1) | (r << 31)); +} + +unsigned int +test_15 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a >> 1) | (r << 31)); +} + +unsigned int +test_16 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a >> 2) | (r << 31)); +} + +unsigned int +test_17 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a >> 3) | (r << 31)); +} + +unsigned int +test_18 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a >> 4) | (r << 31)); +} + +unsigned int +test_19 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a >> 5) | (r << 31)); +} + +unsigned int +test_20 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a >> 6) | (r << 31)); +} + +unsigned int +test_21 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a >> 7) | (r << 31)); +} + +unsigned int +test_22 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a >> 8) | (r << 31)); +} + +unsigned int +test_23 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a >> 31) | (r << 31)); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-2.c new file mode 100644 index 0000000..17466f3 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-2.c @@ -0,0 +1,22 @@ +/* Check that for dynamic logical right shifts with a constant the negated + constant is loaded directly, instead of loading the postitive constant + and negating it separately. This was a case that happened at optimization + level -O2 and looked like: + cmp/eq r6,r5 + mov #30,r1 + neg r1,r1 + shld r1,r4 + mov r4,r0 + rts + rotcr r0 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*"} { "-m3* -m2a* -m4*" } } */ +/* { dg-final { scan-assembler-not "neg" } } */ + +unsigned int +test (unsigned int a, int b, int c) +{ + unsigned char r = b == c; + return ((a >> 31) | (r << 31)); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-3.c new file mode 100644 index 0000000..abdb021 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-3.c @@ -0,0 +1,40 @@ +/* The dynamic shift library functions truncate the shift count to 5 bits. + Verify that this is taken into account and no extra shift count + truncations are generated before the library call. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m1*" "-m2" "-m2e*" } } */ +/* { dg-final { scan-assembler-not "and" } } */ +/* { dg-final { scan-assembler-not "#31" } } */ + +int +test00 (unsigned int a, int* b, int c, int* d, unsigned int e) +{ + int s = 0; + int i; + for (i = 0; i < c; ++i) + s += d[i] + b[i] + (e << (i & 31)); + return s; +} + +int +test01 (unsigned int a, int* b, int c, int* d, unsigned int e) +{ + int s = 0; + int i; + for (i = 0; i < c; ++i) + s += d[i] + b[i] + (e >> (i & 31)); + return s; +} + +int +test03 (unsigned int a, unsigned int b) +{ + return b << (a & 31); +} + +unsigned int +test04 (unsigned int a, int b) +{ + return a >> (b & 31); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-4.c new file mode 100644 index 0000000..e01e51c --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-4.c @@ -0,0 +1,15 @@ +/* Check that the rotcr instruction is generated when shifting the + negated T bit on non-SH2A. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" "-m2a*" } { "" } } */ +/* { dg-final { scan-assembler-times "rotcr" 1 } } */ +/* { dg-final { scan-assembler-times "tst" 1 } } */ +/* { dg-final { scan-assembler-times "movt" 1 } } */ + +int +test_00 (int a, int b) +{ + int r = a != b; + return r << 31; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-5.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-5.c new file mode 100644 index 0000000..decb9db --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-5.c @@ -0,0 +1,14 @@ +/* Check that the movrt rotr instruction sequence is generated when shifting + the negated T bit on SH2A. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-times "movrt" 1 } } */ +/* { dg-final { scan-assembler-times "rotr" 1 } } */ + +int +test_00 (int a, int b) +{ + int r = a != b; + return r << 31; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-6.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-6.c new file mode 100644 index 0000000..577690d --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-6.c @@ -0,0 +1,36 @@ +/* Check that the rotr and rotl instructions are generated. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "rotr" 2 } } */ +/* { dg-final { scan-assembler-times "rotl" 3 } } */ + +int +test_00 (int a) +{ + return (a << 1) | ((a >> 31) & 1); +} + +int +test_01 (int a) +{ + return (a << 1) | ((unsigned int)a >> 31); +} + +int +test_02 (int a) +{ + return ((unsigned int)a >> 1) | (a << 31); +} + +int +test_03 (int a) +{ + return ((a >> 1) & 0x7FFFFFFF) | (a << 31); +} + +int +test_04 (int a) +{ + return a + a + ((a >> 31) & 1); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-7.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-7.c new file mode 100644 index 0000000..0476f75 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-7.c @@ -0,0 +1,63 @@ +/* Check that the rotcr instruction is generated. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "rotcr" 4 } } */ +/* { dg-final { scan-assembler-not "movt" } } */ +/* { dg-final { scan-assembler-not "or\t" } } */ +/* { dg-final { scan-assembler-not "rotr" } } */ +/* { dg-final { scan-assembler-not "and" } } */ + +typedef char bool; + +int +test_00 (int* a, int* b) +{ + int i; + unsigned int r = 0; + for (i = 0; i < 16; ++i) + { + bool t = a[i] == b[i]; + r = (t << 31) | (r >> 1); + } + return r; +} + +int +test_01 (int* a, int* b) +{ + int i; + unsigned int r = 0; + for (i = 0; i < 16; ++i) + { + bool t = a[i] == b[i]; + r = (t << 31) | (r >> 2); + } + return r; +} + +int +test_02 (int* a, int* b) +{ + int i; + unsigned int r = 0; + for (i = 0; i < 16; ++i) + { + bool t = a[i] == b[i]; + r = (t << 31) | (r >> 3); + } + return r; +} + +unsigned int +test_03 (const bool* a) +{ + int i; + unsigned int r = 0; + for (i = 0; i < 32; ++i) + { + bool t = a[i]; + r = (t << 31) | (r >> 1); + } + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-8.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-8.c new file mode 100644 index 0000000..d2cced7 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-8.c @@ -0,0 +1,203 @@ +/* Check that the rotcl instruction is generated. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "rotcl" 28 } } */ + +typedef char bool; + +long long +test_00 (long long a) +{ + return a << 1; +} + +unsigned int +test_01 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a << 1) | r); +} + +unsigned int +test_02 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a << 2) | r); +} + +unsigned int +test_03 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a << 3) | r); +} + +unsigned int +test_04 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a << 4) | r); +} + +unsigned int +test_05 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a << 5) | r); +} + +unsigned int +test_06 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a << 6) | r); +} + +unsigned int +test_07 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a << 7) | r); +} + +unsigned int +test_08 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a << 8) | r); +} + +unsigned int +test_09 (unsigned int a, int b, int c) +{ + bool r = b == c; + return ((a << 31) | r); +} + +unsigned int +test_10 (unsigned int a, int b) +{ + /* 1x shlr, 1x rotcl */ + return (a << 1) | (b & 1); +} + +unsigned int +test_11 (unsigned int a, int b) +{ + /* 1x shlr, 1x rotcl (+1x add as shll) */ + return (a << 2) | (b & 1); +} + +unsigned int +test_12 (unsigned int a, int b) +{ + /* 1x shlr, 1x shll2, 1x rotcl */ + return (a << 3) | (b & 1); +} + +unsigned int +test_13 (unsigned int a, int b) +{ + /* 1x shll, 1x rotcl */ + bool r = b < 0; + return (a << 1) | r; +} + +unsigned int +test_14 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a << 1) | r); +} + +unsigned int +test_15 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a << 11) | r); +} + +unsigned int +test_16 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a << 3) | r); +} + +unsigned int +test_17 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a << 4) | r); +} + +unsigned int +test_18 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a << 5) | r); +} + +unsigned int +test_19 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a << 6) | r); +} + +unsigned int +test_20 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a << 7) | r); +} + +unsigned int +test_21 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a << 8) | r); +} + +unsigned int +test_22 (unsigned int a, int b, int c) +{ + bool r = b != c; + return ((a << 31) | r); +} + +unsigned int +test_23 (unsigned int a, int b, int c) +{ + /* 1x shll, 1x rotcl */ + return (a >> 31) | (b << 13); +} + +unsigned int +test_24 (unsigned int a, unsigned int b) +{ + /* 1x shll, 1x rotcl */ + return (a >> 31) | (b << 1); +} + +unsigned int +test_25 (unsigned int a, unsigned int b) +{ + /* 1x shll, 1x rotcl */ + return (a >> 31) | (b << 3); +} + +unsigned int +test_26 (unsigned int a, unsigned int b) +{ + /* 1x shll, 1x rotcl */ + return (b << 3) | (a >> 31); +} + +unsigned int +test_27 (unsigned int a, unsigned int b) +{ + /* 1x shlr, 1x rotcl */ + return (a << 1) | ((b >> 4) & 1); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-9.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-9.c new file mode 100644 index 0000000..8aa15df --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54089-9.c @@ -0,0 +1,63 @@ +/* Check that the rotcr instruction is generated. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "rotcl" 4 } } */ +/* { dg-final { scan-assembler-not "movt" } } */ +/* { dg-final { scan-assembler-not "or\t" } } */ +/* { dg-final { scan-assembler-not "rotl" } } */ +/* { dg-final { scan-assembler-not "and" } } */ + +typedef char bool; + +int +test_00 (int* a, int* b) +{ + int i; + int r = 0; + for (i = 0; i < 16; ++i) + { + bool t = a[i] == b[i]; + r = (r << 1) | t; + } + return r; +} + +int +test_01 (int* a, int* b) +{ + int i; + int r = 0; + for (i = 0; i < 16; ++i) + { + bool t = a[i] == b[i]; + r = (r << 2) | t; + } + return r; +} + +int +test_02 (int* a, int* b) +{ + int i; + int r = 0; + for (i = 0; i < 16; ++i) + { + bool t = a[i] == b[i]; + r = (r << 3) | t; + } + return r; +} + +int +test_03 (const bool* a) +{ + int i; + int r = 0; + for (i = 0; i < 16; ++i) + { + bool t = a[i]; + r = (r << 1) | (t & 1); + } + return r; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54236-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54236-1.c new file mode 100644 index 0000000..f7568a9 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54236-1.c @@ -0,0 +1,83 @@ +/* Tests to check the utilization of addc, subc and negc instructions in + special cases. If everything works as expected we won't see any + movt instructions in these cases. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "addc" 4 } } */ +/* { dg-final { scan-assembler-times "subc" 3 } } */ +/* { dg-final { scan-assembler-times "sett" 5 } } */ +/* { dg-final { scan-assembler-times "negc" 1 } } */ +/* { dg-final { scan-assembler-not "movt" } } */ + +int +test_00 (int a, int b, int c, int d) +{ + /* 1x addc, 1x sett */ + return a + b + 1; +} + +int +test_01 (int a, int b, int c, int d) +{ + /* 1x addc */ + return a + (c == d); +} + +int +test_02 (int a, int b, int c, int d) +{ + /* 1x subc, 1x sett */ + return a - b - 1; +} + +int +test_03 (int a, int b, int c, int d) +{ + /* 1x subc */ + return a - (c == d); +} + +int +test_04 (int a, int b, int c, int d) +{ + /* 1x addc, 1x sett */ + return a + b + c + 1; +} + +int +test_05 (int a, int b, int c, int d) +{ + /* 1x subc, 1x sett */ + return a - b - c - 1; +} + +int +test_06 (int a, int b, int c, int d) +{ + /* 1x negc */ + return 0 - a - (b == c); +} + +int +test_07 (int *vec) +{ + /* Must not see a 'sett' or 'addc' here. + This is a case where combine tries to produce + 'a + (0 - b) + 1' out of 'a - b + 1'. */ + int z = vec[0]; + int vi = vec[1]; + int zi = vec[2]; + + if (zi != 0 && z < -1) + vi -= (((vi >> 7) & 0x01) << 1) - 1; + + return vi; +} + +int +test_08 (int a) +{ + /* 1x addc, 1x sett */ + return (a << 1) + 1; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54236-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54236-2.c new file mode 100644 index 0000000..b3cf48c --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54236-2.c @@ -0,0 +1,270 @@ +/* Tests to check the utilization of the addc instruction in special cases. + If everything works as expected we won't see any movt instructions in + these cases. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "addc" 37 } } */ +/* { dg-final { scan-assembler-times "shlr" 23 } } */ +/* { dg-final { scan-assembler-times "shll" 14 } } */ +/* { dg-final { scan-assembler-times "add\t" 12 } } */ +/* { dg-final { scan-assembler-not "movt" } } */ + +int +test_000 (int a, int c, int b, int d) +{ + // 1x shlr, 1x addc + return a + (b & 1); +} + +int +test_001 (int a, int c, int b, int d) +{ + // 1x shlr, 1x addc + return a + b + (c & 1); +} + +int +test_002 (int a, int c, int b, int d) +{ + // 1x shlr, 1x add, 1x addc + return a + b + c + (d & 1); +} + +int +test_003 (int a, int c, int b, int d) +{ + // 1x shlr, 1x addc + return (b & 1) + a; +} + +int +test_004 (int a, int c, int b, int d) +{ + // 1x shlr, 1x addc + return a + (c & 1) + b; +} + +int +test_005 (int a, int c, int b, int d) +{ + // 1x shlr, 1x add, 1x addc + return a + b + (d & 1) + c; +} + +int +test_006 (int a, int c, int b, int d) +{ + // 1x shlr, 1x addc + return (c & 1) + a + b; +} + +int +test_007 (int a, int c, int b, int d) +{ + // 1x shlr, 1x add, 1x addc + return a + (d & 1) + b + c; +} + +int +test_008 (int a, int c, int b, int d) +{ + // 1x shlr, 1x add, 1x addc + return (d & 1) + a + b + c; +} + +int +test_009 (int a, int c, int b, int d) +{ + // 1x shlr, 1x addc + return a + b + (b & 1); +} + +int +test_010 (int a, int c, int b, int d) +{ + // 1x shlr, 1x addc + return a + (b & 1) + b; +} + +int +test_011 (int a, int c, int b, int d) +{ + // 1x shlr, 1x addc + return (b & 1) + a + b; +} + +int +test_012 (int a, int c, int b, int d) +{ + // 1x shlr, 1x add, 1x addc + return a + b + d + (b & 1); +} + +int +test_013 (int a, int c, int b, int d) +{ + // 1x shlr, 1x add, 1x addc + return a + d + (b & 1) + b; +} + +int +test_014 (int a, int c, int b, int d) +{ + // 1x shlr, 1x add, 1x addc + return a + (b & 1) + d + b; +} + +int +test_015 (int a, int c, int b, int d) +{ + // 1x shlr, 1x add, 1x addc + return (b & 1) + a + d + b; +} + +int +test_016 (int a, int b, int c, int d) +{ + // 1x shlr, 1x addc + return a + (a & 1); +} + +int +test_017 (int a, int b, int c, int d) +{ + // 1x shlr, 1x addc + return a + a + (a & 1); +} + +int +test_018 (int a, int b, int c, int d) +{ + // 1x shlr, 1x addc + return a + (a & 1) + a; +} + +int +test_019 (int a, int b, int c, int d) +{ + // 1x shlr, 1x addc + return (a & 1) + a + a; +} + +int +test_020 (int a, int b, int c, int d) +{ + // 1x shlr, 1x addc + return b + b + (a & 1); +} + +int +test_021 (int a, int b, int c, int d) +{ + // 1x shlr, 1x addc + return b + (a & 1) + b; +} + +int +test_022 (int a, int b, int c, int d) +{ + // 1x shlr, 1x addc + return (a & 1) + b + b; +} + +int +test_023 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc + return a + ((b >> 31) & 1); +} + +int +test_024 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc + return ((b >> 31) & 1) + a; +} + +int +test_025 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc + return ((a >> 31) & 1) + a; +} + +int +test_026 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc + return a + ((a >> 31) & 1); +} + +int +test_027 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc + return a + b + ((c >> 31) & 1); +} + +int +test_028 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc + return a + ((c >> 31) & 1) + b; +} + +int +test_029 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc + return ((c >> 31) & 1) + a + b; +} + +int +test_030 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc, 1x add + return a + b + c + ((d >> 31) & 1); +} + +int +test_031 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc, 1x add + return a + b + ((d >> 31) & 1) + c; +} + +int +test_032 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc, 1x add + return a + ((d >> 31) & 1) + b + c; +} + +int +test_033 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc, 1x add + return ((d >> 31) & 1) + a + b + c; +} + +int +test_034 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc + return a + a + ((d >> 31) & 1); +} + +int +test_035 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc + return a + ((d >> 31) & 1) + a; +} + +int +test_036 (int a, int b, int c, int d) +{ + // 1x shll, 1x addc + return ((d >> 31) & 1) + a + a; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54386.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54386.c new file mode 100644 index 0000000..ec52d89 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54386.c @@ -0,0 +1,41 @@ +/* Check that the inlined mem load is not handled as unaligned load. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-not "shll|extu|or" } } */ + +static inline int +readint0 (int* x) +{ + return *x; +} + +int +test0 (int* x) +{ + return readint0 (x); +} + +inline int +readint1 (int* x) +{ + return *x; +} + +int +test1 (int* x) +{ + return readint1 (x); +} + +static int +readint2 (int* x) +{ + return *x; +} + +int +test2 (int* x) +{ + return readint2 (x); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-1.c new file mode 100644 index 0000000..bd402b3 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-1.c @@ -0,0 +1,15 @@ +/* Verify that the delay slot is stuffed with register pop insns for normal + (i.e. not interrupt handler) function returns. If everything goes as + expected we won't see any nop insns. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-not "nop" } } */ + +int test00 (int a, int b); + +int +test01 (int a, int b, int c, int d) +{ + return test00 (a, b) + c; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-2.c new file mode 100644 index 0000000..05592dd --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-2.c @@ -0,0 +1,15 @@ +/* Verify that the delay slot is not stuffed with register pop insns for + interrupt handler function returns on SH1* and SH2* targets, where the + rte insn uses the stack pointer. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m1*" "-m2*" } } */ +/* { dg-final { scan-assembler-times "nop" 1 } } */ + +int test00 (int a, int b); + +int __attribute__ ((interrupt_handler)) +test01 (int a, int b, int c, int d) +{ + return test00 (a, b) + c; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-3.c new file mode 100644 index 0000000..5d6a75a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-3.c @@ -0,0 +1,12 @@ +/* Verify that the rte delay slot is not stuffed with register pop insns + which touch the banked registers r0..r7 on SH3* and SH4* targets. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m3*" "-m4*" } } */ +/* { dg-final { scan-assembler-times "nop" 1 } } */ + +int __attribute__ ((interrupt_handler)) +test00 (int a, int b, int c, int d) +{ + return a + b; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-4.c new file mode 100644 index 0000000..78fb909 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54602-4.c @@ -0,0 +1,15 @@ +/* Verify that the delay slot is stuffed with register pop insns on SH3* and + SH4* targets, where the stack pointer is not used by the rte insn. If + everything works out, we won't see a nop insn. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m3*" "-m4*" } } */ +/* { dg-final { scan-assembler-not "nop" } } */ + +int test00 (int a, int b); + +int __attribute__ ((interrupt_handler)) +test01 (int a, int b, int c, int d) +{ + return test00 (a, b) + c; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54680.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54680.c new file mode 100644 index 0000000..9171eea --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54680.c @@ -0,0 +1,66 @@ +/* Verify that the fsca input value is not converted to float and then back + to int. Notice that we can't count just "lds" insns because mode switches + use "lds.l". */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mfsca -funsafe-math-optimizations" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m3*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fsca" 7 } } */ +/* { dg-final { scan-assembler-times "shad" 1 } } */ +/* { dg-final { scan-assembler-times "lds\t" 6 } } */ +/* { dg-final { scan-assembler-times "fmul" 2 } } */ +/* { dg-final { scan-assembler-times "ftrc" 1 } } */ + +#include <math.h> + +static const float pi = 3.14159265359f; + +float +test00 (int x) +{ + /* 1x shad, 1x lds, 1x fsca */ + return sinf ( (x >> 8) * (2*pi) / (1 << 16)); +} + +float +test01 (int x) +{ + /* 1x lds, 1x fsca */ + return sinf (x * (2*pi) / 65536); +} + +float +test02 (int x) +{ + /* 1x lds, 1x fsca */ + return sinf (x * (2*pi / 65536)); +} + +float +test03 (int x) +{ + /* 1x lds, 1x fsca */ + float scale = 2*pi / 65536; + return sinf (x * scale); +} + +float +test04 (int x) +{ + /* 1x lds, 1x fsca */ + return cosf (x / 65536.0f * 2*pi); +} + +float +test05 (int x) +{ + /* 1x lds, 1x fsca, 1x fmul */ + float scale = 2*pi / 65536; + return sinf (x * scale) * cosf (x * scale); +} + +float +test_06 (float x) +{ + /* 1x fmul, 1x ftrc, 1x fsca */ + return sinf (x); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54685.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54685.c new file mode 100644 index 0000000..111a120 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54685.c @@ -0,0 +1,58 @@ +/* Check that a comparison 'unsigned int <= 0x7FFFFFFF' results in code + utilizing the cmp/pz instruction. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-not "not\[ \t\]" } } */ +/* { dg-final { scan-assembler-times "cmp/pz" 7 } } */ +/* { dg-final { scan-assembler-times "shll" 1 } } */ +/* { dg-final { scan-assembler-times "movt" 4 } } */ + +int +test_00 (unsigned int a) +{ + return !(a > 0x7FFFFFFF); +} + +int +test_01 (unsigned int a) +{ + return !(a > 0x7FFFFFFF) ? -5 : 10; +} + +int +test_02 (unsigned int a) +{ + /* 1x shll, 1x movt */ + return a >= 0x80000000; +} + +int +test_03 (unsigned int a) +{ + return a >= 0x80000000 ? -5 : 10; +} + +int +test_04 (unsigned int a) +{ + return a <= 0x7FFFFFFF; +} + +int +test_05 (unsigned int a) +{ + return a <= 0x7FFFFFFF ? -5 : 10; +} + +int +test_06 (unsigned int a) +{ + return a < 0x80000000; +} + +int +test_07 (unsigned int a) +{ + return a < 0x80000000 ? -5 : 10; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-1.c new file mode 100644 index 0000000..4437511 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-1.c @@ -0,0 +1,20 @@ +/* Check that the __builtin_thread_pointer and __builtin_set_thread_pointer + built-in functions result in gbr store / load instructions. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "ldc" 1 } } */ +/* { dg-final { scan-assembler-times "stc" 1 } } */ +/* { dg-final { scan-assembler-times "gbr" 2 } } */ + +void* +test00 (void) +{ + return __builtin_thread_pointer (); +} + +void +test01 (void* p) +{ + __builtin_set_thread_pointer (p); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-2.c new file mode 100644 index 0000000..4a3561a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-2.c @@ -0,0 +1,259 @@ +/* Check that thread pointer relative memory accesses are converted to + gbr displacement address modes. If we see a gbr register store + instruction something is not working properly. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "stc\tgbr" 0 } } */ + +/* --------------------------------------------------------------------------- + Simple GBR load. +*/ +#define func(name, rettype, type, disp)\ + rettype \ + name ## _tp_load (void) \ + { \ + type* tp = (type*)__builtin_thread_pointer (); \ + return tp[disp]; \ + } + +func (test00, int, int, 0) +func (test01, int, int, 5) +func (test02, int, int, 255) + +func (test03, int, short, 0) +func (test04, int, short, 5) +func (test05, int, short, 255) + +func (test06, int, char, 0) +func (test07, int, char, 5) +func (test08, int, char, 255) + +func (test09, int, unsigned int, 0) +func (test10, int, unsigned int, 5) +func (test11, int, unsigned int, 255) + +func (test12, int, unsigned short, 0) +func (test13, int, unsigned short, 5) +func (test14, int, unsigned short, 255) + +func (test15, int, unsigned char, 0) +func (test16, int, unsigned char, 5) +func (test17, int, unsigned char, 255) + +func (test18, long long, long long, 0) +func (test19, long long, long long, 5) +func (test20, long long, long long, 127) + +func (test21, long long, unsigned long long, 0) +func (test22, long long, unsigned long long, 5) +func (test23, long long, unsigned long long, 127) + +#undef func + +/* --------------------------------------------------------------------------- + Simple GBR store. +*/ +#define func(name, argtype, type, disp)\ + void \ + name ## _tp_store (argtype a) \ + { \ + type* tp = (type*)__builtin_thread_pointer (); \ + tp[disp] = (type)a; \ + } + +func (test00, int, int, 0) +func (test01, int, int, 5) +func (test02, int, int, 255) + +func (test03, int, short, 0) +func (test04, int, short, 5) +func (test05, int, short, 255) + +func (test06, int, char, 0) +func (test07, int, char, 5) +func (test08, int, char, 255) + +func (test09, int, unsigned int, 0) +func (test10, int, unsigned int, 5) +func (test11, int, unsigned int, 255) + +func (test12, int, unsigned short, 0) +func (test13, int, unsigned short, 5) +func (test14, int, unsigned short, 255) + +func (test15, int, unsigned char, 0) +func (test16, int, unsigned char, 5) +func (test17, int, unsigned char, 255) + +func (test18, long long, long long, 0) +func (test19, long long, long long, 5) +func (test20, long long, long long, 127) + +func (test21, long long, unsigned long long, 0) +func (test22, long long, unsigned long long, 5) +func (test23, long long, unsigned long long, 127) + +#undef func + +/* --------------------------------------------------------------------------- + Arithmetic on the result of a GBR load. +*/ +#define func(name, retargtype, type, disp, op, opname)\ + retargtype \ + name ## _tp_load_arith_ ##opname (retargtype a) \ + { \ + type* tp = (type*)__builtin_thread_pointer (); \ + return tp[disp] op a; \ + } + +#define funcs(op, opname) \ + func (test00, int, int, 0, op, opname) \ + func (test01, int, int, 5, op, opname) \ + func (test02, int, int, 255, op, opname) \ + func (test03, int, short, 0, op, opname) \ + func (test04, int, short, 5, op, opname) \ + func (test05, int, short, 255, op, opname) \ + func (test06, int, char, 0, op, opname) \ + func (test07, int, char, 5, op, opname) \ + func (test08, int, char, 255, op, opname) \ + func (test09, int, unsigned int, 0, op, opname) \ + func (test10, int, unsigned int, 5, op, opname) \ + func (test11, int, unsigned int, 255, op, opname) \ + func (test12, int, unsigned short, 0, op, opname) \ + func (test13, int, unsigned short, 5, op, opname) \ + func (test14, int, unsigned short, 255, op, opname) \ + func (test15, int, unsigned char, 0, op, opname) \ + func (test16, int, unsigned char, 5, op, opname) \ + func (test17, int, unsigned char, 255, op, opname) \ + func (test18, long long, long long, 0, op, opname) \ + func (test19, long long, long long, 5, op, opname) \ + func (test20, long long, long long, 127, op, opname) \ + func (test21, long long, unsigned long long, 0, op, opname) \ + func (test22, long long, unsigned long long, 5, op, opname) \ + func (test23, long long, unsigned long long, 127, op, opname) \ + +funcs (+, plus) +funcs (-, minus) +funcs (*, mul) +funcs (&, and) +funcs (|, or) +funcs (^, xor) + +#undef funcs +#undef func + +/* --------------------------------------------------------------------------- + Arithmetic of the result of two GBR loads. +*/ +#define func(name, rettype, type, disp0, disp1, op, opname)\ + rettype \ + name ## _tp_load_load_arith_ ##opname (void) \ + { \ + type* tp = (type*)__builtin_thread_pointer (); \ + return tp[disp0] op tp[disp1]; \ + } + +#define funcs(op, opname) \ + func (test00, int, int, 0, 5, op, opname) \ + func (test02, int, int, 1, 255, op, opname) \ + func (test03, int, short, 0, 5, op, opname) \ + func (test05, int, short, 1, 255, op, opname) \ + func (test06, int, char, 0, 5, op, opname) \ + func (test08, int, char, 1, 255, op, opname) \ + func (test09, int, unsigned int, 0, 5, op, opname) \ + func (test11, int, unsigned int, 1, 255, op, opname) \ + func (test12, int, unsigned short, 0, 5, op, opname) \ + func (test14, int, unsigned short, 1, 255, op, opname) \ + func (test15, int, unsigned char, 0, 5, op, opname) \ + func (test17, int, unsigned char, 1, 255, op, opname) \ + func (test18, long long, long long, 0, 5, op, opname) \ + func (test19, long long, long long, 1, 127, op, opname) \ + func (test20, long long, unsigned long long, 0, 5, op, opname) \ + func (test21, long long, unsigned long long, 1, 127, op, opname) \ + +funcs (+, plus) +funcs (-, minus) +funcs (*, mul) +funcs (&, and) +funcs (|, or) +funcs (^, xor) + +#undef funcs +#undef func + +/* --------------------------------------------------------------------------- + GBR load GBR store copy. +*/ + +#define func(name, type, disp0, disp1)\ + void \ + name ## _tp_copy (void) \ + { \ + type* tp = (type*)__builtin_thread_pointer (); \ + tp[disp0] = tp[disp1]; \ + } + +func (test00, int, 0, 5) +func (test02, int, 1, 255) +func (test03, short, 0, 5) +func (test05, short, 1, 255) +func (test06, char, 0, 5) +func (test08, char, 1, 255) +func (test09, unsigned int, 0, 5) +func (test11, unsigned int, 1, 255) +func (test12, unsigned short, 0, 5) +func (test14, unsigned short, 1, 255) +func (test15, unsigned char, 0, 5) +func (test17, unsigned char, 1, 255) +func (test18, long long, 0, 5) +func (test19, long long, 1, 127) +func (test20, unsigned long long, 0, 5) +func (test21, unsigned long long, 1, 127) + +#undef func + +/* --------------------------------------------------------------------------- + GBR load, arithmetic, GBR store +*/ + +#define func(name, argtype, type, disp, op, opname)\ + void \ + name ## _tp_load_arith_store_ ##opname (argtype a) \ + { \ + type* tp = (type*)__builtin_thread_pointer (); \ + tp[disp] op a; \ + } + +#define funcs(op, opname) \ + func (test00, int, int, 0, op, opname) \ + func (test01, int, int, 5, op, opname) \ + func (test02, int, int, 255, op, opname) \ + func (test03, int, short, 0, op, opname) \ + func (test04, int, short, 5, op, opname) \ + func (test05, int, short, 255, op, opname) \ + func (test06, int, char, 0, op, opname) \ + func (test07, int, char, 5, op, opname) \ + func (test08, int, char, 255, op, opname) \ + func (test09, int, unsigned int, 0, op, opname) \ + func (test10, int, unsigned int, 5, op, opname) \ + func (test11, int, unsigned int, 255, op, opname) \ + func (test12, int, unsigned short, 0, op, opname) \ + func (test13, int, unsigned short, 5, op, opname) \ + func (test14, int, unsigned short, 255, op, opname) \ + func (test15, int, unsigned char, 0, op, opname) \ + func (test16, int, unsigned char, 5, op, opname) \ + func (test17, int, unsigned char, 255, op, opname) \ + func (test18, long long, long long, 0, op, opname) \ + func (test19, long long, long long, 5, op, opname) \ + func (test20, long long, long long, 127, op, opname) \ + func (test21, long long, unsigned long long, 0, op, opname) \ + func (test22, long long, unsigned long long, 5, op, opname) \ + func (test23, long long, unsigned long long, 127, op, opname) \ + +funcs (+=, plus) +funcs (-=, minus) +funcs (*=, mul) +funcs (&=, and) +funcs (|=, or) +funcs (^=, xor) diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-3.c new file mode 100644 index 0000000..678fb39 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-3.c @@ -0,0 +1,69 @@ +/* Check that these thread relative memory accesses play along with + surrounding code. + These should be moved to C torture tests once there are target + independent thread_pointer built-in functions available. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ + +int +test00 (void* p, int x) +{ + int* tcb = (int*)__builtin_thread_pointer (); + int r = tcb[4]; + + __builtin_set_thread_pointer (p); + + tcb = (int*)__builtin_thread_pointer (); + return tcb[255] + r; +} + +int +test01 (void) +{ + unsigned short* tcb = (unsigned short*)__builtin_thread_pointer (); + return tcb[500]; +} + +void +test02 (int* x, int a, int b) +{ + int* tcb = (int*)__builtin_thread_pointer (); + tcb[50] = a; + + __builtin_set_thread_pointer (x); + + tcb = (int*)__builtin_thread_pointer (); + tcb[40] = b; +} + +int +test03 (const int* x, int c) +{ + volatile int* tcb = (volatile int*)__builtin_thread_pointer (); + + int s = 0; + int i; + for (i = 0; i < c; ++i) + s ^= x[i] + tcb[40]; + + return s; +} + +int +test04 (const int* x, int c, int** xx, int d) +{ + int s = 0; + int i; + for (i = 0; i < c; ++i) + { + volatile int* tcb = (volatile int*)__builtin_thread_pointer (); + tcb[20] = s; + + __builtin_set_thread_pointer (xx[i]); + + tcb = (volatile int*)__builtin_thread_pointer (); + s ^= x[i] + tcb[40] + d; + } + return s; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-4.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-4.c new file mode 100644 index 0000000..d218281 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr54760-4.c @@ -0,0 +1,19 @@ +/* Check that the GBR address optimization does not combine a gbr store + and its use when a function call is in between, when GBR is a call used + register, i.e. it is invalidated by function calls. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fcall-used-gbr" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler "stc\tgbr" } } */ + +extern int test00 (void); +int +test01 (int x) +{ + /* We must see a stc gbr,rn before the function call, because + a function call could modify the gbr. In this case the user requests + the old gbr value, before the function call. */ + int* p = (int*)__builtin_thread_pointer (); + p[5] = test00 (); + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55146.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55146.c new file mode 100644 index 0000000..91f0935 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55146.c @@ -0,0 +1,50 @@ +/* Check that the 'extu.b' instruction is generated for short jump tables. */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler "extu.b" } } */ + +int +test (int arg) +{ + int rc; + switch (arg) + { + case 0: + asm ("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t" + "nop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\t" + "mov r4,%0" + : "=r" (rc) + : "r" (arg)); + break; + case 1: + asm ("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t" + "nop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\t" + "mov r5,%0" + : "=r" (rc) + : "r" (arg)); + break; + case 2: + asm ("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t" + "nop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\t" + "mov r6,%0" + : "=r" (rc) + : "r" (arg)); + break; + case 3: + asm ("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t" + "nop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\t" + "mov r7,%0" + : "=r" (rc) + : "r" (arg)); + break; + case 4: + asm ("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t" + "nop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\t" + "mov r8,%0" + : "=r" (rc) + : "r" (arg)); + break; + } + return rc; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55160.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55160.c new file mode 100644 index 0000000..dca15c9 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55160.c @@ -0,0 +1,25 @@ +/* Check that the decrement-and-test instruction is generated. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "dt\tr" 2 } } */ + +int +test_00 (int* x, int c) +{ + int s = 0; + int i; + for (i = 0; i < c; ++i) + s += x[i]; + return s; +} + +int +test_01 (int* x, int c) +{ + int s = 0; + int i; + for (i = 0; i < c; ++i) + s += *--x; + return s; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55303-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55303-1.c new file mode 100644 index 0000000..b77c5e1 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55303-1.c @@ -0,0 +1,87 @@ +/* Verify that the SH2A clips and clipu instructions are generated as + expected. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-times "clips.b" 2 } } */ +/* { dg-final { scan-assembler-times "clips.w" 2 } } */ +/* { dg-final { scan-assembler-times "clipu.b" 2 } } */ +/* { dg-final { scan-assembler-times "clipu.w" 2 } } */ + +static inline int +min (int a, int b) +{ + return a < b ? a : b; +} + +static inline int +max (int a, int b) +{ + return a < b ? b : a; +} + +int +test_00 (int a) +{ + /* 1x clips.b */ + return max (-128, min (127, a)); +} + +int +test_01 (int a) +{ + /* 1x clips.b */ + return min (127, max (-128, a)); +} + +int +test_02 (int a) +{ + /* 1x clips.w */ + return max (-32768, min (32767, a)); +} + +int +test_03 (int a) +{ + /* 1x clips.w */ + return min (32767, max (-32768, a)); +} + +unsigned int +test_04 (unsigned int a) +{ + /* 1x clipu.b */ + return a > 255 ? 255 : a; +} + +unsigned int +test_05 (unsigned int a) +{ + /* 1x clipu.b */ + return a >= 255 ? 255 : a; +} + +unsigned int +test_06 (unsigned int a) +{ + /* 1x clipu.w */ + return a > 65535 ? 65535 : a; +} + +unsigned int +test_07 (unsigned int a) +{ + /* 1x clipu.w */ + return a >= 65535 ? 65535 : a; +} + +void +test_08 (unsigned short a, unsigned short b, unsigned int* r) +{ + /* Must not see a clip insn here -- it is not needed. */ + unsigned short x = a + b; + if (x > 65535) + x = 65535; + *r = x; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55303-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55303-2.c new file mode 100644 index 0000000..34f7063 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55303-2.c @@ -0,0 +1,35 @@ +/* Verify that for SH2A smax/smin -> cbranch conversion is done properly + if the clips insn is not used and the expected comparison insns are + generated. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-times "cmp/pl" 4 } } */ + +int +test_00 (int a) +{ + /* 1x cmp/pl */ + return a >= 0 ? a : 0; +} + +int +test_01 (int a) +{ + /* 1x cmp/pl */ + return a <= 0 ? a : 0; +} + +int +test_02 (int a) +{ + /* 1x cmp/pl */ + return a < 1 ? 1 : a; +} + +int +test_03 (int a) +{ + /* 1x cmp/pl */ + return a < 1 ? a : 1; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55303-3.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55303-3.c new file mode 100644 index 0000000..57c2f40 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr55303-3.c @@ -0,0 +1,15 @@ +/* Verify that the special case (umin (reg const_int 1)) results in the + expected instruction sequence on SH2A. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */ +/* { dg-final { scan-assembler-times "tst" 1 } } */ +/* { dg-final { scan-assembler-times "movrt" 1 } } */ + +unsigned int +test_00 (unsigned int a) +{ + /* 1x tst + 1x movrt */ + return a > 1 ? 1 : a; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr56547-1.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr56547-1.c new file mode 100644 index 0000000..0c7c97e --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr56547-1.c @@ -0,0 +1,19 @@ +/* Verify that the fmac insn is used for the expression 'a * b + a' and + 'a * a + a'. + This assumes that the default compiler setting is -ffp-contract=fast. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmac" 2 } } */ + +float +test_00 (float a, float b) +{ + return a * b + a; +} + +float +test_01 (float a) +{ + return a * a + a; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr56547-2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr56547-2.c new file mode 100644 index 0000000..2d36fa9 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr56547-2.c @@ -0,0 +1,18 @@ +/* Verify that the fmac insn is used for the expression 'a * b + a' and + 'a * a + a' when -ffast-math is specified. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -ffast-math" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmac" 2 } } */ + +float +test_00 (float a, float b) +{ + return a * b + a; +} + +float +test_01 (float a) +{ + return a * a + a; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pr6526.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr6526.c new file mode 100644 index 0000000..a49b877 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pr6526.c @@ -0,0 +1,64 @@ +/* Check that the XF registers are not clobbered by an integer division + that is done using double precision FPU division. */ +/* { dg-do run } */ +/* { dg-options "-O1 -mdiv=call-fp" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m4*-single" "-m4*-single-only" } } */ + +#include <assert.h> +#include <stdlib.h> + +extern void __set_fpscr (int); + +void +write_xf0 (float* f) +{ + __asm__ __volatile__ ("frchg; fmov.s @%0,fr0; frchg" : : "r" (f) : "memory"); +} + +void +read_xf0 (float* f) +{ + __asm__ __volatile__ ("frchg; fmov.s fr0,@%0; frchg" : : "r" (f) : "memory"); +} + +int __attribute__ ((noinline)) +test_00 (int a, int b) +{ + return a / b; +} + +unsigned int __attribute__ ((noinline)) +test_01 (unsigned a, unsigned b) +{ + return a / b; +} + +int __attribute__ ((noinline)) +test_02 (int x) +{ + return x & 0; +} + +int +main (void) +{ + float test_value; + int r = 0; + + /* Set FPSCR.FR to 1. */ + __set_fpscr (0x200000); + + test_value = 123; + write_xf0 (&test_value); + r += test_00 (40, 4); + read_xf0 (&test_value); + assert (test_value == 123); + + test_value = 321; + write_xf0 (&test_value); + r += test_01 (50, 5); + read_xf0 (&test_value); + assert (test_value == 321); + + return test_02 (r); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-nosave_low_regs.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-nosave_low_regs.c new file mode 100644 index 0000000..e1d880d --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-nosave_low_regs.c @@ -0,0 +1,23 @@ +/* A call will clobber all call-saved registers. + If #pragma nosave_low_regs is specified, do not save/restore r0..r7. + (On SH3* and SH4* r0..r7 are banked) + One of these registers will also do fine to hold the function address. + Call-saved registers r8..r13 also don't need to be restored. */ +/* { dg-do compile { target { { "sh*-*-*" } && nonpic } } } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1*" "-m2*" "-m5*" } { "" } } */ +/* { dg-options "-O" } */ +/* { dg-final { scan-assembler-times "rte" 1 } } */ +/* { dg-final { scan-assembler-not "\[^f\]r\[0-9\]\[ \t\]*," } } */ +/* { dg-final { scan-assembler-not "\[^f\]r\[89\]" } } */ +/* { dg-final { scan-assembler-not "\[^f\]r1\[,0-3\]" } } */ +/* { dg-final { scan-assembler-times "macl" 2 } } */ + +extern void foo (void); + +#pragma interrupt +#pragma nosave_low_regs +void +isr (void) +{ + foo (); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-trap-exit.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-trap-exit.c new file mode 100644 index 0000000..6dbd8e7 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-trap-exit.c @@ -0,0 +1,24 @@ +/* Check whether trapa is generated only for an ISR. */ +/* { dg-do compile } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-options "-O" } */ +/* { dg-final { scan-assembler-times "trapa\[ \t\]\[ \t\]*#4" 1 } } */ + +#pragma interrupt +void isr (void) __attribute__ ((trap_exit (4))); + +void +isr (void) +{ +} + +void +delay (int a) +{ +} + +int +main (void) +{ + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-trapa.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-trapa.c new file mode 100644 index 0000000..cc57014 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-trapa.c @@ -0,0 +1,19 @@ +/* Check that no interrupt-specific register saves are generated. */ +/* { dg-do compile { target { { "sh*-*-*" } && nonpic } } } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-options "-O" } */ +/* { dg-final { scan-assembler-times "rte" 1 } } */ +/* { dg-final { scan-assembler-not "r\[0-7\]\[ \t,\]\[^\n\]*r15" } } */ +/* { dg-final { scan-assembler-not "@r15\[^\n\]*r\[0-7\]\n" } } */ +/* { dg-final { scan-assembler-not "r\[8-9\]" } } */ +/* { dg-final { scan-assembler-not "r1\[,0-3\]" } } */ +/* { dg-final { scan-assembler-not "macl" } } */ + +extern void foo (void); + +#pragma trapa +void +isr (void) +{ + foo (); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-trapa2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-trapa2.c new file mode 100644 index 0000000..9a23b97 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/pragma-isr-trapa2.c @@ -0,0 +1,24 @@ +/* Check that no interrupt-specific register saves are generated. + The function call will require to load the address first into a register, + then use that for a jsr or jmp. It will also need to load a constant + address in order to load fpscr. */ +/* { dg-do compile { target { { "sh*-*-*" } && nonpic } } } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-options "-O" } */ +/* { dg-final { scan-assembler-times "rte" 1 } } */ +/* { dg-final { scan-assembler-times "r\[0-7\]\n" 3 } } */ +/* { dg-final { scan-assembler-not "r\[8-9\]" } } */ +/* { dg-final { scan-assembler-not "r1\[,0-3\]" } } */ +/* { dg-final { scan-assembler-not "macl" } } */ + +/* Expect that fpscr needs to be saved, loaded and restored. */ +/* { dg-final { scan-assembler-times "\[^_\]fpscr" 3 } } */ + +extern void foo (void); + +#pragma trapa +void +isr (void) +{ + foo (); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/prefetch.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/prefetch.c new file mode 100644 index 0000000..fb580bd --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/prefetch.c @@ -0,0 +1,35 @@ +/* Testcase to check generation of a SH4 and SH2A operand cache prefetch + instruction PREF @Rm. */ +/* { dg-do assemble } */ +/* { dg-options "-O0" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" "-m3*" "-m4*" } } */ +/* { dg-final { scan-assembler "pref"} } */ + +void +opt (void) +{ + int *p, wk; + int data[100]; + + /* data prefetch , instructions hit the cache. */ + + __builtin_prefetch (&data[0], 0, 0); + __builtin_prefetch (&data[0], 0, 1); + __builtin_prefetch (&data[0], 0, 2); + __builtin_prefetch (&data[0], 0, 3); + __builtin_prefetch (&data[0], 1, 0); + __builtin_prefetch (&data[0], 1, 1); + __builtin_prefetch (&data[0], 1, 2); + __builtin_prefetch (&data[0], 1, 3); + + + for (p = &data[0]; p < &data[9]; p++) + { + if (*p > *(p + 1)) + { + wk = *p; + *p = *(p + 1); + *(p + 1) = wk; + } + } +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/rte-delay-slot.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/rte-delay-slot.c new file mode 100644 index 0000000..48f1b13 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/rte-delay-slot.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m1 -m2*" } */ +/* { dg-final { scan-assembler-not "\trte\t\n\tmov.l\t@r15\\+" } } */ + +/* This test checks if the compiler generates a pop instruction + in the delay slot after rte. For the sh and sh2, the rte + instruction reads the return pc from the stack and any pop + in the delay slot crashes the hardware. + + Incorrect code generated + mov.l @r15+,r1 + rte + mov.l @r15+,r14 + + The right code should be + + mov.l @r15+,r1 + mov.l @r15+,r14 + rte + nop +*/ +void INT_MTU2_1_TGIA1 (void) + __attribute__ ((interrupt_handler)); +void +INT_MTU2_1_TGIA1 (void) +{ + volatile int i = 0; + volatile int x, y; + + for (i = 0; i < 10; i++) + y = y + x; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh-relax-vxworks.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh-relax-vxworks.c new file mode 100644 index 0000000..f8c2ffe --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh-relax-vxworks.c @@ -0,0 +1,5 @@ +/* Check that -mrelax produces the correct error message. */ +/* { dg-do compile { target { sh-*-vxworks* && nonpic } } } */ +/* { dg-error "-mrelax is only supported for RTP PIC" "" { target *-*-* } 0 } */ +/* { dg-options "-O1 -mrelax" } */ +int x; diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh-relax.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh-relax.c new file mode 100644 index 0000000..54422de --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh-relax.c @@ -0,0 +1,41 @@ +/* Check that -mrelax works. */ +/* { dg-do run { target { { sh-*-* sh?-*-* } && { ! { sh*-*-vxworks* && nonpic } } } } } */ +/* { dg-options "-O1 -mrelax" } */ + +extern void abort (void); +extern int qwerty (int); + +int +f (int i) +{ + return qwerty (i) + 1; +} + +int +qwerty (int i) +{ + switch (i) + { + case 1: + return 'q'; + case 2: + return 'w'; + case 3: + return 'e'; + case 4: + return 'r'; + case 5: + return 't'; + case 6: + return 'y'; + } +} + +int +main () +{ + if (f (1) != 'q' + 1 || f (2) != 'w' + 1 || f (3) != 'e' + 1 + || f(4) != 'r' + 1 || f (5) != 't' + 1 || f (6) != 'y' + 1) + abort (); + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh.exp b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh.exp new file mode 100644 index 0000000..ac428cd --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh.exp @@ -0,0 +1,41 @@ +# Copyright (C) 2007-2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a sh target. +if ![istarget sh*-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-band.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-band.c new file mode 100644 index 0000000..a509626 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-band.c @@ -0,0 +1,91 @@ +/* Testcase to check generation of a SH2A specific instruction for + "BAND.B #imm3, @(disp12, Rn)". */ +/* { dg-do assemble } */ +/* { dg-options "-O1 -mbitops" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "band.b"} } */ + +volatile struct +{ + union + { + unsigned char BYTE; + struct + { + unsigned char BIT7:1; + unsigned char BIT6:1; + unsigned char BIT5:1; + unsigned char BIT4:1; + unsigned char BIT3:1; + unsigned char BIT2:1; + unsigned char BIT1:1; + unsigned char BIT0:1; + } + BIT; + } + ICR0; +} +USRSTR; + +volatile union t_IOR +{ + unsigned short WORD; + struct + { + unsigned char IOR15:1; + unsigned char IOR14:1; + unsigned char IOR13:1; + unsigned char IOR12:1; + unsigned char IOR11:1; + unsigned char IOR10:1; + unsigned char IOR9:1; + unsigned char IOR8:1; + unsigned char IOR7:1; + unsigned char IOR6:1; + unsigned char IOR5:1; + unsigned char IOR4:1; + unsigned char IOR3:1; + unsigned char IOR2:1; + unsigned char IOR1:1; + unsigned char IOR0:1; + } + BIT; +} +PORT; + +int +main () +{ + volatile unsigned char a; + + /* Instruction generated is BAND.B #imm3, @(disp12, Rn) */ + USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 & USRSTR.ICR0.BIT.BIT1; + USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 & USRSTR.ICR0.BIT.BIT6; + USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT4; + USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 & USRSTR.ICR0.BIT.BIT3; + + a = USRSTR.ICR0.BIT.BIT0 & USRSTR.ICR0.BIT.BIT1; + a = USRSTR.ICR0.BIT.BIT5 & USRSTR.ICR0.BIT.BIT7; + a = USRSTR.ICR0.BIT.BIT2 & USRSTR.ICR0.BIT.BIT6; + + PORT.BIT.IOR13 = PORT.BIT.IOR0 & USRSTR.ICR0.BIT.BIT7; + PORT.BIT.IOR15 = PORT.BIT.IOR6 & USRSTR.ICR0.BIT.BIT2; + PORT.BIT.IOR3 = PORT.BIT.IOR2 & USRSTR.ICR0.BIT.BIT5; + PORT.BIT.IOR1 = PORT.BIT.IOR13 & USRSTR.ICR0.BIT.BIT1; + + PORT.BIT.IOR1 = PORT.BIT.IOR2 & USRSTR.ICR0.BIT.BIT1; + PORT.BIT.IOR11 = PORT.BIT.IOR9 & USRSTR.ICR0.BIT.BIT2; + PORT.BIT.IOR8 = PORT.BIT.IOR14 & USRSTR.ICR0.BIT.BIT5; + + PORT.BIT.IOR10 &= USRSTR.ICR0.BIT.BIT1; + PORT.BIT.IOR1 &= USRSTR.ICR0.BIT.BIT2; + PORT.BIT.IOR5 &= USRSTR.ICR0.BIT.BIT5; + PORT.BIT.IOR14 &= USRSTR.ICR0.BIT.BIT4; + + /* Instruction generated on using size optimization option "-Os". */ + a = a & USRSTR.ICR0.BIT.BIT1; + a = a & USRSTR.ICR0.BIT.BIT4; + a = a & USRSTR.ICR0.BIT.BIT0; + + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bclr.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bclr.c new file mode 100644 index 0000000..ab1e3dd --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bclr.c @@ -0,0 +1,57 @@ +/* Testcase to check generation of a SH2A specific instruction + 'BCLR #imm3,Rn'. */ +/* { dg-do assemble } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "bclr"} } */ + +struct a +{ + char a, b; + short c; +}; + +/* This function generates the instruction "BCLR #imm3,Rn" only + on using optimization option "-O1" and above. */ + +int +a2 () +{ + volatile int j; + volatile static struct a x = {1, 66, ~1}, y = {1, 2, ~2}; + + if (j > 1) + return (x.a == y.a && (x.b & ~1) == y.b); + if (j > 2) + return (x.a == y.a && (x.b & ~2) == y.b); + if (j > 3) + return (x.a == y.a && (x.b & ~4) == y.b); + if (j > 4) + return (x.a == y.a && (x.b & ~8) == y.b); + if (j > 5) + return (x.a == y.a && (x.b & ~16) == y.b); + if (j > 6) + return (x.a == y.a && (x.b & ~32) == y.b); + if (j > 7) + return (x.a == y.a && (x.b & ~64) == y.b); + if (j > 8) + return (x.a == y.a && (x.b & ~128) == y.b); +} + +int +main () +{ + volatile unsigned char x; + + x &= 0xFE; + x &= 0xFD; + x &= 0xFB; + x &= 0xF7; + x &= 0xEF; + x &= 0xDF; + x &= 0xBF; + x &= 0x7F; + + if (!a2 ()) + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c new file mode 100644 index 0000000..9c99c59 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bclrmem.c @@ -0,0 +1,55 @@ +/* Testcase to check generation of a SH2A specific instruction + "BCLR #imm3,@(disp12,Rn)". */ +/* { dg-do assemble } */ +/* { dg-options "-O2 -mbitops" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "bclr"} } */ +/* { dg-final { scan-assembler "bclr.b"} } */ + +volatile union un_paddr +{ + unsigned char BYTE; + struct + { + unsigned char B15:1; + unsigned char B14:1; + unsigned char B13:1; + unsigned char B12:1; + unsigned char B11:1; + unsigned char B10:1; + unsigned char B9:1; + unsigned char B8:1; + unsigned char B7:1; + unsigned char B6:1; + unsigned char B5:1; + unsigned char B4:1; + unsigned char B3:1; + unsigned char B2:1; + unsigned char B1:1; + unsigned char B0:1; + } + BIT; +} +PADDR; + +int +main () +{ + PADDR.BIT.B0 = 0; + PADDR.BIT.B3 = 0; + PADDR.BIT.B6 = 0; + + PADDR.BIT.B1 &= 0; + PADDR.BIT.B4 &= 0; + PADDR.BIT.B7 &= 0; + + PADDR.BIT.B10 = 0; + PADDR.BIT.B13 = 0; + PADDR.BIT.B15 = 0; + + PADDR.BIT.B9 &= 0; + PADDR.BIT.B12 &= 0; + PADDR.BIT.B14 &= 0; + + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bld.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bld.c new file mode 100644 index 0000000..d0c74c9 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bld.c @@ -0,0 +1,43 @@ +/* A testcase to check generation of the following SH2A specific + instructions. + + BLD #imm3, Rn + BLD.B #imm3, @(disp12, Rn) + */ +/* { dg-do assemble } */ +/* { dg-options "-Os -mbitops" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "bld"} } */ +/* { dg-final { scan-assembler "bld.b"} } */ + +volatile struct +{ + union + { + unsigned char BYTE; + struct + { + unsigned char BIT7:1; + unsigned char BIT6:1; + unsigned char BIT5:1; + unsigned char BIT4:1; + unsigned char BIT3:1; + unsigned char BIT2:1; + unsigned char BIT1:1; + unsigned char BIT0:1; + } + BIT; + } + ICR0; +} +USRSTR; + +int +main () +{ + volatile unsigned char a, b, c; + USRSTR.ICR0.BIT.BIT6 &= a; + USRSTR.ICR0.BIT.BIT5 |= b; + USRSTR.ICR0.BIT.BIT4 ^= c; + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bor.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bor.c new file mode 100644 index 0000000..8db4377 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bor.c @@ -0,0 +1,91 @@ +/* Testcase to check generation of a SH2A specific instruction for + "BOR.B #imm3, @(disp12, Rn)". */ +/* { dg-do assemble } */ +/* { dg-options "-O1 -mbitops" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "bor.b"} } */ + +volatile struct +{ + union + { + unsigned char BYTE; + struct + { + unsigned char BIT7:1; + unsigned char BIT6:1; + unsigned char BIT5:1; + unsigned char BIT4:1; + unsigned char BIT3:1; + unsigned char BIT2:1; + unsigned char BIT1:1; + unsigned char BIT0:1; + } + BIT; + } + ICR0; +} +USRSTR; + +volatile union t_IOR +{ + unsigned short WORD; + struct + { + unsigned char IOR15:1; + unsigned char IOR14:1; + unsigned char IOR13:1; + unsigned char IOR12:1; + unsigned char IOR11:1; + unsigned char IOR10:1; + unsigned char IOR9:1; + unsigned char IOR8:1; + unsigned char IOR7:1; + unsigned char IOR6:1; + unsigned char IOR5:1; + unsigned char IOR4:1; + unsigned char IOR3:1; + unsigned char IOR2:1; + unsigned char IOR1:1; + unsigned char IOR0:1; + } + BIT; +} +PORT; + +int +main () +{ + volatile unsigned char a; + + /* Instruction generated is BOR.B #imm3, @(disp12, Rn) */ + USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 | USRSTR.ICR0.BIT.BIT1; + USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 | USRSTR.ICR0.BIT.BIT6; + USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT4; + USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 | USRSTR.ICR0.BIT.BIT3; + + a = USRSTR.ICR0.BIT.BIT0 | USRSTR.ICR0.BIT.BIT1; + a = USRSTR.ICR0.BIT.BIT5 | USRSTR.ICR0.BIT.BIT7; + a = USRSTR.ICR0.BIT.BIT2 | USRSTR.ICR0.BIT.BIT6; + + PORT.BIT.IOR13 = PORT.BIT.IOR0 | USRSTR.ICR0.BIT.BIT7; + PORT.BIT.IOR15 = PORT.BIT.IOR6 | USRSTR.ICR0.BIT.BIT2; + PORT.BIT.IOR3 = PORT.BIT.IOR2 | USRSTR.ICR0.BIT.BIT5; + PORT.BIT.IOR1 = PORT.BIT.IOR13 | USRSTR.ICR0.BIT.BIT1; + + PORT.BIT.IOR1 = PORT.BIT.IOR2 | USRSTR.ICR0.BIT.BIT1; + PORT.BIT.IOR11 = PORT.BIT.IOR9 | USRSTR.ICR0.BIT.BIT2; + PORT.BIT.IOR8 = PORT.BIT.IOR14 | USRSTR.ICR0.BIT.BIT5; + + PORT.BIT.IOR10 |= USRSTR.ICR0.BIT.BIT1; + PORT.BIT.IOR1 |= USRSTR.ICR0.BIT.BIT2; + PORT.BIT.IOR5 |= USRSTR.ICR0.BIT.BIT5; + PORT.BIT.IOR14 |= USRSTR.ICR0.BIT.BIT4; + + /* Instruction generated on using size optimization option "-Os". */ + a = a & USRSTR.ICR0.BIT.BIT1; + a = a & USRSTR.ICR0.BIT.BIT4; + a = a & USRSTR.ICR0.BIT.BIT0; + + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bset.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bset.c new file mode 100644 index 0000000..322821b --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bset.c @@ -0,0 +1,57 @@ +/* Testcase to check generation of a SH2A specific instruction + 'BSET #imm3,Rn'. */ +/* { dg-do assemble } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "bset"} } */ + +struct a +{ + char a, b; + short c; +}; + +/* This function generates the instruction "BSET #imm3,Rn" only + on using optimization option "-O1" and above. */ + +int +a2 () +{ + volatile int j; + volatile static struct a x = {1, 66, ~1}, y = {1, 2, ~2}; + + if (j > 1) + return (x.a == y.a && (x.b | 1) == y.b); + if (j > 2) + return (x.a == y.a && (x.b | 2) == y.b); + if (j > 3) + return (x.a == y.a && (x.b | 4) == y.b); + if (j > 4) + return (x.a == y.a && (x.b | 8) == y.b); + if (j > 5) + return (x.a == y.a && (x.b | 16) == y.b); + if (j > 6) + return (x.a == y.a && (x.b | 32) == y.b); + if (j > 7) + return (x.a == y.a && (x.b | 64) == y.b); + if (j > 8) + return (x.a == y.a && (x.b | 128) == y.b); +} + +int +main () +{ + volatile unsigned char x; + + x |= 0x1; + x |= 0x2; + x |= 0x4; + x |= 0x8; + x |= 0x16; + x |= 0x32; + x |= 0x64; + x |= 0x128; + + if (!a2 ()) + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c new file mode 100644 index 0000000..cf35ed6 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bsetmem.c @@ -0,0 +1,55 @@ +/* Testcase to check generation of a SH2A specific instruction + "BSET #imm3,@(disp12,Rn)". */ +/* { dg-do assemble } */ +/* { dg-options "-O2 -mbitops" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "bset"} } */ +/* { dg-final { scan-assembler "bset.b"} } */ + +volatile union un_paddr +{ + unsigned char BYTE; + struct + { + unsigned char B15:1; + unsigned char B14:1; + unsigned char B13:1; + unsigned char B12:1; + unsigned char B11:1; + unsigned char B10:1; + unsigned char B9:1; + unsigned char B8:1; + unsigned char B7:1; + unsigned char B6:1; + unsigned char B5:1; + unsigned char B4:1; + unsigned char B3:1; + unsigned char B2:1; + unsigned char B1:1; + unsigned char B0:1; + } + BIT; +} +PADDR; + +int +main () +{ + PADDR.BIT.B0 = 1; + PADDR.BIT.B3 = 1; + PADDR.BIT.B6 = 1; + + PADDR.BIT.B1 |= 1; + PADDR.BIT.B4 |= 1; + PADDR.BIT.B7 |= 1; + + PADDR.BIT.B10 = 1; + PADDR.BIT.B13 = 1; + PADDR.BIT.B15 = 1; + + PADDR.BIT.B9 |= 1; + PADDR.BIT.B12 |= 1; + PADDR.BIT.B14 |= 1; + + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bxor.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bxor.c new file mode 100644 index 0000000..6cca825 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-bxor.c @@ -0,0 +1,91 @@ +/* Testcase to check generation of a SH2A specific instruction for + "BXOR.B #imm3, @(disp12, Rn)". */ +/* { dg-do assemble } */ +/* { dg-options "-O1 -mbitops" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "bxor.b"} } */ + +volatile struct +{ + union + { + unsigned char BYTE; + struct + { + unsigned char BIT7:1; + unsigned char BIT6:1; + unsigned char BIT5:1; + unsigned char BIT4:1; + unsigned char BIT3:1; + unsigned char BIT2:1; + unsigned char BIT1:1; + unsigned char BIT0:1; + } + BIT; + } + ICR0; +} +USRSTR; + +volatile union t_IOR +{ + unsigned short WORD; + struct + { + unsigned char IOR15:1; + unsigned char IOR14:1; + unsigned char IOR13:1; + unsigned char IOR12:1; + unsigned char IOR11:1; + unsigned char IOR10:1; + unsigned char IOR9:1; + unsigned char IOR8:1; + unsigned char IOR7:1; + unsigned char IOR6:1; + unsigned char IOR5:1; + unsigned char IOR4:1; + unsigned char IOR3:1; + unsigned char IOR2:1; + unsigned char IOR1:1; + unsigned char IOR0:1; + } + BIT; +} +PORT; + +int +main () +{ + volatile unsigned char a; + + /* Instruction generated is BXOR.B #imm3, @(disp12, Rn) */ + USRSTR.ICR0.BIT.BIT3 = USRSTR.ICR0.BIT.BIT4 ^ USRSTR.ICR0.BIT.BIT1; + USRSTR.ICR0.BIT.BIT2 = USRSTR.ICR0.BIT.BIT6 ^ USRSTR.ICR0.BIT.BIT6; + USRSTR.ICR0.BIT.BIT4 = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT4; + USRSTR.ICR0.BIT.BIT6 = USRSTR.ICR0.BIT.BIT1 ^ USRSTR.ICR0.BIT.BIT3; + + a = USRSTR.ICR0.BIT.BIT0 ^ USRSTR.ICR0.BIT.BIT1; + a = USRSTR.ICR0.BIT.BIT5 ^ USRSTR.ICR0.BIT.BIT7; + a = USRSTR.ICR0.BIT.BIT2 ^ USRSTR.ICR0.BIT.BIT6; + + PORT.BIT.IOR13 = PORT.BIT.IOR0 ^ USRSTR.ICR0.BIT.BIT7; + PORT.BIT.IOR15 = PORT.BIT.IOR6 ^ USRSTR.ICR0.BIT.BIT2; + PORT.BIT.IOR3 = PORT.BIT.IOR2 ^ USRSTR.ICR0.BIT.BIT5; + PORT.BIT.IOR1 = PORT.BIT.IOR13 ^ USRSTR.ICR0.BIT.BIT1; + + PORT.BIT.IOR1 = PORT.BIT.IOR2 ^ USRSTR.ICR0.BIT.BIT1; + PORT.BIT.IOR11 = PORT.BIT.IOR9 ^ USRSTR.ICR0.BIT.BIT2; + PORT.BIT.IOR8 = PORT.BIT.IOR14 ^ USRSTR.ICR0.BIT.BIT5; + + PORT.BIT.IOR10 ^= USRSTR.ICR0.BIT.BIT1; + PORT.BIT.IOR1 ^= USRSTR.ICR0.BIT.BIT2; + PORT.BIT.IOR5 ^= USRSTR.ICR0.BIT.BIT5; + PORT.BIT.IOR14 ^= USRSTR.ICR0.BIT.BIT4; + + /* Instruction generated on using size optimization option "-Os". */ + a = a ^ USRSTR.ICR0.BIT.BIT1; + a = a ^ USRSTR.ICR0.BIT.BIT4; + a = a ^ USRSTR.ICR0.BIT.BIT0; + + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-jsrn.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-jsrn.c new file mode 100644 index 0000000..3f55327 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-jsrn.c @@ -0,0 +1,15 @@ +/* Testcase to check generation of a SH2A specific instruction for + 'JSR/N @Rm'. */ +/* { dg-do assemble } */ +/* { dg-options "-O0" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "jsr/n"} } */ + +void foo(void) +{ +} + +void bar() +{ + foo(); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-movi20s.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-movi20s.c new file mode 100644 index 0000000..fe3226e --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-movi20s.c @@ -0,0 +1,14 @@ +/* Testcase to check generation of 'MOVI20S #imm20, Rn'. */ +/* { dg-do assemble } */ +/* { dg-options "-O0" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "movi20s"} } */ + +volatile long la; + +void +testfun (void) +{ + la = -134217728; + la = 134217216; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-movrt.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-movrt.c new file mode 100644 index 0000000..3e72930 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-movrt.c @@ -0,0 +1,15 @@ +/* Testcase to check generation of a SH2A specific instruction for + 'MOVRT Rn'. */ +/* { dg-do assemble } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "movrt"} } */ + +int +foo (void) +{ + int a, b, g, stop; + if (stop = ((a + b) % 2 != g)) + ; + return stop; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-resbank.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-resbank.c new file mode 100644 index 0000000..a12a711 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-resbank.c @@ -0,0 +1,12 @@ +/* Test for resbank attribute. */ +/* { dg-do assemble } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "resbank" } } */ + +extern void bar(void); + +void foo(void) __attribute__((interrupt_handler, resbank)); +void foo(void) +{ + bar(); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-rtsn.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-rtsn.c new file mode 100644 index 0000000..612c303 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-rtsn.c @@ -0,0 +1,11 @@ +/* Testcase to check generation of a SH2A specific instruction for + 'RTS/N'. */ +/* { dg-do assemble } */ +/* { dg-options "-O0" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler "rts/n"} } */ + +void +bar (void) +{ +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-tbr-jump.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-tbr-jump.c new file mode 100644 index 0000000..24b57fe --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh2a-tbr-jump.c @@ -0,0 +1,22 @@ +/* Testcase to check generation of a SH2A specific, + TBR relative jump instruction - 'JSR @@(disp8,TBR)'. */ +/* { dg-do assemble } */ +/* { dg-options "" } */ +/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */ +/* { dg-final { scan-assembler-times "jsr/n\\t@@\\(40,tbr\\)" 1} } */ +/* { dg-final { scan-assembler-times "jsr/n\\t@@\\(72,tbr\\)" 1} } */ + +extern void foo1 (void) __attribute__ ((function_vector(10))); +extern void foo2 (void); +extern int bar1 (void) __attribute__ ((function_vector(18))); +extern int bar2 (void); + +int +bar() +{ + foo1(); + foo2(); + + bar1(); + bar2(); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-bitmovua.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-bitmovua.c new file mode 100644 index 0000000..35ebf5c --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-bitmovua.c @@ -0,0 +1,91 @@ +/* Verify that we generate movua to load unaligned 32-bit values on SH4A. */ +/* { dg-do run } */ +/* { dg-options "-O1 -save-temps -fno-inline" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m4a*" } } */ +/* { dg-final { scan-assembler-times "movua.l" 6 } } */ + +/* Aligned. */ +struct s0 { long long d : 32; } x0; +long long f0() { + return x0.d; +} + +/* Unaligned load. */ +struct s1 { long long c : 8; long long d : 32; } x1; +long long f1() { + return x1.d; +} + +/* Unaligned load. */ +struct s2 { long long c : 16; long long d : 32; } x2; +long long f2() { + return x2.d; +} + +/* Unaligned load. */ +struct s3 { long long c : 24; long long d : 32; } x3; +long long f3() { + return x3.d; +} + +/* Aligned. */ +struct s4 { long long c : 32; long long d : 32; } x4; +long long f4() { + return x4.d; +} + +/* Aligned. */ +struct u0 { unsigned long long d : 32; } y_0; +unsigned long long g0() { + return y_0.d; +} + +/* Unaligned load. */ +struct u1 { long long c : 8; unsigned long long d : 32; } y_1; +unsigned long long g1() { + return y_1.d; +} + +/* Unaligned load. */ +struct u2 { long long c : 16; unsigned long long d : 32; } y2; +unsigned long long g2() { + return y2.d; +} + +/* Unaligned load. */ +struct u3 { long long c : 24; unsigned long long d : 32; } y3; +unsigned long long g3() { + return y3.d; +} + +/* Aligned. */ +struct u4 { long long c : 32; unsigned long long d : 32; } y4; +unsigned long long g4() { + return y4.d; +} + +#include <assert.h> + +int +main (void) +{ + x1.d = 0x12345678; + assert (f1 () == 0x12345678); + + x2.d = 0x12345678; + assert (f2 () == 0x12345678); + + x3.d = 0x12345678; + assert (f3 () == 0x12345678); + + y_1.d = 0x12345678; + assert (g1 () == 0x12345678); + + y2.d = 0x12345678; + assert (g2 () == 0x12345678); + + y3.d = 0x12345678; + assert (g3 () == 0x12345678); + + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-cosf.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-cosf.c new file mode 100644 index 0000000..d6277da --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-cosf.c @@ -0,0 +1,11 @@ +/* Verify that we generate single-precision sine and cosine approximate + (fsca) in fast math mode on SH4A with FPU. */ +/* { dg-do compile } */ +/* { dg-options "-O -ffast-math" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m4a" "-m4a-single" "-m4a-single-only" } } */ +/* { dg-final { scan-assembler "fsca" } } */ + +#include <math.h> + +float test(float f) { return cosf(f); } + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-fprun.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-fprun.c new file mode 100644 index 0000000..e5fbc4a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-fprun.c @@ -0,0 +1,55 @@ +/* Verify that fsca and fssra yield reasonable results. */ +/* This test calls the sinf and cosf library functions for targets other + than sh4a, but the VxWorks kernel doesn't have those functions. */ +/* { dg-do run { target { "sh*-*-*" && { ! vxworks_kernel } } } } */ +/* { dg-options "-O -ffast-math" } */ + +#include <math.h> +#include <stdlib.h> + +float sqrt_arg = 4.0f, sqrt_res = 2.0f; +float dg2rad_f; +double dg2rad_d; + +float __attribute__ ((noinline)) +test_sinf (float x) +{ + return sinf (x); +} + +float __attribute ((noinline)) +test_cosf (float x) +{ + return cosf (x); +} + +void +check_f (float res, float expected) +{ + if (res >= expected - 0.001f && res <= expected + 0.001f) + return; + + abort (); +} + +void +check_d (double res, double expected) +{ + if (res >= expected - 0.001 && res <= expected + 0.001) + return; + + abort (); +} + +int +main() +{ + check_f (sqrtf(sqrt_arg), sqrt_res); + dg2rad_f = dg2rad_d = atan(1) / 45; + check_f (test_sinf(90*dg2rad_f), 1); + check_f (test_cosf(90*dg2rad_f), 0); + check_d (sin(-90*dg2rad_d), -1); + check_d (cos(180*dg2rad_d), -1); + check_d (sin(-45*dg2rad_d) * cosf(135*dg2rad_f), 0.5); + exit (0); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-fsrra.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-fsrra.c new file mode 100644 index 0000000..0bd7d87 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-fsrra.c @@ -0,0 +1,11 @@ +/* Verify that we generate single-precision square root reciprocal + approximate (fsrra) in fast math mode on SH4A with FPU. */ +/* { dg-do compile } */ +/* { dg-options "-O -ffast-math" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m4a" "-m4a-single" "-m4a-single-only" } } */ +/* { dg-final { scan-assembler "fsrra" } } */ + +#include <math.h> + +float test(float f) { return 1 / sqrtf(f); } + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-memmovua.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-memmovua.c new file mode 100644 index 0000000..7e817c4 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-memmovua.c @@ -0,0 +1,14 @@ +/* Verify that we generate movua to copy unaligned memory regions to + 32-bit-aligned addresses on SH4A. */ +/* { dg-do compile { target "sh*-*-*" } } */ +/* { dg-options "-O" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m4a" "-m4a-single" "-m4a-single-only" "-m4a-nofpu" } } */ +/* { dg-final { scan-assembler-times "movua.l" 2 } } */ + +#include <string.h> + +struct s { int i; char a[10], b[10]; } x; +int f() { + memcpy(x.a, x.b, 10); +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-sincosf.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-sincosf.c new file mode 100644 index 0000000..b85fa86 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-sincosf.c @@ -0,0 +1,12 @@ +/* Verify that we generate a single single-precision sine and cosine + approximate (fsca) in fast math mode when a function computes both + sine and cosine. */ +/* { dg-do compile } */ +/* { dg-options "-O -ffast-math" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m4a" "-m4a-single" "-m4a-single-only" } } */ +/* { dg-final { scan-assembler-times "fsca" 1 } } */ + +#include <math.h> + +float test(float f) { return sinf(f) + cosf(f); } + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-sinf.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-sinf.c new file mode 100644 index 0000000..0ce1326 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sh4a-sinf.c @@ -0,0 +1,11 @@ +/* Verify that we generate single-precision sine and cosine approximate + (fsca) in fast math mode on SH4A with FPU. */ +/* { dg-do compile } */ +/* { dg-options "-O -ffast-math" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m4a" "-m4a-single" "-m4a-single-only" } } */ +/* { dg-final { scan-assembler "fsca" } } */ + +#include <math.h> + +float test(float f) { return sinf(f); } + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/sp-switch.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/sp-switch.c new file mode 100644 index 0000000..aad6ba0 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/sp-switch.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-final { scan-assembler "mov\tr0,r15" } } */ +/* { dg-final { scan-assembler ".long\t_alt_stack" } } */ + +void *alt_stack; +void f() __attribute__ ((interrupt_handler, sp_switch ("alt_stack"))); + +void f() +{ +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/strlen.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/strlen.c new file mode 100644 index 0000000..115baba --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/strlen.c @@ -0,0 +1,19 @@ +/* Check that the __builtin_strlen function is inlined with cmp/str + when optimizing for speed. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "jmp" } } */ +/* { dg-final { scan-assembler-times "cmp/str" 2 } } */ +/* { dg-final { scan-assembler-times "tst\t#3" 1 } } */ + +test00 (const char *s1) +{ + return __builtin_strlen (s1); +} + +/* Check that no test for alignment is needed. */ +test03(const char *s1) +{ + return __builtin_strlen (__builtin_assume_aligned (s1, 4)); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/struct-arg-dw2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/struct-arg-dw2.c new file mode 100644 index 0000000..50c8f34 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/struct-arg-dw2.c @@ -0,0 +1,26 @@ +/* Verify that we don't generate frame related insn against stack adjustment + for the object sent partially in registers. */ +/* { dg-do compile } */ +/* { dg-options "-g" } */ +/* { dg-final { scan-assembler-not "\t.cfi_def_cfa_offset 16" } } */ + +typedef struct +{ + unsigned short A1; + unsigned short A2; +} A_t; + +typedef struct +{ + A_t C13[10]; +} C_t; + +void +Store (C_t Par) +{ + unsigned char *ptr; + unsigned int test; + + ptr = (unsigned char*) 0x12345678; + ptr++; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr30807.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr30807.c new file mode 100644 index 0000000..c9cc771 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr30807.c @@ -0,0 +1,218 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fpic -std=c99" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ + +typedef unsigned int size_t; +typedef struct +{ + unsigned long __val[(1024 / (8 * sizeof (unsigned long)))]; +} __sigset_t; +struct __jmp_buf_tag +{ + __sigset_t __saved_mask; +}; +typedef struct __jmp_buf_tag sigjmp_buf[1]; +struct stat +{ + long long st_dev; + unsigned short int __pad1; + int tm_isdst; + long int tm_gmtoff; + char *tm_zone; +}; + +typedef size_t STRLEN; +typedef struct op OP; +typedef struct cop COP; +typedef struct interpreter PerlInterpreter; +typedef struct sv SV; +typedef struct av AV; +typedef struct cv CV; +typedef struct gp GP; +typedef struct gv GV; +typedef struct xpv XPV; +typedef struct xpvio XPVIO; +typedef union any ANY; +typedef unsigned char U8; +typedef long I32; +typedef unsigned long U32; +typedef U32 line_t; +typedef struct _PerlIO PerlIOl; +typedef PerlIOl *PerlIO; +struct sv +{ + void *sv_any; + U32 sv_flags; + union + { + char *svu_pv; + } sv_u; +}; +struct gv +{ + U32 sv_flags; + union + { + GP *svu_gp; + } sv_u; +}; +struct io +{ + XPVIO *sv_any; +}; +struct xpv +{ + STRLEN xpv_cur; +}; +struct xpvio +{ + PerlIO *xio_ofp; +}; +struct gp +{ + SV *gp_sv; + struct io *gp_io; +}; +struct jmpenv +{ + struct jmpenv *je_prev; + sigjmp_buf je_buf; + int je_ret; +}; +typedef struct jmpenv JMPENV; +struct cop +{ + line_t cop_line; + struct refcounted_he *cop_hints_hash; +}; +struct interpreter +{ + SV **Istack_sp; + OP *Iop; + SV **Icurpad; + SV **Istack_base; + SV **Istack_max; + I32 *Iscopestack; + I32 Iscopestack_ix; + I32 Iscopestack_max; + ANY *Isavestack; + I32 Isavestack_ix; + I32 Isavestack_max; + SV **Itmps_stack; + I32 Itmps_ix; + I32 Itmps_floor; + I32 Itmps_max; + I32 Imodcount; + I32 *Imarkstack; + I32 *Imarkstack_ptr; + I32 *Imarkstack_max; + SV *ISv; + XPV *IXpv; + STRLEN Ina; + struct stat Istatbuf; + struct stat Istatcache; + OP *Irestartop; + COP *volatile Icurcop; + JMPENV *Itop_env; + U8 Iexit_flags; + I32 Istatusvalue; + I32 Istatusvalue_posix; + GV *Istderrgv; + GV *Ierrgv; + AV *Ibeginav; + AV *Iunitcheckav; + COP Icompiling; + char Isavebegin; + volatile U32 Idebug; + AV *Ibeginav_save; + AV *Icheckav_save; + AV *Iunitcheckav_save; +}; + +void S_my_exit_jump (PerlInterpreter *my_perl __attribute__((unused))) + __attribute__((noreturn)); + +int Perl_av_len (PerlInterpreter*, AV*); +void Perl_av_create_and_push (PerlInterpreter*, AV**, SV*); +int __sigsetjmp (sigjmp_buf env, int savemask); +void Perl_sv_2pv_flags (PerlInterpreter*, SV*, STRLEN*, int); +void Perl_deb (PerlInterpreter*, + const char*, const char*, int, const char*, int); +void Perl_croak (PerlInterpreter*, const char*, void*); +void foo (void); + +void +Perl_call_list (PerlInterpreter *my_perl __attribute__((unused)), + I32 oldscope, AV *paramList) +{ + SV *atsv; + CV *cv; + STRLEN len; + int ret; + JMPENV cur_env; + GV *shplep; + volatile line_t oldline; + + oldline = (my_perl->Icurcop) ? my_perl->Icurcop->cop_line : 0; + + while (Perl_av_len (my_perl, paramList) >= 0) + { + if (my_perl->Isavebegin) + { + if (paramList == my_perl->Ibeginav) + { + Perl_av_create_and_push (my_perl, &my_perl->Ibeginav_save, + (SV*) cv); + Perl_av_create_and_push(my_perl, &my_perl->Icheckav_save, + (SV*) cv); + } + else if (paramList == my_perl->Iunitcheckav) + Perl_av_create_and_push(my_perl, &my_perl->Iunitcheckav_save, + (SV*) cv); + } + + cur_env.je_ret = __sigsetjmp (cur_env.je_buf, 0); + + switch (ret) + { + case 0: + shplep = (GV *) my_perl->Ierrgv; + *my_perl->Imarkstack_ptr = my_perl->Istack_sp - my_perl->Istack_base; + atsv = shplep->sv_u.svu_gp->gp_sv; + if (atsv->sv_flags & 0x00000400 == 0x00000400) + len = ((XPV*) ((SV *) atsv)->sv_any)->xpv_cur; + else + Perl_sv_2pv_flags (my_perl, atsv, &len, 2|32); + + if (len) + { + my_perl->Icurcop = &my_perl->Icompiling; + while (my_perl->Iscopestack_ix > oldscope) + { + if (my_perl->Idebug & 0x00000004) + Perl_deb (my_perl, "scope", "LEAVE", + my_perl->Iscopestack_ix, "perl.c", 5166); + (my_perl->Itop_env) = cur_env.je_prev; + } + + Perl_croak (my_perl, "%""-p""", (void*) atsv); + } + + case 1: + my_perl->Istatusvalue = 1; + my_perl->Istatusvalue_posix = 1; + case 2: + while (my_perl->Iscopestack_ix > oldscope) + if (my_perl->Idebug & 0x00000004) + foo (); + my_perl->Icurcop = &my_perl->Icompiling; + my_perl->Icurcop->cop_line = oldline; + if (my_perl->Idebug & 0x00000004) + foo (); + S_my_exit_jump (my_perl); + case 3: + if (my_perl->Irestartop) + foo (); + } + } +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr34777.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr34777.c new file mode 100644 index 0000000..de6ba02 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr34777.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fschedule-insns -fPIC -mprefergot" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ + +static __inline __attribute__ ((__always_inline__)) void * +_dl_mmap (void * start, int length, int prot, int flags, int fd, + int offset) +{ + register long __sc3 __asm__ ("r3") = 90; + register long __sc4 __asm__ ("r4") = (long) start; + register long __sc5 __asm__ ("r5") = (long) length; + register long __sc6 __asm__ ("r6") = (long) prot; + register long __sc7 __asm__ ("r7") = (long) flags; + register long __sc0 __asm__ ("r0") = (long) fd; + register long __sc1 __asm__ ("r1") = (long) offset; + __asm__ __volatile__ ("trapa %1" + : "=z" (__sc0) + : "i" (0x10 + 6), "0" (__sc0), "r" (__sc4), + "r" (__sc5), "r" (__sc6), "r" (__sc7), + "r" (__sc3), "r" (__sc1) + : "memory" ); +} + +extern int _dl_pagesize; +void +_dl_dprintf(int fd, const char *fmt, ...) +{ + static char *buf; + buf = _dl_mmap ((void *) 0, _dl_pagesize, 0x1 | 0x2, 0x02 | 0x20, -1, 0); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr58314.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr58314.c new file mode 100644 index 0000000..7a11508 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr58314.c @@ -0,0 +1,102 @@ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ + +typedef unsigned short __u16; +typedef unsigned int __u32; + +typedef signed short s16; + + +static inline __attribute__((always_inline)) __attribute__((__const__)) __u16 __arch_swab16(__u16 x) +{ + __asm__( + "swap.b %1, %0" + : "=r" (x) + : "r" (x)); + return x; +} + +void u16_add_cpu(__u16 *var) +{ + *var = __arch_swab16(*var); +} + +typedef struct xfs_mount { + int m_attr_magicpct; +} xfs_mount_t; + +typedef struct xfs_da_args { + struct xfs_mount *t_mountp; + int index; +} xfs_da_args_t; + +typedef struct xfs_dabuf { + void *data; +} xfs_dabuf_t; + +typedef struct xfs_attr_leaf_map { + __u16 base; + __u16 size; +} xfs_attr_leaf_map_t; +typedef struct xfs_attr_leaf_hdr { + __u16 count; + xfs_attr_leaf_map_t freemap[3]; +} xfs_attr_leaf_hdr_t; + +typedef struct xfs_attr_leaf_entry { + __u16 nameidx; +} xfs_attr_leaf_entry_t; + +typedef struct xfs_attr_leafblock { + xfs_attr_leaf_hdr_t hdr; + xfs_attr_leaf_entry_t entries[1]; +} xfs_attr_leafblock_t; + +int +xfs_attr_leaf_remove(xfs_attr_leafblock_t *leaf, xfs_da_args_t *args) +{ + xfs_attr_leaf_hdr_t *hdr; + xfs_attr_leaf_map_t *map; + xfs_attr_leaf_entry_t *entry; + int before, after, smallest, entsize; + int tablesize, tmp, i; + xfs_mount_t *mp; + hdr = &leaf->hdr; + mp = args->t_mountp; + + entry = &leaf->entries[args->index]; + + tablesize = __arch_swab16(hdr->count); + + map = &hdr->freemap[0]; + tmp = map->size; + before = after = -1; + smallest = 3 - 1; + entsize = xfs_attr_leaf_entsize(leaf, args->index); + + for (i = 0; i < 2; map++, i++) { + + if (map->base == tablesize) + u16_add_cpu(&map->base); + + if (__arch_swab16(map->base) + __arch_swab16(map->size) == __arch_swab16(entry->nameidx)) + before = i; + else if (map->base == entsize) + after = i; + else if (__arch_swab16(map->size) < tmp) + smallest = i; + } + + if (before >= 0) + { + map = &hdr->freemap[after]; + map->base = entry->nameidx; + + } + + map = &hdr->freemap[smallest]; + + map->base = __arch_swab16(entry->nameidx); + + return(tmp < mp->m_attr_magicpct); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr58475.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr58475.c new file mode 100644 index 0000000..f44780d --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pr58475.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +int +kerninfo(int __bsx, double tscale) +{ + return ( + (int)(__extension__ + ({ + ((((__bsx) & 0xff000000u) >> 24) + | (((__bsx) & 0x00ff0000) >> 8) + | (((__bsx) & 0x0000ff00) << 8) + | (((__bsx) & 0x000000ff) << 24) + ); })) + * tscale); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pragma-isr.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pragma-isr.c new file mode 100644 index 0000000..9e665ba --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pragma-isr.c @@ -0,0 +1,20 @@ +/* Check whether rte is generated for two ISRs. */ +/* { dg-do compile } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "rte" 2 } } */ + +extern void foo (void); + +#pragma interrupt +void +isr1 (void) +{ + foo (); +} + +#pragma interrupt +void +isr2 (void) +{ + foo (); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pragma-isr2.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pragma-isr2.c new file mode 100644 index 0000000..ce984e7 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/pragma-isr2.c @@ -0,0 +1,21 @@ +/* Check whether rte is generated only for an ISRs. */ +/* { dg-do compile } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "rte" 1 } } */ + +#pragma interrupt +void +isr (void) +{ +} + +void +delay (int a) +{ +} + +int +main (void) +{ + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/sh-torture.exp b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/sh-torture.exp new file mode 100644 index 0000000..8fef587 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/sh-torture.exp @@ -0,0 +1,41 @@ +# Copyright (C) 2012-2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `gcc-dg.exp' driver, looping over +# optimization options. + +# Exit immediately if this isn't a SH target. +if { ![istarget sh*-*-*] } then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/strncmp.c b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/strncmp.c new file mode 100644 index 0000000..cd50f5c --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/sh/torture/strncmp.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ + +extern void abort (void); + +const char *s="astc"; +const char *s1="-----BEGIN RSA PRIVATE KEY-----"; +const char *s2="atextaac"; + +main() +{ + if (! __builtin_strncmp ("astb", s, 4)) + abort(); + + if (__builtin_strncmp(s1, "-----BEGIN ", 11)) + abort(); + + if (! __builtin_strncmp ("atextaacb", s2, 9)) + abort(); + + return 0; +} + |