Index: lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmParser.cpp +++ lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2365,10 +2365,11 @@ 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 && @@ -2379,8 +2380,9 @@ 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 && Index: test/MC/X86/x86-32.s =================================================================== --- test/MC/X86/x86-32.s +++ test/MC/X86/x86-32.s @@ -593,6 +593,55 @@ setnaeb %bl // CHECK: setb %bl +// PR8114 +// CHECK: outb %al, %dx +// CHECK: outb %al, %dx +// CHECK: outw %ax, %dx +// CHECK: outw %ax, %dx +// CHECK: outl %eax, %dx +// CHECK: outl %eax, %dx + +out %al, (%dx) +outb %al, (%dx) +out %ax, (%dx) +outw %ax, (%dx) +out %eax, (%dx) +outl %eax, (%dx) + +// CHECK: inb %dx, %al +// CHECK: inb %dx, %al +// CHECK: inw %dx, %ax +// CHECK: inw %dx, %ax +// CHECK: inl %dx, %eax +// CHECK: inl %dx, %eax + +in (%dx), %al +inb (%dx), %al +in (%dx), %ax +inw (%dx), %ax +in (%dx), %eax +inl (%dx), %eax + +//PR15455 +// CHECK: outsw (%esi), %dx +// CHECK: outsb (%esi), %dx +// CHECK: outsw (%esi), %dx +// CHECK: outsl (%esi), %dx + +outs (%esi), (%dx) +outsb (%esi), (%dx) +outsw (%esi), (%dx) +outsl (%esi), (%dx) + +// CHECK: insw %dx, %es:(%edi) +// CHECK: insb %dx, %es:(%edi) +// CHECK: insw %dx, %es:(%edi) +// CHECK: insl %dx, %es:(%edi) +ins (%dx), %es:(%edi) +insb (%dx), %es:(%edi) +insw (%dx), %es:(%edi) +insl (%dx), %es:(%edi) + // CHECK: lcalll $31438, $31438 // CHECK: lcalll $31438, $31438 // CHECK: ljmpl $31438, $31438 Index: test/MC/X86/x86-64.s =================================================================== --- test/MC/X86/x86-64.s +++ test/MC/X86/x86-64.s @@ -281,6 +281,26 @@ in (%dx), %eax inl (%dx), %eax +//PR15455 +// CHECK: outsw (%rsi), %dx +// CHECK: outsb (%rsi), %dx +// CHECK: outsw (%rsi), %dx +// CHECK: outsl (%rsi), %dx + +outs (%rsi), (%dx) //permitted invalid memory form +outsb (%rsi), (%dx) +outsw (%rsi), (%dx) +outsl (%rsi), (%dx) + +// CHECK: insw %dx, %es:(%rdi) +// CHECK: insb %dx, %es:(%rdi) +// CHECK: insw %dx, %es:(%rdi) +// CHECK: insl %dx, %es:(%rdi) +ins (%dx), %es:(%rdi) +insb (%dx), %es:(%rdi) +insw (%dx), %es:(%rdi) +insl (%dx), %es:(%rdi) + // rdar://8431422 // CHECK: fxch %st(1)