Bug 172035

Summary: save 2 bytes for "movq $0x38,%rax"
Product: [Fedora] Fedora Reporter: John Reiser <jreiser>
Component: binutilsAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 4Keywords: FutureFeature
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-10-29 17:52:14 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description John Reiser 2005-10-29 17:23:18 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.12) Gecko/20050922 Fedora/1.0.7-1.1.fc4 Firefox/1.0.7

Description of problem:
The current generated code for "movq $0x38,%rax" is 7 bytes: 0x48,0xc7,0xc0,0x38,0,0,0.  Instead: 0xb8,0x38,0,0,0 is only 5 bytes, achieves exactly the same effects (value in %rax, and no change in condition codes [flag register]), and executes just as quickly.



Version-Release number of selected component (if applicable):
binutils-2.15.94.0.2.2-2.1

How reproducible:
Always

Steps to Reproduce:
1. Compare these variants:
-----foo.S
_start: .globl _start
        nop; int3
        movq $0x38,%rax
        movl $0x39,%ecx
        movq $-0x38,%rdx
        movl $-0x39,%ebx
        nop; nop
-----
$ gcc -o foo -nostartfiles -nostdlib foo.S
$ gdb foo
run
x/i $pc
x/2x $pc
stepi
p $rax
x/i $pc
x/2x $pc
stepi
p $rcx
x/i $pc
x/2x $pc
stepi
p $rdx
x/i $pc
x/2x $pc
stepi
p $rbx

2.
3.
  

Actual Results:  (gdb) x/i $pc
0x4000b2 <_start+2>:    mov    $0x38,%rax
(gdb) x/2x $pc
0x4000b2 <_start+2>:    0x38c0c748     0xb9000000
(gdb) stepi
0x00000000004000b9 in _start ()   ## instruction was 7 bytes
(gdb) p $rax
$1 = 0x38

(gdb) x/i $pc
0x4000b9 <_start+9>:    mov    $0x39,%ecx
(gdb) x/2x $pc
0x4000b9 <_start+9>:    0x000039b9      0xc2c74800
(gdb) stepi
0x00000000004000be in _start ()   ## instruction was 5 bytes
(gdb) p $rcx
$2 = 0x39


(gdb) x/i $pc
0x4000be <_start+14>:   mov    $0xffffffffffffffc8,%rdx
(gdb) x/2x $pc
0x4000b2 <_start+2>:    0x38c0c748      0xb9000000
(gdb) stepi
0x00000000004000c5 in _start ()   ## instruction was 7 bytes
(gdb) p $rdx
$3 = 0xffffffffffffffc8

(gdb) x/i $pc
0x4000c5 <_start+21>:   mov    $0xffffffc7,%ebx
(gdb) x/2x $pc
0x4000c5 <_start+21>:   0xffffc7bb      0x009090ff
(gdb) stepi
0x00000000004000ca in _start ()   ## instruction was 5 bytes
(gdb) p $rbx
$4 = 0xffffffc7


Expected Results:  The assembler should have chosen the 5-byte sequence "0xb8,0x38,0,0,0" for "movq $0x38,%rax" instead of the 7-byte sequence "0x48,0xc7,0xc0,0x38,0,0,0".

Additional info:

Comment 1 Jakub Jelinek 2005-10-29 17:52:14 UTC
When you want that, just write movl $0x38, %eax instead.
GCC does exactly that.

movq in x86_64 assembler is not "some instruction to move source to destination",
but a particular instruction, it would be very bad idea to do something
else, as code might e.g. rely on the instruction size.