Skip to content

Commit 5aebebe

Browse files
committed
Revert part of r141274. Only need to change encoding for xchg %eax, %eax in 64-bit mode. This is because in 64-bit mode xchg %eax, %eax implies zeroing the upper 32-bits of RAX which makes it not a NOP. In 32-bit mode using NOP encoding is fine.
llvm-svn: 141353
1 parent c26e445 commit 5aebebe

File tree

5 files changed

+21
-25
lines changed

5 files changed

+21
-25
lines changed

llvm/lib/Target/X86/X86InstrInfo.td

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,11 +1154,15 @@ def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
11541154
"xchg{q}\t{$val, $src|$src, $val}", []>;
11551155
}
11561156

1157-
def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16_NOAX:$src),
1157+
def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
11581158
"xchg{w}\t{$src, %ax|AX, $src}", []>, OpSize;
1159-
def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1160-
"xchg{l}\t{$src, %eax|EAX, $src}", []>;
1161-
def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64_NOAX:$src),
1159+
def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1160+
"xchg{l}\t{$src, %eax|EAX, $src}", []>, Requires<[In32BitMode]>;
1161+
// Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1162+
// xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1163+
def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1164+
"xchg{l}\t{$src, %eax|EAX, $src}", []>, Requires<[In64BitMode]>;
1165+
def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
11621166
"xchg{q}\t{$src, %rax|RAX, $src}", []>;
11631167

11641168

@@ -1716,6 +1720,7 @@ def : InstAlias<"xchgl $mem, $val", (XCHG32rm GR32:$val, i32mem:$mem)>;
17161720
def : InstAlias<"xchgq $mem, $val", (XCHG64rm GR64:$val, i64mem:$mem)>;
17171721

17181722
// xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
1719-
def : InstAlias<"xchgw %ax, $src", (XCHG16ar GR16_NOAX:$src)>;
1720-
def : InstAlias<"xchgl %eax, $src", (XCHG32ar GR32_NOAX:$src)>;
1721-
def : InstAlias<"xchgq %rax, $src", (XCHG64ar GR64_NOAX:$src)>;
1723+
def : InstAlias<"xchgw %ax, $src", (XCHG16ar GR16:$src)>;
1724+
def : InstAlias<"xchgl %eax, $src", (XCHG32ar GR32:$src)>, Requires<[In32BitMode]>;
1725+
def : InstAlias<"xchgl %eax, $src", (XCHG32ar64 GR32_NOAX:$src)>, Requires<[In64BitMode]>;
1726+
def : InstAlias<"xchgq %rax, $src", (XCHG64ar GR64:$src)>;

llvm/lib/Target/X86/X86RegisterInfo.td

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -390,21 +390,11 @@ def GR64_NOREX : RegisterClass<"X86", [i64], 64,
390390
(GR32_NOREX sub_32bit)];
391391
}
392392

393-
// GR16_NOAX - GR16 registers except AX.
394-
def GR16_NOAX : RegisterClass<"X86", [i16], 16, (sub GR16, AX)> {
395-
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi)];
396-
}
397-
398-
// GR32_NOAX - GR32 registers except EAX.
393+
// GR32_NOAX - GR32 registers except EAX. Used by AddRegFrm of XCHG32 in 64-bit
394+
// mode to prevent encoding using the 0x90 NOP encoding. xchg %eax, %eax needs
395+
// to clear upper 32-bits of RAX so is not a NOP.
399396
def GR32_NOAX : RegisterClass<"X86", [i32], 32, (sub GR32, EAX)> {
400-
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16_NOAX sub_16bit)];
401-
}
402-
403-
// GR64_NOAX - GR64 registers except RAX.
404-
def GR64_NOAX : RegisterClass<"X86", [i64], 64, (sub GR64, RAX)> {
405-
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi),
406-
(GR16_NOAX sub_16bit),
407-
(GR32_NOAX sub_32bit)];
397+
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)];
408398
}
409399

410400
// GR32_NOSP - GR32 registers except ESP.

llvm/test/MC/X86/x86-32.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -948,11 +948,11 @@ fsubp %st, %st(2)
948948

949949
// PR10345
950950
// CHECK: xchgl %eax, %eax
951-
// CHECK: encoding: [0x87,0xc0]
951+
// CHECK: encoding: [0x90]
952952
xchgl %eax, %eax
953953

954954
// CHECK: xchgw %ax, %ax
955-
// CHECK: encoding: [0x66,0x87,0xc0]
955+
// CHECK: encoding: [0x66,0x90]
956956
xchgw %ax, %ax
957957

958958
// CHECK: xchgl %ecx, %eax

llvm/test/MC/X86/x86-64.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,15 +1173,15 @@ pclmulqdq $0, (%rdi), %xmm1
11731173

11741174
// PR10345
11751175
// CHECK: xchgq %rax, %rax
1176-
// CHECK: encoding: [0x48,0x87,0xc0]
1176+
// CHECK: encoding: [0x48,0x90]
11771177
xchgq %rax, %rax
11781178

11791179
// CHECK: xchgl %eax, %eax
11801180
// CHECK: encoding: [0x87,0xc0]
11811181
xchgl %eax, %eax
11821182

11831183
// CHECK: xchgw %ax, %ax
1184-
// CHECK: encoding: [0x66,0x87,0xc0]
1184+
// CHECK: encoding: [0x66,0x90]
11851185
xchgw %ax, %ax
11861186

11871187
// CHECK: xchgl %ecx, %eax

llvm/utils/TableGen/X86DisassemblerTables.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,7 @@ void DisassemblerTables::setTableFields(ModRMDecision &decision,
620620

621621
if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" ||
622622
newInfo.name == "XCHG32ar" ||
623+
newInfo.name == "XCHG32ar64" ||
623624
newInfo.name == "XCHG64ar"))
624625
continue; // special case for XCHG*ar and NOOP
625626

0 commit comments

Comments
 (0)