Index: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2364,10 +2364,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 && @@ -2378,8 +2379,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: llvm/trunk/test/MC/X86/x86-32.s =================================================================== --- llvm/trunk/test/MC/X86/x86-32.s +++ llvm/trunk/test/MC/X86/x86-32.s @@ -593,6 +593,55 @@ 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 Index: llvm/trunk/test/MC/X86/x86-64.s =================================================================== --- llvm/trunk/test/MC/X86/x86-64.s +++ llvm/trunk/test/MC/X86/x86-64.s @@ -281,6 +281,27 @@ 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)