I have some code which I believe is compiled incorrectly. It seems that the
same register is being used for an input and an output, so the function returns
incorrect results.

The code can be compiled cleanly with a straight: "mipsel-linux-gcc filename.c"
to reproduce the problem.

If you look at the assembly generated in the BAD_MULL function, the three
instructions before the "mult" load the function arguments and do the shift
show that the [temp] register and the [a] register are both the same register
("v1" for me), which causes the value of [a] to be clobbered by the "SLL"
instruction.

I'm using the toolchain provided by the chip manufacturer, so I'm aware that
this isn't the latest version of gcc. Sorry if this has been fixed in a more
recent version, but I couldn't find a similar bug. I also have a workaround
(doing the shift in C and getting rid of the 'temp' variable). And sorry if my
understanding of the extended assembly is wrong and this is a bug in my own
code.

This is the output of mipsel-linux-gcc -v
Using built-in specs.
Target: mipsel-linux-uclibc
Configured with:
/home/aowen/toolchain/smp86xx_toolchain_2.8.3.0/toolchain_build_mipsel_nofpu/gcc-4.0.4/configure
--prefix=/home/aowen/toolchain/smp86xx_toolchain_2.8.3.0/build_mipsel_nofpu/staging_dir
--build=i386-pc-linux-gnu --host=i386-pc-linux-gnu --target=mipsel-linux-uclibc
--enable-languages=c,c++ --enable-shared --disable-__cxa_atexit
--enable-target-optspace --with-gnu-ld --disable-nls --enable-multilib
--with-float=soft --enable-sjlj-exceptions
Thread model: posix
gcc version 4.0.4

The code doesn't need any preprocessing and is short and sweet, so I'll just
paste it here:


static inline int BAD_MUL(int a, short c)
{
        int result;
        int temp;
        asm("SLL %[temp], %[c], 16\n\t"
            "MULT %[a], %[c]\n\t"
            : [result]"=h"(result), [temp]"=r"(temp)
            : [a]"r"(a), [c]"r"(c)
            : "lo");
        return result;     
}

int main(int argc, char *argv[]) {
        int a = 0;
        short b = 300;
        return BAD_MUL(a, b);
}


-- 
           Summary: Incorrect code generated for mips inline assembly
           Product: gcc
           Version: 4.0.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: andy-gcc at ultra-premium dot com
  GCC host triplet: i486-linux-gnu
GCC target triplet: mipsel-linux-uclibc


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37711

Reply via email to