From: David Woodhouse Date: Wed, 22 Jan 2014 15:08:27 +0000 (+0000) Subject: [x86] Allow address-size overrides for SCAS{8,16,32,64} (PR9385) X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6abfcfe1555fb8e95eb7b2c3189785b9e5ed817d;p=oota-llvm.git [x86] Allow address-size overrides for SCAS{8,16,32,64} (PR9385) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199805 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 503ae9b6f51..345c57c8b23 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2361,6 +2361,14 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, Name == "stosl" || Name == "stosd" || Name == "stosq")) Operands.push_back(DefaultMemDIOperand(NameLoc)); + // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate + // values of $DIREG according to the mode. It would be nice if this + // could be achieved with InstAlias in the tables. + if (Name.startswith("scas") && Operands.size() == 1 && + (Name == "scas" || Name == "scasb" || Name == "scasw" || + Name == "scasl" || Name == "scasd" || Name == "scasq")) + Operands.push_back(DefaultMemDIOperand(NameLoc)); + // FIXME: Hack to handle recognize s{hr,ar,hl} $1, . Canonicalize to // "shift ". if ((Name.startswith("shr") || Name.startswith("sar") || diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index c7e44232971..296da6cf184 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -1157,11 +1157,14 @@ let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI,EFLAGS] in def STOSQ : RI<0xAB, RawFrmDst, (outs dstidx64:$dst), (ins), "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>; -def SCAS8 : I<0xAE, RawFrm, (outs), (ins), "scasb", [], IIC_SCAS>; -def SCAS16 : I<0xAF, RawFrm, (outs), (ins), "scasw", [], IIC_SCAS>, OpSize; -def SCAS32 : I<0xAF, RawFrm, (outs), (ins), "scas{l|d}", [], IIC_SCAS>, - OpSize16; -def SCAS64 : RI<0xAF, RawFrm, (outs), (ins), "scasq", [], IIC_SCAS>; +def SCAS8 : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst), + "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>; +def SCAS16 : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst), + "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize; +def SCAS32 : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst), + "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize16; +def SCAS64 : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst), + "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>; def CMPS8 : I<0xA6, RawFrm, (outs), (ins), "cmpsb", [], IIC_CMPS>; def CMPS16 : I<0xA7, RawFrm, (outs), (ins), "cmpsw", [], IIC_CMPS>, OpSize; @@ -2432,6 +2435,18 @@ def : InstAlias<"stos {%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>; def : InstAlias<"stos {%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>; def : InstAlias<"stos {%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>; +// scas aliases. Accept the destination being omitted because it's implicit +// in the mnemonic, or the mnemonic suffix being omitted because it's implicit +// in the destination. +def : InstAlias<"scasb $dst", (SCAS8 dstidx8:$dst), 0>; +def : InstAlias<"scasw $dst", (SCAS16 dstidx16:$dst), 0>; +def : InstAlias<"scas{l|d} $dst", (SCAS32 dstidx32:$dst), 0>; +def : InstAlias<"scasq $dst", (SCAS64 dstidx64:$dst), 0>, Requires<[In64BitMode]>; +def : InstAlias<"scas {$dst, %al|al, $dst}", (SCAS8 dstidx8:$dst), 0>; +def : InstAlias<"scas {$dst, %ax|ax, $dst}", (SCAS16 dstidx16:$dst), 0>; +def : InstAlias<"scas {$dst, %eax|eax, $dst}", (SCAS32 dstidx32:$dst), 0>; +def : InstAlias<"scas {$dst, %rax|rax, $dst}", (SCAS64 dstidx64:$dst), 0>, Requires<[In64BitMode]>; + // div and idiv aliases for explicit A register. def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>; def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>; diff --git a/test/MC/X86/index-operations.s b/test/MC/X86/index-operations.s index ffad9596c83..f1ccfe817cd 100644 --- a/test/MC/X86/index-operations.s +++ b/test/MC/X86/index-operations.s @@ -74,3 +74,23 @@ stos %rax, (%edi) // 64: stosq %rax, %es:(%edi) # encoding: [0x48,0x67,0xab] // ERR32: only available in 64-bit mode // ERR16: only available in 64-bit mode + +scas %es:(%edi), %al +// 64: scasb %es:(%edi), %al # encoding: [0x67,0xae] +// 32: scasb %es:(%edi), %al # encoding: [0xae] +// 16: scasb %es:(%edi), %al # encoding: [0x67,0xae] + +scasq %es:(%edi) +// 64: scasq %es:(%edi), %rax # encoding: [0x48,0x67,0xaf] +// ERR32: 64-bit +// ERR16: 64-bit + +scasl %es:(%edi), %al +// ERR64: invalid operand +// ERR32: invalid operand +// ERR16: invalid operand + +scas %es:(%di), %ax +// ERR64: invalid 16-bit base register +// 16: scasw %es:(%di), %ax # encoding: [0xaf] +// 32: scasw %es:(%di), %ax # encoding: [0x66,0x67,0xaf]