From 7ea16b01fad5236cc132cb5fc3e443fcbf70d3b8 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 6 Oct 2011 06:44:41 +0000 Subject: Fix assembling of xchg %eax, %eax to not use the NOP encoding of 0x90. This was done by creating a new register group that excludes AX registers. Fixes PR10345. Also added aliases for flipping the order of the operands of xchg , %eax. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141274 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86InstrInfo.td | 11 ++++++++--- lib/Target/X86/X86RegisterInfo.td | 17 +++++++++++++++++ test/MC/X86/x86-32.s | 16 ++++++++++++++++ test/MC/X86/x86-64.s | 21 +++++++++++++++++++++ utils/TableGen/EDEmitter.cpp | 3 +++ utils/TableGen/X86RecognizableInstr.cpp | 6 ++++++ 6 files changed, 71 insertions(+), 3 deletions(-) diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 61e4b57a85..03a9a332ce 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -1154,11 +1154,11 @@ def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src), "xchg{q}\t{$val, $src|$src, $val}", []>; } -def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src), +def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16_NOAX:$src), "xchg{w}\t{$src, %ax|AX, $src}", []>, OpSize; -def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src), +def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src), "xchg{l}\t{$src, %eax|EAX, $src}", []>; -def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src), +def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64_NOAX:$src), "xchg{q}\t{$src, %rax|RAX, $src}", []>; @@ -1714,3 +1714,8 @@ def : InstAlias<"xchgb $mem, $val", (XCHG8rm GR8 :$val, i8mem :$mem)>; def : InstAlias<"xchgw $mem, $val", (XCHG16rm GR16:$val, i16mem:$mem)>; def : InstAlias<"xchgl $mem, $val", (XCHG32rm GR32:$val, i32mem:$mem)>; def : InstAlias<"xchgq $mem, $val", (XCHG64rm GR64:$val, i64mem:$mem)>; + +// xchg: We accept "xchgX , %eax" and "xchgX %eax, " as synonyms. +def : InstAlias<"xchgw %ax, $src", (XCHG16ar GR16_NOAX:$src)>; +def : InstAlias<"xchgl %eax, $src", (XCHG32ar GR32_NOAX:$src)>; +def : InstAlias<"xchgq %rax, $src", (XCHG64ar GR64_NOAX:$src)>; diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index 14d1e87c03..3f81d3b65a 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -390,6 +390,23 @@ def GR64_NOREX : RegisterClass<"X86", [i64], 64, (GR32_NOREX sub_32bit)]; } +// GR16_NOAX - GR16 registers except AX. +def GR16_NOAX : RegisterClass<"X86", [i16], 16, (sub GR16, AX)> { + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi)]; +} + +// GR32_NOAX - GR32 registers except EAX. +def GR32_NOAX : RegisterClass<"X86", [i32], 32, (sub GR32, EAX)> { + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16_NOAX sub_16bit)]; +} + +// GR64_NOAX - GR64 registers except RAX. +def GR64_NOAX : RegisterClass<"X86", [i64], 64, (sub GR64, RAX)> { + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), + (GR16_NOAX sub_16bit), + (GR32_NOAX sub_32bit)]; +} + // GR32_NOSP - GR32 registers except ESP. def GR32_NOSP : RegisterClass<"X86", [i32], 32, (sub GR32, ESP)> { let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)]; diff --git a/test/MC/X86/x86-32.s b/test/MC/X86/x86-32.s index 60178801ef..41226474a7 100644 --- a/test/MC/X86/x86-32.s +++ b/test/MC/X86/x86-32.s @@ -946,3 +946,19 @@ fsubp %st,%st(1) // CHECK: encoding: [0xde,0xe2] fsubp %st, %st(2) +// PR10345 +// CHECK: xchgl %eax, %eax +// CHECK: encoding: [0x87,0xc0] +xchgl %eax, %eax + +// CHECK: xchgw %ax, %ax +// CHECK: encoding: [0x66,0x87,0xc0] +xchgw %ax, %ax + +// CHECK: xchgl %ecx, %eax +// CHECK: encoding: [0x91] +xchgl %ecx, %eax + +// CHECK: xchgl %ecx, %eax +// CHECK: encoding: [0x91] +xchgl %eax, %ecx diff --git a/test/MC/X86/x86-64.s b/test/MC/X86/x86-64.s index 6f828e815d..23fa54f0d6 100644 --- a/test/MC/X86/x86-64.s +++ b/test/MC/X86/x86-64.s @@ -1170,3 +1170,24 @@ pclmullqhqdq (%rdi), %xmm1 // CHECK: pclmulqdq $0, (%rdi), %xmm1 // CHECK: encoding: [0x66,0x0f,0x3a,0x44,0x0f,0x00] pclmulqdq $0, (%rdi), %xmm1 + +// PR10345 +// CHECK: xchgq %rax, %rax +// CHECK: encoding: [0x48,0x87,0xc0] +xchgq %rax, %rax + +// CHECK: xchgl %eax, %eax +// CHECK: encoding: [0x87,0xc0] +xchgl %eax, %eax + +// CHECK: xchgw %ax, %ax +// CHECK: encoding: [0x66,0x87,0xc0] +xchgw %ax, %ax + +// CHECK: xchgl %ecx, %eax +// CHECK: encoding: [0x91] +xchgl %ecx, %eax + +// CHECK: xchgl %ecx, %eax +// CHECK: encoding: [0x91] +xchgl %eax, %ecx diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 85f7e1f26c..b5fe7e6e1a 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -256,12 +256,15 @@ static int X86TypeFromOpName(LiteralConstantEmitter *type, REG("GR8"); REG("GR8_NOREX"); REG("GR16"); + REG("GR16_NOAX"); REG("GR32"); + REG("GR32_NOAX"); REG("GR32_NOREX"); REG("GR32_TC"); REG("FR32"); REG("RFP32"); REG("GR64"); + REG("GR64_NOAX"); REG("GR64_TC"); REG("FR64"); REG("VR64"); diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index f958966b81..ee9deb3628 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -1064,6 +1064,9 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("offset32", TYPE_MOFFS32) TYPE("offset64", TYPE_MOFFS64) TYPE("VR256", TYPE_XMM256) + TYPE("GR16_NOAX", TYPE_Rv) + TYPE("GR32_NOAX", TYPE_Rv) + TYPE("GR64_NOAX", TYPE_R64) errs() << "Unhandled type string " << s << "\n"; llvm_unreachable("Unhandled type string"); } @@ -1205,6 +1208,9 @@ OperandEncoding RecognizableInstr::opcodeModifierEncodingFromString ENCODING("GR64", ENCODING_RO) ENCODING("GR16", ENCODING_Rv) ENCODING("GR8", ENCODING_RB) + ENCODING("GR16_NOAX", ENCODING_Rv) + ENCODING("GR32_NOAX", ENCODING_Rv) + ENCODING("GR64_NOAX", ENCODING_RO) errs() << "Unhandled opcode modifier encoding " << s << "\n"; llvm_unreachable("Unhandled opcode modifier encoding"); } -- cgit v1.2.3