https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124505

            Bug ID: 124505
           Summary: -m16 is inconsistent about 0x66 operand size prefix
                    for JMP/CALL instructions
           Product: gcc
           Version: 15.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: paul.emmerich at icloud dot com
  Target Milestone: ---

Okay, this is a weird one and you might say it's not a bug and/or I'm holding
it wrong. 

Consider this C code:

extern void foo(int);

void example(int n) {
        for (int i = 0; i < n; ++i) {
                foo(i);
        }
}


> gcc-15 -m16 -c -O2 example.c

Yields these JMP instructions for the loop:

eb 0d                   jmp    30 <example+0x30>
75 e7                   jne    30 <example+0x3

These don't get the 0x66 prefix whereas the CALL for the function call inside
the loop does get this prefix:

66 e8 fc ff ff ff       calld  3c <example+0x3c>


But why would you even want the 0x66 prefix on a jmp immediate? It does control
whether the instruction pointer is 16 or 32 bit.
And that's relevant when using unreal mode
(https://en.wikipedia.org/wiki/Unreal_mode) to run code from segments larger
than 64 KiB, the jump wouldn't be able to cross these boundaries (or even
worse: be truncated on each jmp, not sure about real hardware, but all
implementations in DOSBox truncate on each jmp).


Arguably that's not something you support in the first place, so, well, I'm
holding it wrong.

But why does the CALL get the 0x66 prefix? Presumably because the target could
be relocated and it might need the large immediate vs. the small static known
offset for jmp.


But if that is the explanation, then it should consistently apply (or not
apply) the 0x66 prefix:


void example(void (*func)()) {
        func();
}

But no, with -O2 this is compiled to

67 FF 64 24 04  jmp     word ptr [esp + 4]

And with -O1 it compiles to:

67 66 FF 54 24 10    call dword ptr [esp + 0x10]


To summarize: I think it would be more correct to always add 0x66 to all JMPs
with -m16.
  • [Bug target/124505] New: -m16... paul.emmerich at icloud dot com via Gcc-bugs

Reply via email to