2

I have the following C file

int foo (int input)
{
    if (input == 0)
        input = 1;
    
    return input;
}

When I create an object file using gcc foo.c -m32 -Wa,-march=i486 -c, everything goes well. However, when I add a -O3 to the command, I get the following error:

/tmp/cc7br7gY.s: Assembler messages:
/tmp/cc7br7gY.s:12: Error: `cmove' is not supported on `i486'

Do I have to provide an additional option for the assembly optimizer to tell it that I want instructions that will work on i486?

gcc --version outputs gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0.

Kolodez
  • 553
  • 2
  • 9
  • https://godbolt.org/z/M56PMcdKn – 0___________ Mar 25 '23 at 20:04
  • 2
    The GNU assembler doesn't optimize. The compiler emits a stream of instructions and the assembler assembles them exactly as given. Passing `-march` to the assembler doesn't affect its output at all, it only causes it to abort if it sees an instruction that the target architecture wouldn't support (as you saw here). It's the *compiler* that needs to be informed what instructions (not) to emit. – Nate Eldredge Mar 25 '23 at 22:18

1 Answers1

6

You aren't telling the compiler to compile to the arch, just the assembler (which I'm not really sure you need to do).

Pass a plain -m32 -march=i486 if that's what you want to do (or use any other arch as you require).

Hasturkun
  • 35,395
  • 6
  • 71
  • 104
  • Would `-m32 -march=i486 -Wa,-march=i486` be an appropriate choice to tell both the compiler and the assembler the desired architecture? – Kolodez Mar 25 '23 at 20:07
  • Why would anyone want different architectures for the compiler and the assembler (just curious)? – Kolodez Mar 25 '23 at 20:08
  • 3
    I was asking myself that when I saw you passing `-Wa,-march=i486`. As I said, I don't think you actually need to do this (and while I didn't check, I'm guessing that GCC passes the correct value to the assembler by itself, if needed). – Hasturkun Mar 25 '23 at 20:09
  • 1
    @Kolodez you can pass the parameters to the assembler. Why should GCC stop you from passing any parameter you want (even if they make no sense)? – 0___________ Mar 25 '23 at 20:10
  • Due to [this answer](https://stackoverflow.com/a/72762509/10126596), I originally used `-Wa,-march=i486`. – Kolodez Mar 25 '23 at 20:22
  • 2
    @Kolodez That answer is about assembly code, where the compiler driver basically passes your source code to the assembler unchanged. It does not apply here and is not needed usually anyway (assembly programmers generally know which instructions are supported where). – fuz Mar 25 '23 at 22:05
  • 3
    @Kolodez: No, `-march=i486` alone doesn't automatically pass the corresponding option to the assembler. But it shouldn't be needed. The only effect of passing `-march` to the assembler is to have it barf if you write an instruction not supported by the target architecture. Here the compiler already knows that it's not going to emit any such instructions. You could add `-Wa,-march=i486` if you wish to be paranoid, but unless the compiler has a bug, it won't do anything. – Nate Eldredge Mar 25 '23 at 22:12