On 2020-02-19 00:16, Jim Wilson wrote: > On Wed, Feb 12, 2020 at 9:10 AM J.W. Jagersma <jwjagersma@xxxxxxxxx> wrote: >> i686-gcc -march=i386: cmov (!) > > Did you check to see where the cmov instruction is coming from? The > compiler won't generate it with -march=i386, but there may be a > precompiled library like libgcc or libstdc++ that contains the cmov > instruction because they were compiled for i686. In order to get the > right effect with -march=i386, you would need to build multiple copies > of the libraries, one of them with -march=i386. We call this > multilibs. This is normally done with -m32/-m64 so a single compiler > can generate both 32-bit and 64-bit code, but it is not normally done > with i386 and i686. You would have to change the default > configuration to build multilibs based on -march. Ah, you're right. The cmovs only appear in library code. So the target name only sets the default value for -march? Which is what I initially expected. Say I wanted to do build multilibs for x86, where would I start? I've been looking through the configure/make files but I don't see how it's done. >> So it looks like gcc compiled with --target=i686-* is incapable of producing >> i386 code, and --target=i386-* is the most versatile option for backwards >> compatibility with older cpus. Are there any disadvantages (reduced >> optimization, etc) to using an i386-gcc with -march=i686 when compiling for >> "newer" systems? > > Besides the performance loss, i386 doesn't have cmpxchg which means > atomic support will be a problem. Otherwise, it will probably work. I did notice that using i386, my program doesn't link at -O0 due to undefined references to __atomic_* builtins. Somehow it works at -O1 and above. It seems the only atomic operations I use are compiled to 'lock add/sub' instructions.