diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 78cccc82252..e2cd655971a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2013-03-13 Oleg Endo + + PR target/49880 + * config/sh/sh.opt (FPU_SINGLE_ONLY): New mask. + (musermode): Convert to Var(TARGET_USERMODE). + * config/sh/sh.h (SELECT_SH2A_SINGLE_ONLY, SELECT_SH4_SINGLE_ONLY, + MASK_ARCH): Add MASK_FPU_SINGLE_ONLY. + * config/sh/sh.c (sh_option_override): Use + TARGET_FPU_DOUBLE || TARGET_FPU_SINGLE_ONLY for call-fp case. + * config/sh/sh.md (udivsi3_i1, divsi3_i1): Remove ! TARGET_SH4 + condition. + (udivsi3_i4, divsi3_i4): Use TARGET_FPU_DOUBLE condition instead of + TARGET_SH4. + (udivsi3_i4_single, divsi3_i4_single): Use + TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE instead of TARGET_HARD_SH4. + 2013-03-13 Dave Korn * config/i386/cygwin.h (SHARED_LIBGCC_SPEC): Make shared libgcc the diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index dcbd93286ed..44e1e4ce30e 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -816,8 +816,7 @@ sh_option_override (void) if (! strcmp (sh_div_str, "call-div1")) sh_div_strategy = SH_DIV_CALL_DIV1; else if (! strcmp (sh_div_str, "call-fp") - && (TARGET_FPU_DOUBLE - || (TARGET_HARD_SH4 && TARGET_SH2E) + && (TARGET_FPU_DOUBLE || TARGET_FPU_SINGLE_ONLY || (TARGET_SHCOMPACT && TARGET_FPU_ANY))) sh_div_strategy = SH_DIV_CALL_FP; else if (! strcmp (sh_div_str, "call-table") && TARGET_DYNSHIFT) diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index ecd6c17e553..3744f980fe7 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -138,14 +138,16 @@ extern int code_for_indirect_jump_scratch; | MASK_SH2 | MASK_SH1) #define SELECT_SH2A_NOFPU (MASK_HARD_SH2A | MASK_SH2 | MASK_SH1) #define SELECT_SH2A_SINGLE_ONLY (MASK_SH_E | MASK_HARD_SH2A | MASK_SH2 \ - | MASK_SH1 | MASK_FPU_SINGLE) + | MASK_SH1 | MASK_FPU_SINGLE \ + | MASK_FPU_SINGLE_ONLY) #define SELECT_SH2A_SINGLE (MASK_SH_E | MASK_HARD_SH2A \ | MASK_FPU_SINGLE | MASK_HARD_SH2A_DOUBLE \ | MASK_SH2 | MASK_SH1) #define SELECT_SH3 (MASK_SH3 | SELECT_SH2) #define SELECT_SH3E (MASK_SH_E | MASK_FPU_SINGLE | SELECT_SH3) #define SELECT_SH4_NOFPU (MASK_HARD_SH4 | SELECT_SH3) -#define SELECT_SH4_SINGLE_ONLY (MASK_HARD_SH4 | SELECT_SH3E) +#define SELECT_SH4_SINGLE_ONLY (MASK_HARD_SH4 | SELECT_SH3E \ + | MASK_FPU_SINGLE_ONLY) #define SELECT_SH4 (MASK_SH4 | MASK_SH_E | MASK_HARD_SH4 \ | SELECT_SH3) #define SELECT_SH4_SINGLE (MASK_FPU_SINGLE | SELECT_SH4) @@ -212,7 +214,8 @@ extern int code_for_indirect_jump_scratch; /* Reset all target-selection flags. */ #define MASK_ARCH (MASK_SH1 | MASK_SH2 | MASK_SH3 | MASK_SH_E | MASK_SH4 \ | MASK_HARD_SH2A | MASK_HARD_SH2A_DOUBLE | MASK_SH4A \ - | MASK_HARD_SH4 | MASK_FPU_SINGLE | MASK_SH5) + | MASK_HARD_SH4 | MASK_FPU_SINGLE | MASK_SH5 \ + | MASK_FPU_SINGLE_ONLY) /* This defaults us to big-endian. */ #ifndef TARGET_ENDIAN_DEFAULT diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 75b102c3fa7..42ef5e142d8 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -2154,7 +2154,7 @@ (clobber (reg:SI PR_REG)) (clobber (reg:SI R4_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] - "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)" + "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]) @@ -2217,7 +2217,7 @@ (clobber (reg:SI R5_REG)) (use (reg:PSI FPSCR_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] - "TARGET_SH4 && ! TARGET_FPU_SINGLE" + "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "fp_mode" "double") @@ -2236,7 +2236,8 @@ (clobber (reg:SI R4_REG)) (clobber (reg:SI R5_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] - "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE" + "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT) + && TARGET_FPU_SINGLE" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]) @@ -2358,7 +2359,7 @@ (clobber (reg:SI R2_REG)) (clobber (reg:SI R3_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] - "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)" + "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]) @@ -2487,7 +2488,7 @@ (clobber (reg:DF DR2_REG)) (use (reg:PSI FPSCR_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] - "TARGET_SH4 && ! TARGET_FPU_SINGLE" + "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "fp_mode" "double") @@ -2501,7 +2502,8 @@ (clobber (reg:DF DR2_REG)) (clobber (reg:SI R2_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] - "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE" + "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT) + && TARGET_FPU_SINGLE" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]) diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt index 0ee36be45fa..c314e144c21 100644 --- a/gcc/config/sh/sh.opt +++ b/gcc/config/sh/sh.opt @@ -24,6 +24,10 @@ Mask(SH_E) ;; Set if the default precision of th FPU is single. Mask(FPU_SINGLE) +;; Set if the a double-precision FPU is present but is restricted to +;; single precision usage only. +Mask(FPU_SINGLE_ONLY) + ;; Set if we should generate code using type 2A insns. Mask(HARD_SH2A) @@ -339,7 +343,7 @@ Target RejectNegative Joined UInteger Var(sh_multcost) Init(-1) Cost to assume for a multiply insn musermode -Target Report RejectNegative Mask(USERMODE) +Target Report RejectNegative Var(TARGET_USERMODE) Don't generate privileged-mode only code; implies -mno-inline-ic_invalidate if the inline code would not work in user mode. ;; We might want to enable this by default for TARGET_HARD_SH4, because diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1f69684fb6c..231ceb5bd0a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2013-03-13 Oleg Endo + + PR target/49880 + * gcc.target/sh/pr49880-1.c: New. + * gcc.target/sh/pr49880-2.c: New. + * gcc.target/sh/pr49880-3.c: New. + * gcc.target/sh/pr49880-4.c: New. + * gcc.target/sh/pr49880-5.c: New. + 2013-03-13 Paolo Carlini * g++.dg/cpp0x/alias-decl-32.C: Remove redundant bits. diff --git a/gcc/testsuite/gcc.target/sh/pr49880-1.c b/gcc/testsuite/gcc.target/sh/pr49880-1.c new file mode 100644 index 00000000000..e19f1bf38a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr49880-1.c @@ -0,0 +1,22 @@ +/* Check that the option -mdiv=call-div1 works. */ +/* { dg-do link { target "sh*-*-*" } } */ +/* { 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/testsuite/gcc.target/sh/pr49880-2.c b/gcc/testsuite/gcc.target/sh/pr49880-2.c new file mode 100644 index 00000000000..eef832e30db --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr49880-2.c @@ -0,0 +1,22 @@ +/* Check that the option -mdiv=call-fp works. */ +/* { dg-do link { target "sh*-*-*" } } */ +/* { 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/testsuite/gcc.target/sh/pr49880-3.c b/gcc/testsuite/gcc.target/sh/pr49880-3.c new file mode 100644 index 00000000000..80a7df548a8 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr49880-3.c @@ -0,0 +1,22 @@ +/* Check that the option -mdiv=call-table works. */ +/* { dg-do link { target "sh*-*-*" } } */ +/* { 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/testsuite/gcc.target/sh/pr49880-4.c b/gcc/testsuite/gcc.target/sh/pr49880-4.c new file mode 100644 index 00000000000..998a8b69fdd --- /dev/null +++ b/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 { target "sh*-*-*" } } */ +/* { 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/testsuite/gcc.target/sh/pr49880-5.c b/gcc/testsuite/gcc.target/sh/pr49880-5.c new file mode 100644 index 00000000000..09e99a85f63 --- /dev/null +++ b/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 { target "sh*-*-*" } } */ +/* { 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/libgcc/ChangeLog b/libgcc/ChangeLog index fe08adb12aa..61f5cc07694 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2013-03-13 Oleg Endo + + PR target/49880 + * config/sh/lib1funcs.S (sdivsi3_i4, udivsi3_i4): Enable for SH2A. + (sdivsi3, udivsi3): Remove SH4 check and always compile these functions. + 2013-03-07 Sriraman Tallam * config/i386/cpuinfo.c (get_intel_cpu): Fix cpuid codes for diff --git a/libgcc/config/sh/lib1funcs.S b/libgcc/config/sh/lib1funcs.S index 56257190421..5f0bbff264f 100644 --- a/libgcc/config/sh/lib1funcs.S +++ b/libgcc/config/sh/lib1funcs.S @@ -1006,7 +1006,7 @@ hiset: sts macl,r0 ! r0 = bb*dd #ifdef L_sdivsi3_i4 .title "SH DIVIDE" !! 4 byte integer Divide code for the Renesas SH -#ifdef __SH4__ +#if defined (__SH4__) || defined (__SH2A__) !! args in r4 and r5, result in fpul, clobber dr0, dr2 .global GLOBAL(sdivsi3_i4) @@ -1021,7 +1021,7 @@ GLOBAL(sdivsi3_i4): ftrc dr0,fpul ENDFUNC(GLOBAL(sdivsi3_i4)) -#elif defined(__SH4_SINGLE__) || defined(__SH4_SINGLE_ONLY__) || (defined (__SH5__) && ! defined __SH4_NOFPU__) +#elif defined (__SH2A_SINGLE__) || defined (__SH2A_SINGLE_ONLY__) || defined(__SH4_SINGLE__) || defined(__SH4_SINGLE_ONLY__) || (defined (__SH5__) && ! defined __SH4_NOFPU__) !! args in r4 and r5, result in fpul, clobber r2, dr0, dr2 #if ! __SH5__ || __SH5__ == 32 @@ -1046,13 +1046,12 @@ GLOBAL(sdivsi3_i4): ENDFUNC(GLOBAL(sdivsi3_i4)) #endif /* ! __SH5__ || __SH5__ == 32 */ -#endif /* ! __SH4__ */ +#endif /* ! __SH4__ || __SH2A__ */ #endif #ifdef L_sdivsi3 /* __SH4_SINGLE_ONLY__ keeps this part for link compatibility with sh2e/sh3e code. */ -#if (! defined(__SH4__) && ! defined (__SH4_SINGLE__)) || defined (__linux__) !! !! Steve Chamberlain !! sac@cygnus.com @@ -1369,13 +1368,12 @@ div0: rts ENDFUNC(GLOBAL(sdivsi3)) #endif /* ! __SHMEDIA__ */ -#endif /* ! __SH4__ */ #endif #ifdef L_udivsi3_i4 .title "SH DIVIDE" !! 4 byte integer Divide code for the Renesas SH -#ifdef __SH4__ +#if defined (__SH4__) || defined (__SH2A__) !! args in r4 and r5, result in fpul, clobber r0, r1, r4, r5, dr0, dr2, dr4, !! and t bit @@ -1417,7 +1415,7 @@ L1: .double 2147483648 ENDFUNC(GLOBAL(udivsi3_i4)) -#elif defined (__SH5__) && ! defined (__SH4_NOFPU__) +#elif defined (__SH5__) && ! defined (__SH4_NOFPU__) && ! defined (__SH2A_NOFPU__) #if ! __SH5__ || __SH5__ == 32 !! args in r4 and r5, result in fpul, clobber r20, r21, dr0, fr33 .mode SHmedia @@ -1438,7 +1436,7 @@ GLOBAL(udivsi3_i4): ENDFUNC(GLOBAL(udivsi3_i4)) #endif /* ! __SH5__ || __SH5__ == 32 */ -#elif defined(__SH4_SINGLE__) || defined(__SH4_SINGLE_ONLY__) +#elif defined (__SH2A_SINGLE__) || defined (__SH2A_SINGLE_ONLY__) || defined(__SH4_SINGLE__) || defined(__SH4_SINGLE_ONLY__) !! args in r4 and r5, result in fpul, clobber r0, r1, r4, r5, dr0, dr2, dr4 .global GLOBAL(udivsi3_i4) @@ -1493,7 +1491,6 @@ L1: #ifdef L_udivsi3 /* __SH4_SINGLE_ONLY__ keeps this part for link compatibility with sh2e/sh3e code. */ -#if (! defined(__SH4__) && ! defined (__SH4_SINGLE__)) || defined (__linux__) !! args in r4 and r5, result in r0, clobbers r4, pr, and t bit .global GLOBAL(udivsi3) @@ -1688,7 +1685,6 @@ LOCAL(large_divisor): ENDFUNC(GLOBAL(udivsi3)) #endif /* ! __SHMEDIA__ */ -#endif /* __SH4__ */ #endif /* L_udivsi3 */ #ifdef L_udivdi3