[llvm-commits] [llvm] r141274 - in /llvm/trunk: lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86RegisterInfo.td test/MC/X86/x86-32.s test/MC/X86/x86-64.s utils/TableGen/EDEmitter.cpp utils/TableGen/X86RecognizableInstr.cpp

Craig Topper craig.topper at gmail.com
Fri Oct 7 00:25:58 PDT 2011


In 64-bit mode, xchg %eax, %eax shoud not be a NOP. Just like all
instructions that write EAX in 64-bit mode, the upper 32-bits of RAX need to
be cleared. This means the operation needs to have an effect that the NOP
encoding won't have. So we need to use 0x87 0xc0 to create the appropriate
affect.

2011/10/7 Török Edwin <edwintorok at gmail.com>

> On 10/07/2011 01:24 AM, Eli Friedman wrote:
> > On Wed, Oct 5, 2011 at 11:44 PM, Craig Topper <craig.topper at gmail.com>
> wrote:
> >> Author: ctopper
> >> Date: Thu Oct  6 01:44:41 2011
> >> New Revision: 141274
> >>
> >> URL: http://llvm.org/viewvc/llvm-project?rev=141274&view=rev
> >> Log:
> >> 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 <reg>, %eax.
> >>
> >> Modified:
> >>    llvm/trunk/lib/Target/X86/X86InstrInfo.td
> >>    llvm/trunk/lib/Target/X86/X86RegisterInfo.td
> >>    llvm/trunk/test/MC/X86/x86-32.s
> >>    llvm/trunk/test/MC/X86/x86-64.s
> >>    llvm/trunk/utils/TableGen/EDEmitter.cpp
> >>    llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp
> >>
> >> Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
> >> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=141274&r1=141273&r2=141274&view=diff
> >>
> ==============================================================================
> >> --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
> >> +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Oct  6 01:44:41 2011
> >> @@ -1154,11 +1154,11 @@
> >>                   "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<"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 <reg>, %eax" and "xchgX %eax, <reg>" 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)>;
> >>
> >> Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td
> >> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=141274&r1=141273&r2=141274&view=diff
> >>
> ==============================================================================
> >> --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original)
> >> +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Thu Oct  6 01:44:41
> 2011
> >> @@ -390,6 +390,23 @@
> >>                        (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)];
> >>
> >> Modified: llvm/trunk/test/MC/X86/x86-32.s
> >> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-32.s?rev=141274&r1=141273&r2=141274&view=diff
> >>
> ==============================================================================
> >> --- llvm/trunk/test/MC/X86/x86-32.s (original)
> >> +++ llvm/trunk/test/MC/X86/x86-32.s Thu Oct  6 01:44:41 2011
> >> @@ -946,3 +946,19 @@
> >>  // 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
> >
> > Is this really correct for x86-32?  On my system, binutils prefers
> > 0x90 on x86-32, and 0x87,0xc0 on x86-64.
>
> How is xchg %eax, %eax different from a nop?
> They both do nothing...
>
> Best regards,
> --Edwin
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>



-- 
~Craig
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20111007/8ed97a77/attachment.html>


More information about the llvm-commits mailing list