From 73a154cef6c3a6f52a50c486078c49db20172f6c Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 16 Jan 2018 06:07:16 +0000 Subject: [PATCH] [X86] Revisit the fix I made years ago to make 'xchgl %eax, %eax' not encode using the 0x90 encoding in 64-bit mode. Prior to this we had a separate instruction and register class that excluded eax to prevent matching the instruction that would encode with 0x90. This patch changes this to just use an InstAlias to force xchgl %eax, %eax to use XCHG32rr instruction in 64-bit mode. This gets rid of the separate instruction and register class. llvm-svn: 322532 --- lib/Target/X86/X86InstrInfo.td | 19 ++++++++----------- lib/Target/X86/X86RegisterInfo.td | 5 ----- utils/TableGen/X86RecognizableInstr.cpp | 2 -- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 2a29084eae5..14c1372cfef 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -1958,13 +1958,7 @@ def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src), let Uses = [EAX], Defs = [EAX] in def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src), "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>, - OpSize32, Requires<[Not64BitMode]>; -let Uses = [EAX], Defs = [EAX] in -// Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding. -// xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP. -def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src), - "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>, - OpSize32, Requires<[In64BitMode]>; + OpSize32; let Uses = [RAX], Defs = [RAX] in def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src), "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>; @@ -3304,12 +3298,15 @@ def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}", // xchg: We accept "xchgX , %eax" and "xchgX %eax, " as synonyms. def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>; -def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}", - (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>; -def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}", - (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>; +def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}", (XCHG32ar GR32:$src), 0>; def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>; +// In 64-bit mode, xchg %eax, %eax can't be encoded with the 0x90 opcode we +// would get by default because it's defined as NOP. But xchg %eax, %eax implies +// implicit zeroing of the upper 32 bits. So alias to the longer encoding. +def : InstAlias<"xchg{l}\t{%eax, %eax|eax, eax}", + (XCHG32rr EAX, EAX), 0>, Requires<[In64BitMode]>; + // xchg %rax, %rax is a nop in x86-64 and can be encoded as such. Without this // we emit an unneeded REX.w prefix. def : InstAlias<"xchg{q}\t{%rax, %rax|rax, rax}", (NOOP), 0>; diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index 2341e1fb0fa..ca508255c36 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -400,11 +400,6 @@ def GR32_NOREX : RegisterClass<"X86", [i32], 32, def GR64_NOREX : RegisterClass<"X86", [i64], 64, (add RAX, RCX, RDX, RSI, RDI, RBX, RBP, RSP, RIP)>; -// GR32_NOAX - GR32 registers except EAX. Used by AddRegFrm of XCHG32 in 64-bit -// mode to prevent encoding using the 0x90 NOP encoding. xchg %eax, %eax needs -// to clear upper 32-bits of RAX so is not a NOP. -def GR32_NOAX : RegisterClass<"X86", [i32], 32, (sub GR32, EAX)>; - // GR32_NOSP - GR32 registers except ESP. def GR32_NOSP : RegisterClass<"X86", [i32], 32, (sub GR32, ESP)>; diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index 9afdd7e0963..81cd12f92a5 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -927,7 +927,6 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("VK32WM", TYPE_VK) TYPE("VK64", TYPE_VK) TYPE("VK64WM", TYPE_VK) - TYPE("GR32_NOAX", TYPE_Rv) TYPE("vx64mem", TYPE_MVSIBX) TYPE("vx128mem", TYPE_MVSIBX) TYPE("vx256mem", TYPE_MVSIBX) @@ -1195,7 +1194,6 @@ RecognizableInstr::opcodeModifierEncodingFromString(const std::string &s, ENCODING("GR64", ENCODING_RO) ENCODING("GR16", ENCODING_Rv) ENCODING("GR8", ENCODING_RB) - ENCODING("GR32_NOAX", ENCODING_Rv) errs() << "Unhandled opcode modifier encoding " << s << "\n"; llvm_unreachable("Unhandled opcode modifier encoding"); }