How does the GNU toolchain decide to use near vs. short jump instructions?

Viewed 99

I've got some code that gcc (4.8.5, if it matters) compiles into nearly identical binary on two different machines except for one spot, where something in the toolchain on one machine decides to use a "near" JE instruction while the toolchain on the other machine decides to use a "short" JE instruction:

41e274:   85 ed                   test   %ebp,%ebp          41e274:   85 ed                   test   %ebp,%ebp
41e276:   0f 84 14 00 00 00       je     41e290         |   41e276:   74 18                   je     41e290
41e27c:   31 ed                   xor    %ebp,%ebp      |   41e278:   31 ed                   xor    %ebp,%ebp
41e27e:   48 81 c4 30 01 00 00    add    $0x130,%rsp    |   41e27a:   48 81 c4 30 01 00 00    add    $0x130,%rsp
41e285:   89 e8                   mov    %ebp,%eax      |   41e281:   89 e8                   mov    %ebp,%eax
41e287:   5b                      pop    %rbx           |   41e283:   5b                      pop    %rbx
41e288:   5d                      pop    %rbp           |   41e284:   5d                      pop    %rbp
41e289:   41 5c                   pop    %r12           |   41e285:   41 5c                   pop    %r12
41e28b:   c3                      retq                  |   41e287:   c3                      retq
41e28c:   0f 1f 40 00             nopl   0x0(%rax)      |   41e288:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,
                                                        >   41e28f:   00
41e290:   48 8d 7c 24 60          lea    0x60(%rsp),%rdi    41e290:   48 8d 7c 24 60          lea    0x60(%rsp),%rdi

I'm assuming this is some sort of optimization (though I'm unclear as to whether it's the compiler or assembler that is being clever).

The odd thing, though, is that (in the same object file) there are other "nearby je branches" (to less than 40 or so bytes away) that are not similarly optimized to the single byte opcode:

c320:   45 85 ed                test   %r13d,%r13d          c320:   45 85 ed                test   %r13d,%r13d
c323:   0f 84 17 00 00 00       je     c340                 c323:   0f 84 17 00 00 00       je     c340
c329:   45 31 ed                xor    %r13d,%r13d          c329:   45 31 ed                xor    %r13d,%r13d
c32c:   48 81 c4 30 01 00 00    add    $0x130,%rsp          c32c:   48 81 c4 30 01 00 00    add    $0x130,%rsp
c333:   44 89 e8                mov    %r13d,%eax           c333:   44 89 e8                mov    %r13d,%eax
c336:   5b                      pop    %rbx                 c336:   5b                      pop    %rbx
c337:   5d                      pop    %rbp                 c337:   5d                      pop    %rbp
c338:   41 5c                   pop    %r12                 c338:   41 5c                   pop    %r12
c33a:   41 5d                   pop    %r13                 c33a:   41 5d                   pop    %r13
c33c:   41 5e                   pop    %r14                 c33c:   41 5e                   pop    %r14
c33e:   c3                      retq                        c33e:   c3                      retq   
c33f:   90                      nop                         c33f:   90                      nop 
c340:   4c 8d 74 24 60          lea    0x60(%rsp),%r14      c340:   4c 8d 74 24 60          lea    0x60(%rsp),%r14

Is there some parameter/configuration for gcc (or ld) that I can use to control this? I'd like to ensure that my code results in the same binary when compiled elsewhere.

0 Answers
Related