[llvm-commits] Support for explicit argument form of X86 string instructions

Joerg Sonnenberger joerg at britannica.bec.de
Mon Mar 14 08:38:27 PDT 2011


Ping.

On Mon, Mar 07, 2011 at 12:24:45AM +0100, Joerg Sonnenberger wrote:
> Hi all,
> the attached patch implements the various explicit argument forms of the
> X86 string instructions. They are used for documentation purposes, but
> the use of segment overrides make them hard to specify with the normal
> InstAlias syntax. This covers the ins, outs, movs, lods and stos family
> of instructions. For lods and stos, both the implicit and explicit size
> version is recognized.
> 
> Joerg

> Index: test/MC/X86/x86-32.s
> ===================================================================
> --- test/MC/X86/x86-32.s	(revision 126955)
> +++ test/MC/X86/x86-32.s	(working copy)
> @@ -816,3 +816,131 @@
>  // CHECK: loopne 0
>  // CHECK: encoding: [0xe0,A]
>  	loopnz 0
> +
> +// CHECK: outsb # encoding: [0x6e]
> +// CHECK: outsb
> +// CHECK: outsb
> +// CHECK: outsb
> +// CHECK: outsb
> +	outsb
> +	outsb	%ds:(%esi), (%dx)
> +	outsb	%ds:(%esi), %dx
> +	outsb	(%esi), (%dx)
> +	outsb	(%esi), %dx
> +
> +// CHECK: outsw # encoding: [0x66,0x6f]
> +// CHECK: outsw
> +// CHECK: outsw
> +// CHECK: outsw
> +// CHECK: outsw
> +	outsw
> +	outsw	%ds:(%esi), (%dx)
> +	outsw	%ds:(%esi), %dx
> +	outsw	(%esi), (%dx)
> +	outsw	(%esi), %dx
> +
> +// CHECK: outsl # encoding: [0x6f]
> +// CHECK: outsl
> +// CHECK: outsl
> +// CHECK: outsl
> +	outsl
> +	outsl	%ds:(%esi), (%dx)
> +	outsl	%ds:(%esi), %dx
> +	outsl	(%esi), (%dx)
> +	outsl	(%esi), %dx
> +
> +// CHECK: insb # encoding: [0x6c]
> +// CHECK: insb
> +// CHECK: insb
> +	insb
> +	insb	(%dx), %es:(%edi)
> +	insb	%dx, %es:(%edi)
> +
> +// CHECK: insw # encoding: [0x66,0x6d]
> +// CHECK: insw
> +// CHECK: insw
> +	insw
> +	insw	(%dx), %es:(%edi)
> +	insw	%dx, %es:(%edi)
> +
> +// CHECK: insl # encoding: [0x6d]
> +// CHECK: insl
> +// CHECK: insl
> +	insl
> +	insl	(%dx), %es:(%edi)
> +	insl	%dx, %es:(%edi)
> +
> +// CHECK: movsb # encoding: [0xa4]
> +// CHECK: movsb
> +// CHECK: movsb
> +	movsb
> +	movsb	%ds:(%esi), %es:(%edi)
> +	movsb	(%esi), %es:(%edi)
> +
> +// CHECK: movsw # encoding: [0x66,0xa5]
> +// CHECK: movsw
> +// CHECK: movsw
> +	movsw
> +	movsw	%ds:(%esi), %es:(%edi)
> +	movsw	(%esi), %es:(%edi)
> +
> +// CHECK: movsl # encoding: [0xa5]
> +// CHECK: movsl
> +// CHECK: movsl
> +	movsl
> +	movsl	%ds:(%esi), %es:(%edi)
> +	movsl	(%esi), %es:(%edi)
> +
> +// CHECK: lodsb # encoding: [0xac]
> +// CHECK: lodsb
> +// CHECK: lodsb
> +// CHECK: lodsb
> +// CHECK: lodsb
> +	lodsb
> +	lodsb	%ds:(%esi), %al
> +	lodsb	(%esi), %al
> +	lods	%ds:(%esi), %al
> +	lods	(%esi), %al
> +
> +// CHECK: lodsw # encoding: [0x66,0xad]
> +// CHECK: lodsw
> +// CHECK: lodsw
> +// CHECK: lodsw
> +// CHECK: lodsw
> +	lodsw
> +	lodsw	%ds:(%esi), %ax
> +	lodsw	(%esi), %ax
> +	lods	%ds:(%esi), %ax
> +	lods	(%esi), %ax
> +
> +// CHECK: lodsl # encoding: [0xad]
> +// CHECK: lodsl
> +// CHECK: lodsl
> +// CHECK: lodsl
> +// CHECK: lodsl
> +	lodsl
> +	lodsl	%ds:(%esi), %eax
> +	lodsl	(%esi), %eax
> +	lods	%ds:(%esi), %eax
> +	lods	(%esi), %eax
> +
> +// CHECK: stosb # encoding: [0xaa]
> +// CHECK: stosb
> +// CHECK: stosb
> +	stosb
> +	stosb	%al, %es:(%edi)
> +	stos	%al, %es:(%edi)
> +
> +// CHECK: stosw # encoding: [0x66,0xab]
> +// CHECK: stosw
> +// CHECK: stosw
> +	stosw
> +	stosw	%ax, %es:(%edi)
> +	stos	%ax, %es:(%edi)
> +
> +// CHECK: stosl # encoding: [0xab]
> +// CHECK: stosl
> +// CHECK: stosl
> +	stosl
> +	stosl	%eax, %es:(%edi)
> +	stos	%eax, %es:(%edi)
> Index: test/MC/X86/x86-64.s
> ===================================================================
> --- test/MC/X86/x86-64.s	(revision 126955)
> +++ test/MC/X86/x86-64.s	(working copy)
> @@ -973,3 +973,156 @@
>  // CHECK: loopne 0
>  // CHECK: encoding: [0xe0,A]
>  	loopnz 0
> +
> +// CHECK: outsb # encoding: [0x6e]
> +// CHECK: outsb
> +// CHECK: outsb
> +// CHECK: outsb
> +// CHECK: outsb
> +	outsb
> +	outsb	%ds:(%rsi), (%dx)
> +	outsb	%ds:(%rsi), %dx
> +	outsb	(%rsi), (%dx)
> +	outsb	(%rsi), %dx
> +
> +// CHECK: outsw # encoding: [0x66,0x6f]
> +// CHECK: outsw
> +// CHECK: outsw
> +// CHECK: outsw
> +// CHECK: outsw
> +	outsw
> +	outsw	%ds:(%rsi), (%dx)
> +	outsw	%ds:(%rsi), %dx
> +	outsw	(%rsi), (%dx)
> +	outsw	(%rsi), %dx
> +
> +// CHECK: outsl # encoding: [0x6f]
> +// CHECK: outsl
> +// CHECK: outsl
> +// CHECK: outsl
> +	outsl
> +	outsl	%ds:(%rsi), (%dx)
> +	outsl	%ds:(%rsi), %dx
> +	outsl	(%rsi), (%dx)
> +	outsl	(%rsi), %dx
> +
> +// CHECK: insb # encoding: [0x6c]
> +// CHECK: insb
> +// CHECK: insb
> +	insb
> +	insb	(%dx), %es:(%rdi)
> +	insb	%dx, %es:(%rdi)
> +
> +// CHECK: insw # encoding: [0x66,0x6d]
> +// CHECK: insw
> +// CHECK: insw
> +	insw
> +	insw	(%dx), %es:(%rdi)
> +	insw	%dx, %es:(%rdi)
> +
> +// CHECK: insl # encoding: [0x6d]
> +// CHECK: insl
> +// CHECK: insl
> +	insl
> +	insl	(%dx), %es:(%rdi)
> +	insl	%dx, %es:(%rdi)
> +
> +// CHECK: movsb # encoding: [0xa4]
> +// CHECK: movsb
> +// CHECK: movsb
> +	movsb
> +	movsb	%ds:(%rsi), %es:(%rdi)
> +	movsb	(%rsi), %es:(%rdi)
> +
> +// CHECK: movsw # encoding: [0x66,0xa5]
> +// CHECK: movsw
> +// CHECK: movsw
> +	movsw
> +	movsw	%ds:(%rsi), %es:(%rdi)
> +	movsw	(%rsi), %es:(%rdi)
> +
> +// CHECK: movsl # encoding: [0xa5]
> +// CHECK: movsl
> +// CHECK: movsl
> +	movsl
> +	movsl	%ds:(%rsi), %es:(%rdi)
> +	movsl	(%rsi), %es:(%rdi)
> +
> +// CHECK: movsq # encoding: [0x48,0xa5]
> +// CHECK: movsq
> +// CHECK: movsq
> +	movsq
> +	movsq	%ds:(%rsi), %es:(%rdi)
> +	movsq	(%rsi), %es:(%rdi)
> +
> +// CHECK: lodsb # encoding: [0xac]
> +// CHECK: lodsb
> +// CHECK: lodsb
> +// CHECK: lodsb
> +// CHECK: lodsb
> +	lodsb
> +	lodsb	%ds:(%rsi), %al
> +	lodsb	(%rsi), %al
> +	lods	%ds:(%rsi), %al
> +	lods	(%rsi), %al
> +
> +// CHECK: lodsw # encoding: [0x66,0xad]
> +// CHECK: lodsw
> +// CHECK: lodsw
> +// CHECK: lodsw
> +// CHECK: lodsw
> +	lodsw
> +	lodsw	%ds:(%rsi), %ax
> +	lodsw	(%rsi), %ax
> +	lods	%ds:(%rsi), %ax
> +	lods	(%rsi), %ax
> +
> +// CHECK: lodsl # encoding: [0xad]
> +// CHECK: lodsl
> +// CHECK: lodsl
> +// CHECK: lodsl
> +// CHECK: lodsl
> +	lodsl
> +	lodsl	%ds:(%rsi), %eax
> +	lodsl	(%rsi), %eax
> +	lods	%ds:(%rsi), %eax
> +	lods	(%rsi), %eax
> +
> +// CHECK: lodsq # encoding: [0x48,0xad]
> +// CHECK: lodsq
> +// CHECK: lodsq
> +// CHECK: lodsq
> +// CHECK: lodsq
> +	lodsq
> +	lodsq	%ds:(%rsi), %rax
> +	lodsq	(%rsi), %rax
> +	lods	%ds:(%rsi), %rax
> +	lods	(%rsi), %rax
> +
> +// CHECK: stosb # encoding: [0xaa]
> +// CHECK: stosb
> +// CHECK: stosb
> +	stosb
> +	stosb	%al, %es:(%rdi)
> +	stos	%al, %es:(%rdi)
> +
> +// CHECK: stosw # encoding: [0x66,0xab]
> +// CHECK: stosw
> +// CHECK: stosw
> +	stosw
> +	stosw	%ax, %es:(%rdi)
> +	stos	%ax, %es:(%rdi)
> +
> +// CHECK: stosl # encoding: [0xab]
> +// CHECK: stosl
> +// CHECK: stosl
> +	stosl
> +	stosl	%eax, %es:(%rdi)
> +	stos	%eax, %es:(%rdi)
> +
> +// CHECK: stosq # encoding: [0x48,0xab]
> +// CHECK: stosq
> +// CHECK: stosq
> +	stosq
> +	stosq	%rax, %es:(%rdi)
> +	stos	%rax, %es:(%rdi)
> Index: lib/Target/X86/AsmParser/X86AsmParser.cpp
> ===================================================================
> --- lib/Target/X86/AsmParser/X86AsmParser.cpp	(revision 126955)
> +++ lib/Target/X86/AsmParser/X86AsmParser.cpp	(working copy)
> @@ -38,6 +38,10 @@
>    unsigned Is64Bit : 1;
>  
>  private:
> +  bool isSrcOp(X86Operand &Op);
> +  bool isDstOp(X86Operand &Op);
> +  bool isPortDxOp(X86Operand &Op);
> +
>    MCAsmParser &getParser() const { return Parser; }
>  
>    MCAsmLexer &getLexer() const { return Parser.getLexer(); }
> @@ -356,7 +360,32 @@
>  
>  } // end anonymous namespace.
>  
> +bool X86ATTAsmParser::isSrcOp(X86Operand &Op) {
> +  unsigned basereg = Is64Bit ? X86::RSI : X86::ESI;
>  
> +  return (Op.isMem() &&
> +    (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&
> +    isa<MCConstantExpr>(Op.Mem.Disp) &&
> +    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
> +    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0);
> +}
> +
> +bool X86ATTAsmParser::isDstOp(X86Operand &Op) {
> +  unsigned basereg = Is64Bit ? X86::RDI : X86::EDI;
> +
> +  return Op.isMem() && Op.Mem.SegReg == X86::ES &&
> +    isa<MCConstantExpr>(Op.Mem.Disp) &&
> +    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
> +    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0;
> +}
> +
> +bool X86ATTAsmParser::isPortDxOp(X86Operand &Op) {
> +  return Op.isMem() && Op.Mem.SegReg == 0 &&
> +    isa<MCConstantExpr>(Op.Mem.Disp) &&
> +    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
> +    Op.Mem.BaseReg == X86::DX && Op.Mem.IndexReg == 0;
> +}
> +
>  bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
>                                      SMLoc &StartLoc, SMLoc &EndLoc) {
>    RegNo = 0;
> @@ -788,7 +817,108 @@
>        delete &Op;
>      }
>    }
> -  
> +  // Transform "ins[bwl] (%dx), %es:(%edi)" into "ins[bwl]"
> +  if (Name.startswith("ins") && Operands.size() == 3 &&
> +      (Name == "insb" || Name == "insw" || Name == "insl")) {
> +    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
> +    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
> +    if ((isPortDxOp(Op) || (Op.isReg() && Op.getReg() == X86::DX)) &&
> +        isDstOp(Op2)) {
> +      Operands.pop_back();
> +      Operands.pop_back();
> +      delete &Op;
> +      delete &Op2;
> +    }
> +  }
> +
> +  // Transform "outs[bwl] %ds:(%esi), (%dx)" into "out[bwl]"
> +  if (Name.startswith("outs") && Operands.size() == 3 &&
> +      (Name == "outsb" || Name == "outsw" || Name == "outsl")) {
> +    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
> +    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
> +    if (isSrcOp(Op) &&
> +        (isPortDxOp(Op2) || (Op2.isReg() && Op2.getReg() == X86::DX))) {
> +      Operands.pop_back();
> +      Operands.pop_back();
> +      delete &Op;
> +      delete &Op2;
> +    }
> +  }
> +
> +  // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]"
> +  if (Name.startswith("movs") && Operands.size() == 3 &&
> +      (Name == "movsb" || Name == "movsw" || Name == "movsl" ||
> +       (Is64Bit && Name == "movsq"))) {
> +    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
> +    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
> +    if (isSrcOp(Op) && isDstOp(Op2)) {
> +      Operands.pop_back();
> +      Operands.pop_back();
> +      delete &Op;
> +      delete &Op2;
> +    }
> +  }
> +  // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]"
> +  if (Name.startswith("lods") && Operands.size() == 3 &&
> +      (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
> +       Name == "lodsl" || (Is64Bit && Name == "lodsq"))) {
> +    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
> +    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
> +    if (isSrcOp(*Op1) && Op2->isReg()) {
> +      const char *ins;
> +      unsigned reg = Op2->getReg();
> +      bool isLods = Name == "lods";
> +      if (reg == X86::AL && (isLods || Name == "lodsb"))
> +        ins = "lodsb";
> +      else if (reg == X86::AX && (isLods || Name == "lodsw"))
> +        ins = "lodsw";
> +      else if (reg == X86::EAX && (isLods || Name == "lodsl"))
> +        ins = "lodsl";
> +      else if (reg == X86::RAX && (isLods || Name == "lodsq"))
> +        ins = "lodsq";
> +      else
> +        ins = NULL;
> +      if (ins != NULL) {
> +        Operands.pop_back();
> +        Operands.pop_back();
> +        delete Op1;
> +        delete Op2;
> +        if (Name != ins)
> +          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
> +      }
> +    }
> +  }
> +  // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]"
> +  if (Name.startswith("stos") && Operands.size() == 3 &&
> +      (Name == "stos" || Name == "stosb" || Name == "stosw" ||
> +       Name == "stosl" || (Is64Bit && Name == "stosq"))) {
> +    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
> +    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
> +    if (isDstOp(*Op2) && Op1->isReg()) {
> +      const char *ins;
> +      unsigned reg = Op1->getReg();
> +      bool isStos = Name == "stos";
> +      if (reg == X86::AL && (isStos || Name == "stosb"))
> +        ins = "stosb";
> +      else if (reg == X86::AX && (isStos || Name == "stosw"))
> +        ins = "stosw";
> +      else if (reg == X86::EAX && (isStos || Name == "stosl"))
> +        ins = "stosl";
> +      else if (reg == X86::RAX && (isStos || Name == "stosq"))
> +        ins = "stosq";
> +      else
> +        ins = NULL;
> +      if (ins != NULL) {
> +        Operands.pop_back();
> +        Operands.pop_back();
> +        delete Op1;
> +        delete Op2;
> +        if (Name != ins)
> +          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
> +      }
> +    }
> +  }
> +
>    // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
>    // "shift <op>".
>    if ((Name.startswith("shr") || Name.startswith("sar") ||

> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list