ARM IAS: account for predicated pre-UAL mnemonics
authorSaleem Abdulrasool <compnerd@compnerd.org>
Mon, 30 Dec 2013 18:38:01 +0000 (18:38 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Mon, 30 Dec 2013 18:38:01 +0000 (18:38 +0000)
Checking the trailing letter of the mnemonic is insufficient.  Be more thorough
in the scanning of the instruction to ensure that we correctly work with the
predicated mnemonics.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198235 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/vfp-aliases-diagnostics.s
test/MC/ARM/vfp-aliases.s

index 6e0038c9b035ec646c0ee544e4c3cb7726a35a83..33274bfd0faec96ff50d8920199145b4bffc2609 100644 (file)
@@ -5107,18 +5107,37 @@ static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
 }
 static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features,
                                  unsigned VariantID);
+
+static bool RequiresVFPRegListValidation(StringRef Inst,
+                                         bool &AcceptSinglePrecisionOnly,
+                                         bool &AcceptDoublePrecisionOnly) {
+  if (Inst.size() < 7)
+    return false;
+
+  if (Inst.startswith("fldm") || Inst.startswith("fstm")) {
+    StringRef AddressingMode = Inst.substr(4, 2);
+    if (AddressingMode == "ia" || AddressingMode == "db" ||
+        AddressingMode == "ea" || AddressingMode == "fd") {
+      AcceptSinglePrecisionOnly = Inst[6] == 's';
+      AcceptDoublePrecisionOnly = Inst[6] == 'd' || Inst[6] == 'x';
+      return true;
+    }
+  }
+
+  return false;
+}
+
 /// Parse an arm instruction mnemonic followed by its operands.
 bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                                     SMLoc NameLoc,
                                SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   // FIXME: Can this be done via tablegen in some fashion?
-  bool RequireVFPRegisterList;
-  bool AcceptDoublePrecisionOnly;
+  bool RequireVFPRegisterListCheck;
   bool AcceptSinglePrecisionOnly;
-  RequireVFPRegisterList = Name.startswith("fldm") || Name.startswith("fstm");
-  AcceptDoublePrecisionOnly =
-    RequireVFPRegisterList && (Name.back() == 'd' || Name.back() == 'x');
-  AcceptSinglePrecisionOnly = RequireVFPRegisterList && Name.back() == 's';
+  bool AcceptDoublePrecisionOnly;
+  RequireVFPRegisterListCheck =
+    RequiresVFPRegListValidation(Name, AcceptSinglePrecisionOnly,
+                                 AcceptDoublePrecisionOnly);
 
   // Apply mnemonic aliases before doing anything else, as the destination
   // mnemonic may include suffices and we want to handle them normally.
@@ -5288,7 +5307,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
 
   Parser.Lex(); // Consume the EndOfStatement
 
-  if (RequireVFPRegisterList) {
+  if (RequireVFPRegisterListCheck) {
     ARMOperand *Op = static_cast<ARMOperand*>(Operands.back());
     if (AcceptSinglePrecisionOnly && !Op->isSPRRegList())
       return Error(Op->getStartLoc(),
index 911c23b2358312647b1b80b7803df41da328efec..d1ab18e99828b2eee6e9823f6db9d44b3b2b0777 100644 (file)
@@ -95,3 +95,20 @@ aliases:
 @ CHECK:       fldmeax sp!, {s0}
 @ CHECK:                     ^
 
+       fstmiaxcs r0, {s0}
+       fstmiaxhs r0, {s0}
+       fstmiaxls r0, {s0}
+       fstmiaxvs r0, {s0}
+@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK:       fstmiaxcs r0, {s0}
+@ CHECK:                      ^
+@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK:       fstmiaxhs r0, {s0}
+@ CHECK:                      ^
+@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK:       fstmiaxls r0, {s0}
+@ CHECK:                      ^
+@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK:       fstmiaxvs r0, {s0}
+@ CHECK:                      ^
+
index 1ed6e53b80e952d6488615fd6f214c105fd9ec60..4074feabbf18ffc4e972ff49ef43070d6b13e9cf 100644 (file)
@@ -51,3 +51,12 @@ aliases:
 @ CHECK:       fstmdbx sp!, {d0}
 @ CHECK:       fldmdbx sp!, {d0}
 
+       fstmiaxcs r0, {d0}
+       fstmiaxhs r0, {d0}
+       fstmiaxls r0, {d0}
+       fstmiaxvs r0, {d0}
+@ CHECK:       fstmiaxhs r0, {d0}
+@ CHECK:       fstmiaxhs r0, {d0}
+@ CHECK:       fstmiaxls r0, {d0}
+@ CHECK:       fstmiaxvs r0, {d0}
+