egcs 1.02 and Hitachi SH Target

Toshiyasu Morita tm@netcom.com
Thu Apr 23 19:08:00 GMT 1998


> I have done a compile with the dump option ("-dapA") and all the rtl
> code has the "and" instruction in it , so I'm guessing the problem
> occurs in the part of gcc that translates rtl to sh assembly. I've
> looked at the sh specific files, and while I don't understand them
> very well, I'm guessing the problem involves the function
> gen_shl_and() in gcc/config/sh/sh.c.

I'm not terribly good at hacking gcc, but it seems to be this sequence
of code which is the problem:

        if (first > 0)
          {
            operands[2] = GEN_INT (first);
            gen_shifty_hi_op (ASHIFT, operands);
            total_shift -= first;
            mask <<= first;
          }
        if (first >= 0)
          emit_insn (mask == 0xff
                     ? gen_zero_extendqisi2(dest, gen_lowpart (QImode, dest))
                     : gen_zero_extendhisi2(dest, gen_lowpart (HImode, dest)));

The situation is that mask is 127, and first is 1, and when "mask <<= first"
is executed, mask becomes 254, and when execution reaches the emit_insn
it fails the test against 255 and thus a 16-bit to 32-bit zero extend insn
is generated instead of the correct 8-bit to 32-bit zero extend insn.

I'm guessing the mask needs to be padded with ones when it's shifted left:

*** sh.c.bak    Thu Apr 23 18:07:44 1998
--- sh.c        Thu Apr 23 18:11:34 1998
***************
*** 1375,1381 ****
            operands[2] = GEN_INT (first);
            gen_shifty_hi_op (ASHIFT, operands);
            total_shift -= first;
!           mask <<= first;
          }
        if (first >= 0)
          emit_insn (mask == 0xff
--- 1375,1385 ----
            operands[2] = GEN_INT (first);
            gen_shifty_hi_op (ASHIFT, operands);
            total_shift -= first;
!             {
!                 int i; 
!                 for (i=0; i<first; i++)
!                   mask = (mask << 1) | 1;
!               }
          }
        if (first >= 0)
          emit_insn (mask == 0xff

With this patch applied, gcc generates:

_g:
        mov.l   r14,@-r15
        mov.l   L2,r1
        sts.l   pr,@-r15
        mov.l   @r1,r2
        shll2   r2
        extu.b  r2,r2
        mov.l   L3,r1
        mov     r2,r0
        mov.l   @(r0,r1),r4

...which is correct.

This fixes the problem, but I think Joern wrote this code, so I'd like to 
double-check with him before it's inserted into egcs...

Toshi



More information about the Gcc-bugs mailing list