From patchwork Wed Mar 13 00:22:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleg Endo X-Patchwork-Id: 227133 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 3E9D52C029D for ; Wed, 13 Mar 2013 11:22:33 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1363738954; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Message-ID:Subject:From:To:Date:Content-Type:Mime-Version: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=N+rxAWoG7Th2bNsGMdEW 1Aet+BU=; b=tvxY+wlLs8imk8GmOEe2IrZmdIsX/uo9+TSHnmpryZfUIZdEcYDi NIlWQXCr1XUw295JgA0V8owbUwY16FoEfCvIBA1OPkoFO7ialw1rdAKeEr8eOvfX 2jm492c/YCXQIuMe04p+aYbBgvTkwv6GtGPOFyHi9uptJvaU8gOokqg= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Message-ID:Subject:From:To:Date:Content-Type:Mime-Version:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=UgyN4wC/iothdmHtgFLIqOPaUl7OOBUpD2ZXwOUwQSWGf0lKA04RJoBKo4kpLT 4nFAmMUalJPavMcbMDt8hC3K8B2jsLqhN6inylF+gp0mdO3PiI5X/rq2hXhVzJvv xzSpwrmnQcENQOnxYjCY3cEq4tgXefFjdMbZvrzarOx2s=; Received: (qmail 27870 invoked by alias); 13 Mar 2013 00:22:24 -0000 Received: (qmail 27828 invoked by uid 22791); 13 Mar 2013 00:22:17 -0000 X-SWARE-Spam-Status: No, hits=-4.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_YE, RP_MATCHES_RCVD, T_FRT_FREE, UNPARSEABLE_RELAY X-Spam-Check-By: sourceware.org Received: from mailout05.t-online.de (HELO mailout05.t-online.de) (194.25.134.82) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 13 Mar 2013 00:22:10 +0000 Received: from fwd57.aul.t-online.de (fwd57.aul.t-online.de ) by mailout05.t-online.de with smtp id 1UFZSJ-00089J-I2; Wed, 13 Mar 2013 01:22:07 +0100 Received: from [192.168.0.103] (bpniqmZTZht4loskU8ehHvmKbxIQbFIibbZdpH8fKRO3XfbHT7RXJZ9wpBeKDy6gHW@[93.195.17.96]) by fwd57.t-online.de with esmtp id 1UFZSJ-2G0uxM0; Wed, 13 Mar 2013 01:22:07 +0100 Message-ID: <1363134126.2219.213.camel@yam-132-YW-E178-FTW> Subject: [SH] PR 49880 - Fix some more -mdiv option issues From: Oleg Endo To: gcc-patches Date: Wed, 13 Mar 2013 01:22:06 +0100 Mime-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, Initially I just wanted to simplify two lines as mentioned in the PR. However, when I started writing the test cases a small can of worms popped up. '-m4 -mdiv=call-div1' would not link on bare metal configs because of missing functions in libgcc, '-m2a -mdiv=call-fp' would ICE and/or not link and '*-nofpu -mdiv=call-fp' would invoke library functions that use the FPU. I've also run across some confusions regarding TARGET_FPU_SINGLE and friends, but I'm leaving a better cleanup for 4.9. Basically it's not possible to distinguish between -m4-nofpu and -m4-single-only, because there are no corresponding bits. Thus the two new mask bits in sh.opt, which required converting some of the existing mask bit into a var, as we already ran out of bits once in the past. The attached patch should make the -mdiv= option work as it is described in the documentation (which I updated recently as part of PR 56529). Tested with 'make all' and make -k check-gcc RUNTESTFLAGS="sh.exp=pr49880* --target_board=sh-sim \{-m2,-m2a,-m2a-nofpu,-m2a-single,-m2a-single-only,-m3,-m3e,-m4,-m4-single, -m4-single-only,-m4a,-m4a-single,-m4a-single-only}" OK for 4.8 and 4.7? Cheers, Oleg gcc/ChangeLog: 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. libgcc/ChangeLog: PR target/49880 * config/sh/lib1funcs.S (sdivsi3_i4, udivsi3_i4): Enable for SH2A. (sdivsi3, udivsi3): Remove SH4 check and always compile these functions. testsuite/ChangeLog: PR target/49880 * testsuite/gcc.target/sh/pr49880-1.c: New. * testsuite/gcc.target/sh/pr49880-2.c: New. * testsuite/gcc.target/sh/pr49880-3.c: New. * testsuite/gcc.target/sh/pr49880-4.c: New. * testsuite/gcc.target/sh/pr49880-5.c: New. Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 196589) +++ gcc/config/sh/sh.md (working copy) @@ -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")]) Index: gcc/config/sh/sh.opt =================================================================== --- gcc/config/sh/sh.opt (revision 196589) +++ gcc/config/sh/sh.opt (working copy) @@ -24,6 +24,10 @@ ;; 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 @@ 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 Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 196589) +++ gcc/config/sh/sh.c (working copy) @@ -816,8 +816,7 @@ 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) Index: gcc/config/sh/sh.h =================================================================== --- gcc/config/sh/sh.h (revision 196589) +++ gcc/config/sh/sh.h (working copy) @@ -138,14 +138,16 @@ | 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 @@ /* 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 Index: gcc/testsuite/gcc.target/sh/pr49880-4.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr49880-4.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr49880-4.c (revision 0) @@ -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; +} Index: gcc/testsuite/gcc.target/sh/pr49880-1.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr49880-1.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr49880-1.c (revision 0) @@ -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); +} Index: gcc/testsuite/gcc.target/sh/pr49880-5.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr49880-5.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr49880-5.c (revision 0) @@ -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; +} Index: gcc/testsuite/gcc.target/sh/pr49880-2.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr49880-2.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr49880-2.c (revision 0) @@ -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); +} Index: gcc/testsuite/gcc.target/sh/pr49880-3.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr49880-3.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr49880-3.c (revision 0) @@ -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); +} Index: libgcc/config/sh/lib1funcs.S =================================================================== --- libgcc/config/sh/lib1funcs.S (revision 196589) +++ libgcc/config/sh/lib1funcs.S (working copy) @@ -1006,7 +1006,7 @@ #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 @@ 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 @@ 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 @@ 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 @@ .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 @@ 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 @@ #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 @@ ENDFUNC(GLOBAL(udivsi3)) #endif /* ! __SHMEDIA__ */ -#endif /* __SH4__ */ #endif /* L_udivsi3 */ #ifdef L_udivdi3