From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31891 invoked by alias); 10 May 2003 15:56:01 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 31867 invoked by uid 71); 10 May 2003 15:56:01 -0000 Date: Sat, 10 May 2003 15:56:00 -0000 Message-ID: <20030510155601.31866.qmail@sources.redhat.com> To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org, From: Marcus Comstedt Subject: Re: target/6526: [SH4] sdivsi3_i4 can clobber xd0/xd2 Reply-To: Marcus Comstedt X-SW-Source: 2003-05/txt/msg00968.txt.bz2 List-Id: The following reply was made to PR target/6526; it has been noted by GNATS. From: Marcus Comstedt To: Dara Hazeghi Cc: gcc-gnats@gcc.gnu.org Subject: Re: target/6526: [SH4] sdivsi3_i4 can clobber xd0/xd2 Date: 10 May 2003 17:53:25 +0200 Dara Hazeghi writes: > Hello, > > could the submitter please verify if this problem still occurs in a > more current version of gcc (ie 3.2.3) ? If so, could the submitter > please send a self-contained testcase demonstrating this problem? > Thanks, I don't have a 3.2.3 compiled, but I can verify that it still occurs with the 20030421 snapshot of 3.3. Here is a testcase: --8<-- testcase.c --8<-- void write_xf0(float f) { __asm__ __volatile__("frchg; fmov.s @%0,fr0; frchg" : : "r" (&f)); } float read_xf0() { float f; __asm__ __volatile__("frchg; fmov.s fr0,@%0; frchg" : : "r" (&f)); return f; } int do_stuff(int a, int b) { int z; write_xf0(7.0); z = a % b; return z+(int)read_xf0(); } int testfunc() { /* Set FPSCR.FR to 1, selecting register bank 1 */ __set_fpscr(0x200000); return do_stuff(42, 17); } --8<-- Compile with `sh-elf-gcc -m4-single-only -c testcase.c', use `-m4-single-only' when linking as well. With the current libgcc implementation, testfunc() will return 10, not 15 as expected. Also, you can change the declaration of do_stuff() to make both args unsigned int, to see that udivsi3_i4 has the same problem. Btw, here is a patch to gcc/config/sh/lib1funcs.asm which fixes the problem for both functions concerned: ---8<--- --- lib1funcs.asm.orig Sat May 10 17:48:43 2003 +++ lib1funcs.asm Sat May 10 17:50:28 2003 @@ -893,18 +893,21 @@ #endif .global GLOBAL(sdivsi3_i4) GLOBAL(sdivsi3_i4): - sts.l fpscr,@-r15 - mov #8,r2 - swap.w r2,r2 - lds r2,fpscr + mov.l r3,@-r15 + sts fpscr,r2 + mov #8,r3 + swap.w r3,r3 + or r2,r3 + lds r3,fpscr lds r4,fpul float fpul,dr0 lds r5,fpul float fpul,dr2 fdiv dr2,dr0 ftrc dr0,fpul + lds r2,fpscr rts - lds.l @r15+,fpscr + mov.l @r15+,r3 #endif /* ! __SH5__ || __SH5__ == 32 */ #endif /* ! __SH4__ */ @@ -1243,11 +1246,20 @@ mov #1,r1 cmp/hi r1,r5 bf trivial - sts.l fpscr,@-r15 - mova L1,r0 - lds.l @r0+,fpscr + sts fpscr,r0 rotr r1 + mov.l r0,@-r15 xor r1,r4 + xor r1,r5 +#ifndef FMOVD_WORKS + mov #0x8,r1 +#else + mov #0x18,r1 +#endif + swap.w r1,r1 + or r0,r1 + mova L1,r0 + lds r1,fpscr lds r4,fpul #ifdef FMOVD_WORKS fmov.d @r0+,dr4 @@ -1261,7 +1273,6 @@ #endif #endif float fpul,dr0 - xor r1,r5 lds r5,fpul float fpul,dr2 fadd dr4,dr0 @@ -1271,20 +1282,16 @@ rts lds.l @r15+,fpscr -#ifdef FMOVD_WORKS - .align 3 ! make double below 8 byte aligned. -#endif trivial: rts lds r4,fpul - .align 2 -L1: -#ifndef FMOVD_WORKS - .long 0x80000 +#ifdef FMOVD_WORKS + .align 3 ! make double below 8 byte aligned. #else - .long 0x180000 + .align 2 #endif +L1: .double 2147483648 #endif /* ! __SH4__ */ ---8<--- Hope this helps. // Marcus