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

llvm-svn: 274152
This commit is contained in:
Nirav Dave 2016-06-29 19:54:27 +00:00
parent fdcca8cd55
commit 8e10380b73
3 changed files with 76 additions and 4 deletions

View File

@ -2364,10 +2364,11 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
static_cast<X86Operand &>(*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 &&

View File

@ -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

View File

@ -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)