forked from OSchip/llvm-project
Fix assembly parsing and encoding of the pushf and popf family of
instructions. llvm-svn: 104231
This commit is contained in:
parent
265b8b8de0
commit
29790edb93
|
@ -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));
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -163,6 +163,18 @@
|
|||
// CHECK: popw 32493
|
||||
popw 0x7eed
|
||||
|
||||
// CHECK: pushf
|
||||
pushfl
|
||||
|
||||
// CHECK: pushfl
|
||||
pushfl
|
||||
|
||||
// CHECK: popf
|
||||
popfl
|
||||
|
||||
// CHECK: popfl
|
||||
popfl
|
||||
|
||||
// CHECK: clc
|
||||
clc
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue