Fix assembly parsing and encoding of the pushf and popf family of

instructions.

llvm-svn: 104231
This commit is contained in:
Dan Gohman 2010-05-20 16:16:00 +00:00
parent 265b8b8de0
commit 29790edb93
7 changed files with 60 additions and 10 deletions

View 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));

View 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),

View 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;
}
}

View 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

View File

@ -163,6 +163,18 @@
// CHECK: popw 32493
popw 0x7eed
// CHECK: pushf
pushfl
// CHECK: pushfl
pushfl
// CHECK: popf
popfl
// CHECK: popfl
popfl
// CHECK: clc
clc

View 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

View 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