Fix assembly parsing and encoding of the pushf and popf family of
authorDan Gohman <gohman@apple.com>
Thu, 20 May 2010 16:16:00 +0000 (16:16 +0000)
committerDan Gohman <gohman@apple.com>
Thu, 20 May 2010 16:16:00 +0000 (16:16 +0000)
instructions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104231 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/AsmParser/X86AsmParser.cpp
lib/Target/X86/X86Instr64bit.td
lib/Target/X86/X86InstrInfo.cpp
lib/Target/X86/X86InstrInfo.td
test/MC/AsmParser/X86/x86_32-bit_cat.s
test/MC/AsmParser/X86/x86_32-new-encoder.s
test/MC/AsmParser/X86/x86_64-new-encoder.s

index 2c227b9066225a2fd39e2e2abd978f2dba183463..e6d546b33e7b35a1e789bb9963bb95435cceb455 100644 (file)
@@ -535,6 +535,21 @@ X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
 bool X86ATTAsmParser::
 ParseInstruction(const StringRef &Name, SMLoc NameLoc,
                  SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  // The various flavors of pushf and popf use Requires<In32BitMode> and
+  // Requires<In64BitMode>, but the assembler doesn't yet implement that.
+  // For now, just do a manual check to prevent silent misencoding.
+  if (Is64Bit) {
+    if (Name == "popfl")
+      return Error(NameLoc, "popfl cannot be encoded in 64-bit mode");
+    else if (Name == "pushfl")
+      return Error(NameLoc, "pushfl cannot be encoded in 64-bit mode");
+  } else {
+    if (Name == "popfq")
+      return Error(NameLoc, "popfq cannot be encoded in 32-bit mode");
+    else if (Name == "pushfq")
+      return Error(NameLoc, "pushfq cannot be encoded in 32-bit mode");
+  }
+
   // FIXME: Hack to recognize "sal..." and "rep..." for now. We need a way to
   // represent alternative syntaxes in the .td file, without requiring
   // instruction duplication.
@@ -547,6 +562,8 @@ ParseInstruction(const StringRef &Name, SMLoc NameLoc,
     .Case("repe", "rep")
     .Case("repz", "rep")
     .Case("repnz", "repne")
+    .Case("pushf", Is64Bit ? "pushfq" : "pushfl")
+    .Case("popf",  Is64Bit ? "popfq"  : "popfl")
     .Default(Name);
   Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
 
index 8b17f6f3d423f96dcc209cfbf4114f718ac32f04..532a25f52d3d8d918614652301ecd18de38800f1 100644 (file)
@@ -275,9 +275,11 @@ def PUSH64i32  : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
 }
 
 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, neverHasSideEffects=1 in
-def POPFQ    : I<0x9D, RawFrm, (outs), (ins), "popf{q}", []>, REX_W;
+def POPF64   : I<0x9D, RawFrm, (outs), (ins), "popfq", []>,
+               Requires<[In64BitMode]>;
 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, neverHasSideEffects=1 in
-def PUSHFQ64   : I<0x9C, RawFrm, (outs), (ins), "pushf{q}", []>;
+def PUSHF64    : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>,
+                 Requires<[In64BitMode]>;
 
 def LEA64_32r : I<0x8D, MRMSrcMem,
                   (outs GR32:$dst), (ins lea64_32mem:$src),
index cb6cad3e6348c293ad0be01fe3da6c3413a2c774..4713649562a9d6cb5d9d4c5291f428decbd0683a 100644 (file)
@@ -1993,12 +1993,12 @@ bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
     if (SrcReg != X86::EFLAGS)
       return false;
     if (DestRC == &X86::GR64RegClass || DestRC == &X86::GR64_NOSPRegClass) {
-      BuildMI(MBB, MI, DL, get(X86::PUSHFQ64));
+      BuildMI(MBB, MI, DL, get(X86::PUSHF64));
       BuildMI(MBB, MI, DL, get(X86::POP64r), DestReg);
       return true;
     } else if (DestRC == &X86::GR32RegClass ||
                DestRC == &X86::GR32_NOSPRegClass) {
-      BuildMI(MBB, MI, DL, get(X86::PUSHFD));
+      BuildMI(MBB, MI, DL, get(X86::PUSHF32));
       BuildMI(MBB, MI, DL, get(X86::POP32r), DestReg);
       return true;
     }
@@ -2007,12 +2007,12 @@ bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
       return false;
     if (SrcRC == &X86::GR64RegClass || DestRC == &X86::GR64_NOSPRegClass) {
       BuildMI(MBB, MI, DL, get(X86::PUSH64r)).addReg(SrcReg);
-      BuildMI(MBB, MI, DL, get(X86::POPFQ));
+      BuildMI(MBB, MI, DL, get(X86::POPF64));
       return true;
     } else if (SrcRC == &X86::GR32RegClass ||
                DestRC == &X86::GR32_NOSPRegClass) {
       BuildMI(MBB, MI, DL, get(X86::PUSH32r)).addReg(SrcReg);
-      BuildMI(MBB, MI, DL, get(X86::POPFD));
+      BuildMI(MBB, MI, DL, get(X86::POPF32));
       return true;
     }
   }
