From e5e4ff974df52aa870085904b6670c4d22ada0ac Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 20 May 2010 16:16:00 +0000 Subject: [PATCH] Fix assembly parsing and encoding of the pushf and popf family of instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104231 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/AsmParser/X86AsmParser.cpp | 17 +++++++++++++++++ lib/Target/X86/X86Instr64bit.td | 6 ++++-- lib/Target/X86/X86InstrInfo.cpp | 8 ++++---- lib/Target/X86/X86InstrInfo.td | 10 ++++++---- test/MC/AsmParser/X86/x86_32-bit_cat.s | 12 ++++++++++++ test/MC/AsmParser/X86/x86_32-new-encoder.s | 9 +++++++++ test/MC/AsmParser/X86/x86_64-new-encoder.s | 8 ++++++++ 7 files changed, 60 insertions(+), 10 deletions(-) diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 2c227b90662..e6d546b33e7 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -535,6 +535,21 @@ X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) { bool X86ATTAsmParser:: ParseInstruction(const StringRef &Name, SMLoc NameLoc, SmallVectorImpl &Operands) { + // The various flavors of pushf and popf use Requires and + // Requires, 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)); diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td index 8b17f6f3d42..532a25f52d3 100644 --- a/lib/Target/X86/X86Instr64bit.td +++ b/lib/Target/X86/X86Instr64bit.td @@ -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), diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index cb6cad3e634..4713649562a 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -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; } } diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index a767b54f962..502921647f8 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -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 diff --git a/test/MC/AsmParser/X86/x86_32-bit_cat.s b/test/MC/AsmParser/X86/x86_32-bit_cat.s index c1efe293c00..9002c604887 100644 --- a/test/MC/AsmParser/X86/x86_32-bit_cat.s +++ b/test/MC/AsmParser/X86/x86_32-bit_cat.s @@ -163,6 +163,18 @@ // CHECK: popw 32493 popw 0x7eed +// CHECK: pushf + pushfl + +// CHECK: pushfl + pushfl + +// CHECK: popf + popfl + +// CHECK: popfl + popfl + // CHECK: clc clc diff --git a/test/MC/AsmParser/X86/x86_32-new-encoder.s b/test/MC/AsmParser/X86/x86_32-new-encoder.s index 6c087761671..1c02f8823af 100644 --- a/test/MC/AsmParser/X86/x86_32-new-encoder.s +++ b/test/MC/AsmParser/X86/x86_32-new-encoder.s @@ -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 diff --git a/test/MC/AsmParser/X86/x86_64-new-encoder.s b/test/MC/AsmParser/X86/x86_64-new-encoder.s index f119eaa2105..bc8ad21ba72 100644 --- a/test/MC/AsmParser/X86/x86_64-new-encoder.s +++ b/test/MC/AsmParser/X86/x86_64-new-encoder.s @@ -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 -- 2.34.1