From a4d56588c91df271cb1c8e97d29f0d41ad71f616 Mon Sep 17 00:00:00 2001 From: Nirav Dave Date: Wed, 29 Jun 2016 19:54:27 +0000 Subject: [PATCH] Permit memory operands in ins/outs instructions [x86] (PR15455) While (ins|outs)[bwld] instructions do not take %dx as a memory operand, various unofficial references do and objdump disassembles to this format. Extend special treatment of similar (in|out)[bwld] operations. Reviewers: craig.topper, rnk, ab Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D18837 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274152 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/AsmParser/X86AsmParser.cpp | 10 +++-- test/MC/X86/x86-32.s | 49 +++++++++++++++++++++++ test/MC/X86/x86-64.s | 21 ++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 807eb112ee4..d016ae0c57d 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2364,10 +2364,11 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, static_cast(*Operands[0]).setTokenValue(Repl); } - // This is a terrible hack to handle "out[bwl]? %al, (%dx)" -> + // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" -> // "outb %al, %dx". Out doesn't take a memory form, but this is a widely // documented form in various unofficial manuals, so a lot of code uses it. - if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") && + if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" || + Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") && Operands.size() == 3) { X86Operand &Op = (X86Operand &)*Operands.back(); if (Op.isMem() && Op.Mem.SegReg == 0 && @@ -2378,8 +2379,9 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); } } - // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al". - if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") && + // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al". + if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" || + Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") && Operands.size() == 3) { X86Operand &Op = (X86Operand &)*Operands[1]; if (Op.isMem() && Op.Mem.SegReg == 0 && diff --git a/test/MC/X86/x86-32.s b/test/MC/X86/x86-32.s index 56fd658a76e..127d6c7c77c 100644 --- a/test/MC/X86/x86-32.s +++ b/test/MC/X86/x86-32.s @@ -593,6 +593,55 @@ popfl setnaeb %bl // CHECK: setb %bl +// PR8114 + +out %al, (%dx) +// CHECK: outb %al, %dx +outb %al, (%dx) +// CHECK: outb %al, %dx +out %ax, (%dx) +// CHECK: outw %ax, %dx +outw %ax, (%dx) +// CHECK: outw %ax, %dx +out %eax, (%dx) +// CHECK: outl %eax, %dx +outl %eax, (%dx) +// CHECK: outl %eax, %dx + + +in (%dx), %al +// CHECK: inb %dx, %al +inb (%dx), %al +// CHECK: inb %dx, %al +in (%dx), %ax +// CHECK: inw %dx, %ax +inw (%dx), %ax +// CHECK: inw %dx, %ax +in (%dx), %eax +// CHECK: inl %dx, %eax +inl (%dx), %eax +// CHECK: inl %dx, %eax + +//PR15455 + +outs (%esi), (%dx) +// CHECK: outsw (%esi), %dx +outsb (%esi), (%dx) +// CHECK: outsb (%esi), %dx +outsw (%esi), (%dx) +// CHECK: outsw (%esi), %dx +outsl (%esi), (%dx) +// CHECK: outsl (%esi), %dx + +ins (%dx), %es:(%edi) +// CHECK: insw %dx, %es:(%edi) +insb (%dx), %es:(%edi) +// CHECK: insb %dx, %es:(%edi) +insw (%dx), %es:(%edi) +// CHECK: insw %dx, %es:(%edi) +insl (%dx), %es:(%edi) +// CHECK: insl %dx, %es:(%edi) + // CHECK: lcalll $31438, $31438 // CHECK: lcalll $31438, $31438 // CHECK: ljmpl $31438, $31438 diff --git a/test/MC/X86/x86-64.s b/test/MC/X86/x86-64.s index 8a5410bf017..1af25e5412f 100644 --- a/test/MC/X86/x86-64.s +++ b/test/MC/X86/x86-64.s @@ -281,6 +281,27 @@ inw (%dx), %ax in (%dx), %eax inl (%dx), %eax +//PR15455 + +// permitted invalid memory forms +outs (%rsi), (%dx) +// CHECK: outsw (%rsi), %dx +outsb (%rsi), (%dx) +// CHECK: outsb (%rsi), %dx +outsw (%rsi), (%dx) +// CHECK: outsw (%rsi), %dx +outsl (%rsi), (%dx) +// CHECK: outsl (%rsi), %dx + +ins (%dx), %es:(%rdi) +// CHECK: insw %dx, %es:(%rdi) +insb (%dx), %es:(%rdi) +// CHECK: insb %dx, %es:(%rdi) +insw (%dx), %es:(%rdi) +// CHECK: insw %dx, %es:(%rdi) +insl (%dx), %es:(%rdi) +// CHECK: insl %dx, %es:(%rdi) + // rdar://8431422 // CHECK: fxch %st(1) -- 2.50.1