target/7533: gcc 3.0.2 h8300 right shift 15 is wrong

ftu@fi.uu.nl ftu@fi.uu.nl
Wed Aug 7 16:36:00 GMT 2002


>Number:         7533
>Category:       target
>Synopsis:       gcc 3.0.2 h8300 right shift 15 is wrong
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Wed Aug 07 16:36:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     dick wesseling
>Release:        3.0.2
>Organization:
>Environment:
h8300 cross compiler
>Description:
The h8300 backend attempts to decompose unsigned >>15 into:

 1) a single half register left shift, which moves 1 bit into the carry
    register,

 2) followed by half register MOV and XOR which has the effect of >>16

 3) followed by a single bit full register left rotate which combines
    the carry and the register.


The bug is that step 1) uses the wrong register half.

consider the following code:

unsigned long s15(unsigned long in)  {
        return in>>15;
}

if the input parameter is EeeeeeeeeeeeeeeeRxxxxxxxxxxxxxxx 
then the following happens:

;       GCC For the Hitachi H8/300
;       By Hitachi America Ltd and Cygnus Support
; -O2

        .h8300s
        .file   "h8300-shift-bug.c"
        .section .text
        .align 1
        .global _s15
_s15:                       Carry  e0              r0
        push.l  er6
        mov.l   er7,er6         -  EeeeeeeeeeeeeeeeRxxxxxxxxxxxxxxx
> >      shll.w  e0              E  eeeeeeeeeeeeeee0Rxxxxxxxxxxxxxxx
        mov.w   e0,r0           E  eeeeeeeeeeeeeee0eeeeeeeeeeeeeee0
        xor.w   e0,e0           E  0000000000000000eeeeeeeeeeeeeee0
        rotxl.l er0             0  0000000000000000eeeeeeeeeeeeeeeE
        pop.l   er6
        rts
        .end
        .ident
"GCC: (GNU) 3.0.2"

The intended code was:

        push.l  er6         Carry  e0              r0
        mov.l   er7,er6         -  EeeeeeeeeeeeeeeeRrrrrrrrrrrrrrrr
> >      shll.w  r0              R  Eeeeeeeeeeeeeeeerrrrrrrrrrrrrrr0
        mov.w   e0,r0           R  EeeeeeeeeeeeeeeeEeeeeeeeeeeeeeee
        xor.w   e0,e0           R  0000000000000000Eeeeeeeeeeeeeeee
        rotxl.l er0             -  000000000000000EeeeeeeeeeeeeeeeR
        
>How-To-Repeat:
compile this function:
unsigned long s15(unsigned long in)  {
        return in>>15;
}
>Fix:
*** gcc-3.0.2/gcc/config/h8300/h8300.c.orig     Wed Nov 21 18:09:08 2001
--- gcc-3.0.2/gcc/config/h8300/h8300.c  Thu Aug  8 00:55:36 2002
***************
*** 2477,2487 ****
            {
            case SHIFT_ASHIFT:
              info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
              goto end;
            case SHIFT_LSHIFTRT:
!             info->special = "shll.w\t%e0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
              goto end;
            }
        }
        else if ((TARGET_H8300 && count == 16)
               || (TARGET_H8300H && 16 <= count && count <= 19)
--- 2477,2487 ----
            {
            case SHIFT_ASHIFT:
              info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
              goto end;
            case SHIFT_LSHIFTRT:
!             info->special = "shll.w\t%r0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
              goto end;
            }
        }
        else if ((TARGET_H8300 && count == 16)
               || (TARGET_H8300H && 16 <= count && count <= 19)
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the Gcc-bugs mailing list