[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