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 (¶ms); > #endif > params_ptr = ¶ms; > > 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