[llvm] r216604 - X86 MC: Handle instructions like fxsave that match multiple operand sizes

Reid Kleckner reid at kleckner.net
Wed Aug 27 13:10:39 PDT 2014


Author: rnk
Date: Wed Aug 27 15:10:38 2014
New Revision: 216604

URL: http://llvm.org/viewvc/llvm-project?rev=216604&view=rev
Log:
X86 MC: Handle instructions like fxsave that match multiple operand sizes

Instructions like 'fxsave' and control flow instructions like 'jne'
match any operand size. The loop I added to the Intel syntax matcher
assumed that using a different size would give a different instruction.
Now it handles the case where we get the same instruction for different
memory operand sizes.

This also allows us to remove the hack we had for unsized absolute
memory operands, because we can successfully match things like 'jnz'
without reporting ambiguity.  Removing this hack uncovered test case
involving 'fadd' that was ambiguous. The memory operand could have been
single or double precision.

Modified:
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/trunk/test/MC/X86/intel-syntax-ambiguous.s
    llvm/trunk/test/MC/X86/intel-syntax.s

Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=216604&r1=216603&r2=216604&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Wed Aug 27 15:10:38 2014
@@ -2573,10 +2573,7 @@ bool X86AsmParser::MatchAndEmitIntelInst
   X86Operand *UnsizedMemOp = nullptr;
   for (const auto &Op : Operands) {
     X86Operand *X86Op = static_cast<X86Operand *>(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::MatchAndEmitIntelInst
     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()));

Modified: llvm/trunk/test/MC/X86/intel-syntax-ambiguous.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/intel-syntax-ambiguous.s?rev=216604&r1=216603&r2=216604&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/intel-syntax-ambiguous.s (original)
+++ llvm/trunk/test/MC/X86/intel-syntax-ambiguous.s Wed Aug 27 15:10:38 2014
@@ -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 at 4NA"
+// CHECK: error: ambiguous operand size for instruction 'fadd'

Modified: llvm/trunk/test/MC/X86/intel-syntax.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/intel-syntax.s?rev=216604&r1=216603&r2=216604&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/intel-syntax.s (original)
+++ llvm/trunk/test/MC/X86/intel-syntax.s Wed Aug 27 15:10:38 2014
@@ -603,8 +603,8 @@ mov rcx, qword ptr [_g0 + 8]
 "?half@?0??bar@@YAXXZ at 4NA":
 	.quad   4602678819172646912
 
-fadd   "?half@?0??bar@@YAXXZ at 4NA"
-fadd   "?half@?0??bar@@YAXXZ at 4NA"@IMGREL
+fadd   dword ptr "?half@?0??bar@@YAXXZ at 4NA"
+fadd   dword ptr "?half@?0??bar@@YAXXZ at 4NA"@IMGREL
 // CHECK: fadds   "?half@?0??bar@@YAXXZ at 4NA"
 // CHECK: fadds   "?half@?0??bar@@YAXXZ at 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)





More information about the llvm-commits mailing list