On Tue, Sep 23, 2014 at 9:51 AM, Bin Meng <bmeng...@gmail.com> wrote:
> Hi,
>
> I get a piece of code to be compiled by gcc with the combined '-Os
> -mregparm=3' options to generate the x86 32-bit codes, and I found gcc
> created broken codes.
>
> The test codes that can be used to trigger this issue: (save the
> following to test.c.)
>
> typedef struct {
>      int     a;
>      int     b;
> } TEST_INFO;
>
> typedef struct {
>      int     a;
> } PCALL_PARAM;
>
> typedef int (*PCALL)(PCALL_PARAM *);
>
> extern TEST_INFO * dont_care(void);
>
> #undef WORKAROUND
>
> int test (TEST_INFO *info, int d)
> {
>      PCALL          pcall;
>      PCALL_PARAM     params;
>      PCALL_PARAM     *params_ptr;
>      int          status;
>      TEST_INFO     *r;
>
>      if (!info) {
>           r = (TEST_INFO *)dont_care();
>      } else {
>           r = info;
>      }
>
>      pcall = (PCALL)(r->a + r->b);
>      params.a = d;
> #ifdef WORKAROUND
>      status = pcall (&params);
> #endif
>      params_ptr = &params;
>
>      asm volatile (
>      "pushl      %1;"
>      "call       *%%eax;"
>      "addl       $4, %%esp;"
>      : "=a"(status) : "m"(params_ptr), "a"(pcall)
>      );
>
>      return status;
> }
>
> The gcc command I am using to compile the file:
>
> $ gcc -v -Os -mregparm=3 -march=i386 -m32 -c -o test.o test.c
> Using built-in specs.
> COLLECT_GCC=gcc
> Target: x86_64-CentOS-linux
> Configured with: ../configure
> --prefix=/opt/centos/devtoolset-1.1/root/usr
> --mandir=/opt/centos/devtoolset-1.1/root/usr/share/man
> --infodir=/opt/centos/devtoolset-1.1/root/usr/share/info
> --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap
> --enable-shared --enable-threads=posix --enable-checking=release
> --disable-build-with-cxx --disable-build-poststage1-with-cxx
> --with-system-zlib --enable-__cxa_atexit
> --disable-libunwind-exceptions --disable-gnu-unique-object
> --enable-linker-build-id --enable-languages=c,c++,fortran,lto
> --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array
> --disable-libgcj
> --with-gmp=/home/centos/rpm/BUILD/gcc-4.7.2-20121015/obj-x86_64-CentOS-linux/gmp-install
> --with-mpfr=/home/centos/rpm/BUILD/gcc-4.7.2-20121015/obj-x86_64-CentOS-linux/mpfr-install
> --with-ppl=/home/centos/rpm/BUILD/gcc-4.7.2-20121015/obj-x86_64-CentOS-linux/ppl-install
> --with-cloog=/home/centos/rpm/BUILD/gcc-4.7.2-20121015/obj-x86_64-CentOS-linux/cloog-install
> --with-mpc=/home/centos/rpm/BUILD/gcc-4.7.2-20121015/obj-x86_64-CentOS-linux/mpc-install
> --with-tune=generic --with-arch_32=i586 --build=x86_64-CentOS-linux
> Thread model: posix
> gcc version 4.7.2 20121015 (Red Hat 4.7.2-5) (GCC)
> COLLECT_GCC_OPTIONS='-v' '-Os' '-mregparm=3' '-march=i386' '-m32' '-c'
> '-o' 'test.o'
>  /opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/cc1
> -quiet -v -imultilib 32 test.c -quiet -dumpbase test.c -mregparm=3
> -march=i386 -m32 -auxbase-strip test.o -Os -version -o /tmp/ccrfMdFf.s
> GNU C (GCC) version 4.7.2 20121015 (Red Hat 4.7.2-5) (x86_64-CentOS-linux)
>         compiled by GNU C version 4.7.2 20121015 (Red Hat 4.7.2-5),
> GMP version 4.3.1, MPFR version 2.4.1, MPC version 0.8.1
> GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
> ignoring nonexistent directory
> "/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/include-fixed"
> ignoring nonexistent directory
> "/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/../../../../x86_64-CentOS-linux/include"
> #include "..." search starts here:
> #include <...> search starts here:
>  /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/include
>  /usr/local/include
>  /opt/centos/devtoolset-1.1/root/usr/include
>  /usr/include
> End of search list.
> GNU C (GCC) version 4.7.2 20121015 (Red Hat 4.7.2-5) (x86_64-CentOS-linux)
>         compiled by GNU C version 4.7.2 20121015 (Red Hat 4.7.2-5),
> GMP version 4.3.1, MPFR version 2.4.1, MPC version 0.8.1
> GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
> Compiler executable checksum: 08198519a1e798dc5da060bad8011478
> COLLECT_GCC_OPTIONS='-v' '-Os' '-mregparm=3' '-march=i386' '-m32' '-c'
> '-o' 'test.o'
>  /opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/as
> -v --32 -o test.o /tmp/ccrfMdFf.s
> GNU assembler version 2.23.51.0.3 (x86_64-CentOS-linux) using BFD
> version version 2.23.51.0.3-3.el5 20120918
> COMPILER_PATH=/opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/:/opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/:/opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/:/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/:/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/
> LIBRARY_PATH=/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/32/:/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/:/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/../../../:/lib/:/usr/lib/
> COLLECT_GCC_OPTIONS='-v' '-Os' '-mregparm=3' '-march=i386' '-m32' '-c'
> '-o' 'test.o'
>
> Using objdump to disassemble the test.o
> $ objdump -D test.o > asm.txt
>
> And the generated codes are:
>
> 00000000 <test>:
>    0:   55                      push   %ebp
>    1:   89 e5                   mov    %esp,%ebp
>    3:   83 ec 18                sub    $0x18,%esp
>    6:   85 c0                   test   %eax,%eax
>    8:   75 05                   jne    f <test+0xf>
>    a:   e8 fc ff ff ff          call   b <test+0xb>
>    f:   8b 10                   mov    (%eax),%edx
>   11:   03 50 04                add    0x4(%eax),%edx
>   14:   8d 45 f0                lea    -0x10(%ebp),%eax
>   17:   89 45 f4                mov    %eax,-0xc(%ebp)
>   1a:   89 d0                   mov    %edx,%eax
>   1c:   ff 75 f4                pushl  -0xc(%ebp)
>   1f:   ff d0                   call   *%eax
>   21:   83 c4 04                add    $0x4,%esp
>   24:   c9                      leave
>   25:   c3                      ret
>
> See the edx gets overwritten at address 0xf 'mov    (%eax),%edx' while
> edx holds the 2nd parameter of function test when given option
> '-mregparm=3'.
>
> I believe this is a bug. Could someone confirm this? Thanks,

Your asm constraints do not specify that they use %edx.

Richard.

> Regards,
> Bin

Reply via email to