<html>
    <head>
      <base href="http://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - pushf/popf default to wrong operand size in 64-bit with Intel syntax"
   href="http://bugs.llvm.org/show_bug.cgi?id=32035">32035</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>pushf/popf default to wrong operand size in 64-bit with Intel syntax
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Backend: X86
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>mkuper@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider:

.intel_syntax noprefix
foo:
  pushf
  popf
  ret

$ gcc -c -x assembler ./foo.S -o foo.obj && objdump -d foo.obj 

foo.obj:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <foo>:
   0:   9c                      pushfq 
   1:   9d                      popfq  
   2:   c3                      retq   

$ bin/clang -c -x assembler ./foo.S -o foo.obj && objdump -d foo.obj 

foo.obj:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <foo>:
   0:   66 9c                   pushfw 
   2:   66 9d                   popfw  
   4:   c3                      retq   

While in 32-bit mode, the manual intentionally leaves the behavior ambiguous
(Some assemblers may force the operand size to 16 when PUSHF is used and to 32
when PUSHFD is used. Others may treat these mnemonics as synonyms
(PUSHF/PUSHFD) and use the current setting of the operand-size attribute to
determine the size of values to be pushed from the stack, regardless of the
mnemonic used), I'm fairly sure the intended reading for 64-bit mode is that an
unqualified pushf is pushfq.

In 32-bit mode, clang also uses the 16-bit version, while gcc uses 32-bit, and
even though this is technically allowed, we may want to fix that as well?

Amusingly, adding .code16 actually makes us do emit 64-bit pushfs:

.intel_syntax noprefix
.code16

foo:
  pushf
  popf
  ret

$ bin/clang -c -x assembler ./foo.S -o foo.obj && objdump -d foo.obj 

foo.obj:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <foo>:
   0:   9c                      pushfq 
   1:   9d                      popfq  
   2:   66 c3                   retw</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>