diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index fde41aa14cd..bc8ac26603b 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2573,10 +2573,7 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, X86Operand *UnsizedMemOp = nullptr; for (const auto &Op : Operands) { X86Operand *X86Op = static_cast(Op.get()); - // FIXME: Remove this exception for absolute memory references. Currently it - // allows us to assemble 'call foo', because foo is represented as a memory - // operand. - if (X86Op->isMemUnsized() && !X86Op->isAbsMem()) + if (X86Op->isMemUnsized()) UnsizedMemOp = X86Op; } @@ -2602,14 +2599,27 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, for (unsigned Size : MopSizes) { UnsizedMemOp->Mem.Size = Size; uint64_t ErrorInfoIgnore; - Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore, - MatchingInlineAsm, - isParsingIntelSyntax())); + unsigned LastOpcode = Inst.getOpcode(); + unsigned M = + MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore, + MatchingInlineAsm, isParsingIntelSyntax()); + if (Match.empty() || LastOpcode != Inst.getOpcode()) + Match.push_back(M); + // If this returned as a missing feature failure, remember that. if (Match.back() == Match_MissingFeature) ErrorInfoMissingFeature = ErrorInfoIgnore; } - } else { + + // Restore the size of the unsized memory operand if we modified it. + if (UnsizedMemOp) + UnsizedMemOp->Mem.Size = 0; + } + + // If we haven't matched anything yet, this is not a basic integer or FPU + // operation. There shouldn't be any ambiguity in our mneumonic table, so try + // matching with the unsized operand. + if (Match.empty()) { Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax())); diff --git a/test/MC/X86/intel-syntax-ambiguous.s b/test/MC/X86/intel-syntax-ambiguous.s index 1acfb5ba70f..fe1fe502390 100644 --- a/test/MC/X86/intel-syntax-ambiguous.s +++ b/test/MC/X86/intel-syntax-ambiguous.s @@ -42,3 +42,6 @@ add byte ptr [eax], eax add rax, 3 // CHECK: error: register %rax is only available in 64-bit mode + +fadd "?half@?0??bar@@YAXXZ@4NA" +// CHECK: error: ambiguous operand size for instruction 'fadd' diff --git a/test/MC/X86/intel-syntax.s b/test/MC/X86/intel-syntax.s index bb1762e4727..325f64d533b 100644 --- a/test/MC/X86/intel-syntax.s +++ b/test/MC/X86/intel-syntax.s @@ -603,8 +603,8 @@ mov rcx, qword ptr [_g0 + 8] "?half@?0??bar@@YAXXZ@4NA": .quad 4602678819172646912 -fadd "?half@?0??bar@@YAXXZ@4NA" -fadd "?half@?0??bar@@YAXXZ@4NA"@IMGREL +fadd dword ptr "?half@?0??bar@@YAXXZ@4NA" +fadd dword ptr "?half@?0??bar@@YAXXZ@4NA"@IMGREL // CHECK: fadds "?half@?0??bar@@YAXXZ@4NA" // CHECK: fadds "?half@?0??bar@@YAXXZ@4NA"@IMGREL32 @@ -641,3 +641,24 @@ fstp dword ptr [rax] // CHECK: fstpt (%rax) // CHECK: fstpl (%rax) // CHECK: fstps (%rax) + +fxsave [eax] +fsave [eax] +fxrstor [eax] +frstor [eax] +// CHECK: fxsave (%eax) +// CHECK: wait +// CHECK: fnsave (%eax) +// CHECK: fxrstor (%eax) +// CHECK: frstor (%eax) + +// FIXME: Should we accept this? Masm accepts it, but gas does not. +fxsave dword ptr [eax] +fsave dword ptr [eax] +fxrstor dword ptr [eax] +frstor dword ptr [eax] +// CHECK: fxsave (%eax) +// CHECK: wait +// CHECK: fnsave (%eax) +// CHECK: fxrstor (%eax) +// CHECK: frstor (%eax)