index a767b54f9621ee3e78f57fc688c2579deb714e22..502921647f8aad76370642a2361f3e87a885d12b 100644 (file)
@@ -775,12 +775,14 @@ def PUSHi32  : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
 }
 
 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, neverHasSideEffects=1 in {
-def POPF     : I<0x9D, RawFrm, (outs), (ins), "popf{w}", []>, OpSize;
-def POPFD    : I<0x9D, RawFrm, (outs), (ins), "popf{l}", []>;
+def POPF16   : I<0x9D, RawFrm, (outs), (ins), "popf{w}", []>, OpSize;
+def POPF32   : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", []>,
+               Requires<[In32BitMode]>;
 }
 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, neverHasSideEffects=1 in {
-def PUSHF    : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", []>, OpSize;
-def PUSHFD   : I<0x9C, RawFrm, (outs), (ins), "pushf{l}", []>;
+def PUSHF16  : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", []>, OpSize;
+def PUSHF32  : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", []>,
+               Requires<[In32BitMode]>;
 }
 
 let isTwoAddress = 1 in                               // GR32 = bswap GR32
index c1efe293c00ad7ef4382e61b00ef4c6fca01886a..9002c604887bd117e1c4dfa98d35048ed44ebec5 100644 (file)
 // CHECK:      popw    32493
                popw    0x7eed
 
+// CHECK:      pushf
+               pushfl
+
+// CHECK:      pushfl
+               pushfl
+
+// CHECK:      popf
+               popfl
+
+// CHECK:      popfl
+               popfl
+
 // CHECK:      clc
                clc
 
index 6c087761671ec604c1895e8fd7bda123dacd0bea..1c02f8823af8ed32904905657576fdf630d8680f 100644 (file)
@@ -75,3 +75,12 @@ int $4
 int $255
 // CHECK: int $255
 // CHECK:  encoding: [0xcd,0xff]
+
+// CHECK: pushfl       # encoding: [0x9c]
+        pushf
+// CHECK: pushfl       # encoding: [0x9c]
+        pushfl
+// CHECK: popfl                # encoding: [0x9d]
+        popf
+// CHECK: popfl                # encoding: [0x9d]
+        popfl
index f119eaa21058cd645b4a690dd9e39b95e47c9237..bc8ad21ba728ed9caa2b396cc4f0e4a787475e6f 100644 (file)
@@ -76,3 +76,11 @@ movb 0, %al    // CHECK: movb 0, %al # encoding: [0x8a,0x04,0x25,A,A,A,A]
 movw   0, %ax    // CHECK: movw 0, %ax # encoding: [0x66,0x8b,0x04,0x25,A,A,A,A]
 movl   0, %eax   // CHECK: movl 0, %eax # encoding: [0x8b,0x04,0x25,A,A,A,A]
 
+// CHECK: pushfq       # encoding: [0x9c]
+        pushf
+// CHECK: pushfq       # encoding: [0x9c]
+        pushfq
+// CHECK: popfq                # encoding: [0x9d]
+        popf
+// CHECK: popfq                # encoding: [0x9d]
+        popfq