Code generation bug on MIPS R4000

Jeffrey A Law law@hurl.cygnus.com
Sun Feb 14 01:32:00 GMT 1999


I do not believe your analysis is correct.

First, it is not necessary (or desirable) to mask off the upper 32 bits of
the arguments.  According to the documentation I have, sll does not require
its input operand to be properly sign extended, but after the sll the result
will always be properly extended.

Second issue:

     pcr = (m_upper << 22) | (s2 << 16) | (s1);

This first computes the expression "(m_upper << 22) | (s2 << 16) | (s1)" with
an "unsigned int" type.  The result (which is on 32bits wide) is then
converted by the assignment to the 64bit return type.

If you look at the code that is precisely what it implements.

a0 (m_upper) is shifted 22 positions and placed into v0
a1 (s1) is masked to its lower 16 bits (result stays in a1)
a2 (s2) is shifted 16 positions (result stays in a2)

Then we ior those three values.  Lastly we zero extend the value to 64 bits
which is correct according to ANSI conversion rules.


  In message <3521B963898BD111AA6A006008A84516079C55@SERVER>you write:
  > Host:     windows NT 4.0 
  > Target:   mips-wrs-vxworks (same as mips-gnu-elf)
  > Binutils: 980418
  > egcs:     egcs-2.91.23 980411
  > 
  > The following file when compiled yields two code generation bugs.
  > The first comes from the first argument 'm_upper'. The upper 32-bits
  > of this argument should be masked off before it is shifted into v0 on line
  > 14. (Actually, I'm not 100% sure about this. The User's Manual for the
  > chips states that the operand to 'sll' should be a valid sign-extended
  > 32-bit value, which I suppose m_upper should be.)
  > The second problem shows up on line 18 and 22 below: the return value
  > (which is in 'v0') is being truncated to the lower 32 bits only, when
  > it should be all 64 bits.
  > 
  > ---t.c---
  > unsigned long long E(unsigned int m_upper, unsigned short s1, unsigned shor
  > t s2)
  > {
  >     unsigned long long pcr;
  >     pcr = (m_upper << 22) | (s2 << 16) | (s1);
  >     return pcr;
  > }
  > ---end t.c---
  > 
  > $ cc1 -quiet -version -mfp64 -mgp64 -mips3 -mrnames -O3 t.c
  > GNU C version egcs-2.91.23 980411 (gcc2 ss-980401 experimental) (mips-wrs-v
  > xworks) compiled by GNU C version 2.7-B19.
  > 
  > 1         .file   1 "t.c"
  > 2 gcc2_compiled.:
  > 3 __gnu_compiled_c:
  > 4         .text
  > 5         .align  2
  > 6         .globl  E
  > 7         .text
  > 8         .ent    E
  > 9 E:
  > 10        .frame  $sp,0,$ra               # vars= 0, regs= 0/0, args= 0, ex
  > tra= 0
  > 11        .mask   0x00000000,0
  > 12        .fmask  0x00000000,0
  > 13        andi    $a1,$a1,0xffff
  > 14        sll     $v0,$a0,22
  > 15        sll     $a2,$a2,16
  > 16        or      $v0,$v0,$a2
  > 17        or      $v0,$v0,$a1
  > 18        dsll    $v0,$v0,32
  > 19        .set    noreorder
  > 20        .set    nomacro
  > 21        j       $31
  > 22        dsrl    $v0,$v0,32
  > 23        .set    macro
  > 24        .set    reorder
  > 25
  > 26        .end    E
  > 


More information about the Gcc-bugs mailing list