Thread: [GCC] Compiling for a generic x86 architecture

  1. #16
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    mtune=... does NOT affect the instruction sets used, or machines the executable is run on.

    For that (eg, enabling SSE), you'll need march=....

    If you do march=core2 for example (on a new GCC), it will use all the instruction sets available to Core 2 CPUs. march=x also sets mtune=x. The executable won't run on older CPUs.

    If you ONLY use mtune=core2, it will generate code that runs the best on a Core 2, but will still only use instructions available to all x86 CPUs (eg, no SSE), hence it will still run on old CPUs, just a little slower.

    As a real world example, I think a few years ago some Linux distribution decides to use -march=pentium3 -mtune=pentium4, or something like that. That means, the code is guaranteed to run on a P3, but optimized for a P4, since they predict most people will be running for a P4.

    If you don't use any flag, GCC will assume -march=i386 (lowest x86).

    If you want GCC to use all instruction sets on your CPU, and optimize for your CPU (because, for example, the code will only be run on your machine), you can do -march=native (which also sets mtune=native). Only available in newer GCC (it was introduced in 4.3 or 4.4 I THINK).

    -m32 and -m64 are only for generating 32-bit code on a 64-bit machine, or generating 64-bit code on a 32-bit machine, respectively. GCC defaults to 32-bit on 32-bit, and 64-bit on 64-bit.

  2. #17
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    In your case, you probably want

    -march=i386 (or whatever you want the minimum requirement to be) and -mtune=[what you think most of your users will be running]

  3. #18
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    I meant instruction set extensions can/should be used. For example, anything SSE on an 80386 would generate an undefined opcode exception.

    "-mX" will imply that gcc need to compile X bit code, but specifying with march might not be a bad idea(it will make your program compatible with processors older than yours), but march has nothing to do with 32/64 bit distinctions, all processors(except Itanium) start in 16 bit real mode. It's important not to guess newer what you're users are using. If you tell gcc to produce code for the Core2 line and a user has a Pentium 4 processor, it's possible your program won't work correctly(because SSE3 isn't supported by the Pentium 4).

  4. #19
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    And I meant -mtune won't make it use any more instructions.

    Even if you do -mtune=core2, it still won't use SSE. It will just do things like instruction reordering, branch prediction, and loop unrolling differently to optimize for different CPUs (for example, on a CPU with smaller instruction cache, loop unrolling threshold would be set lower. On a CPU with deep pipelines, branch elimination would be done more aggressively). The code won't run on any more or less CPUs.

    -mX is only for when the user has more choices beyond -march. In x86's case, a Core 2 can run both 32-bit and 64-bit code, so the -m32 and -m64 flags are added to allow the user to specify that. They are like "arguments" to -march.

    You can try -march=pentium3 -m64. That won't work because Pentium 3's cannot run 64-bit code.

    Similarly, for processors that can do both big-endian and little-endian natively, there are -mX flags to select which.

    It doesn't matter what mode the processor starts on, unless you are writing an OS. When the OS runs your code, the CPU would be in 32-bit or 64-bit mode already.

  5. #20
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    Quote Originally Posted by [url=http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html]i386 and x86-64 Options - Using the GNU Compiler Collection (GCC)[/url]
    -mtune=cpu-type
    Tune to cpu-type everything applicable about the generated code, except for the ABI and the set of available instructions.
    I was wrong. If it doesn't exclude/include instructions, what does it do? There's not really anything different, as far as the compiler is concerned, between a 80386 and a Core2, or is there?

    I specified OP should use -mX because most Linuxes are 64 bit and if he's compiling for a 32 bit Windows box on a 64 bit Linux, gcc will compile 64 bit by default.

    I mentioned that all processors start in real mode because that explains why just specifiying which processor doesn't specify 32 or 64 bit.

  6. #21
    Registered User
    Join Date
    May 2010
    Posts
    13
    Use "-m32 -Wl,--oformat,pei-i386" for 32 bit Windows
    Use "-m64 -Wl,--oformat,pei-x86-64" for 64 bit Windows
    Use "-m32 -Wl,--oformat,elf32-i386" for 32 bit Linux
    Use "-m64 -Wl,--oformat,elf64-x86-64" for 64 bit Linux
    It works

    mtune=... does NOT affect the instruction sets used, or machines the executable is run on.

    For that (eg, enabling SSE), you'll need march=....

    If you do march=core2 for example (on a new GCC), it will use all the instruction sets available to Core 2 CPUs. march=x also sets mtune=x. The executable won't run on older CPUs.

    If you ONLY use mtune=core2, it will generate code that runs the best on a Core 2, but will still only use instructions available to all x86 CPUs (eg, no SSE), hence it will still run on old CPUs, just a little slower.

    As a real world example, I think a few years ago some Linux distribution decides to use -march=pentium3 -mtune=pentium4, or something like that. That means, the code is guaranteed to run on a P3, but optimized for a P4, since they predict most people will be running for a P4.

    If you don't use any flag, GCC will assume -march=i386 (lowest x86).

    Thanks for replies

  7. #22
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by User Name: View Post
    Yeah, section headers, .text section alignment, and ELF are all useless right
    Umm -- gcc 2.95 is ancient. I believe it was a few years old when linux first came out in 1993. The current version is 4.4

    Again, the OP should not have to use any switches at all and I'm sure everything will come out fine.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #23
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    From my experience, -march/-mtune doesn't make the code faster noticeably anyways, so I just skip them most of the time now.

    I suppose it would matter for floating-point heavy code that would benefit from SIMD instructions.

  9. #24
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    And I agree, no flags should be needed.

    The MinGW target he is compiling for doesn't support 64-bit anyways. The host bit-ness detection thing only applies for native compiles (not cross-compilation).

    There's a special 64-bit MinGW version, but that's still experimental last time I checked (I had to build it from SVN source), and not included in the official source.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. Resource ICONs
    By gbaker in forum Windows Programming
    Replies: 4
    Last Post: 12-15-2003, 07:18 AM