[ARM64] Add/Fixup diagnostics for floating point immediates
authorBradley Smith <bradley.smith@arm.com>
Thu, 15 May 2014 11:07:28 +0000 (11:07 +0000)
committerBradley Smith <bradley.smith@arm.com>
Thu, 15 May 2014 11:07:28 +0000 (11:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208862 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM64/ARM64InstrFormats.td
lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
test/MC/AArch64/neon-diagnostics.s

index 883d9eb7c59042c9e2fb72f64a5f3271a13a20a3..27ee48e7cf9e361e46aaa58551a1be7b52ba9899 100644 (file)
@@ -165,6 +165,7 @@ def ExtendOperandLSL64 : AsmOperandClass {
 def FPImmOperand : AsmOperandClass {
   let Name = "FPImm";
   let ParserMethod = "tryParseFPImm";
+  let DiagnosticType = "InvalidFPImm";
 }
 
 def CondCode : AsmOperandClass {
index 6322448a8ac30ee9fa2ffd975c49669e22cbc43c..acfc7cfe0a7bdf2a193980b0cf3c3b9090100d3b 100644 (file)
@@ -2314,7 +2314,7 @@ ARM64AsmParser::tryParseFPImm(OperandVector &Operands) {
     // as we handle that special case in post-processing before matching in
     // order to use the zero register for it.
     if (Val == -1 && !RealVal.isZero()) {
-      TokError("floating point value out of range");
+      TokError("expected compatible register or floating-point constant");
       return MatchOperand_ParseFail;
     }
     Operands.push_back(ARM64Operand::CreateFPImm(Val, S, getContext()));
@@ -3378,6 +3378,16 @@ bool ARM64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
     if (getLexer().is(AsmToken::Hash))
       Parser.Lex();
 
+    // Parse a negative sign
+    bool isNegative = false;
+    if (Parser.getTok().is(AsmToken::Minus)) {
+      isNegative = true;
+      // We need to consume this token only when we have a Real, otherwise
+      // we let parseSymbolicImmVal take care of it
+      if (Parser.getLexer().peekTok().is(AsmToken::Real))
+        Parser.Lex();
+    }
+
     // The only Real that should come through here is a literal #0.0 for
     // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
     // so convert the value.
@@ -3389,8 +3399,8 @@ bool ARM64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
           Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
           Mnemonic != "fcmlt")
         return TokError("unexpected floating point literal");
-      else if (IntVal != 0)
-        return TokError("only valid floating-point immediate is #0.0");
+      else if (IntVal != 0 || isNegative)
+        return TokError("expected floating-point constant #0.0");
       Parser.Lex(); // Eat the token.
 
       Operands.push_back(
@@ -3729,6 +3739,9 @@ bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
   case Match_AddSubRegShift64:
     return Error(Loc,
        "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
+  case Match_InvalidFPImm:
+    return Error(Loc,
+                 "expected compatible register or floating-point constant");
   case Match_InvalidMemoryIndexedSImm9:
     return Error(Loc, "index must be an integer in range [-256, 255].");
   case Match_InvalidMemoryIndexed32SImm7:
@@ -4187,6 +4200,7 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_AddSubRegShift64:
   case Match_InvalidMovImm32Shift:
   case Match_InvalidMovImm64Shift:
+  case Match_InvalidFPImm:
   case Match_InvalidMemoryIndexed8:
   case Match_InvalidMemoryIndexed16:
   case Match_InvalidMemoryIndexed32SImm7:
index dba9f5e7fd459c02271303d122427e9b33e72754..03c678f28f7b5b67203419f973519e6ef731e443 100644 (file)
 // CHECK-AARCH64-ERROR:        fcmeq v0.8b, v1.4h, #1
 // CHECK-AARCH64-ERROR:                             ^
 
-// CHECK-ARM64-ERROR: error: only valid floating-point immediate is #0.0
+// CHECK-ARM64-ERROR: error: expected floating-point constant #0.0
 // CHECK-ARM64-ERROR:        fcmeq v0.8b, v1.4h, #1.0
 // CHECK-ARM64-ERROR:                             ^
 // CHECK-ARM64-ERROR: error: invalid operand for instruction
 // CHECK-AARCH64-ERROR:        fcmle v17.8h, v15.2d, #2
 // CHECK-AARCH64-ERROR:                               ^
 
-// CHECK-ARM64-ERROR: error: invalid operand for instruction
+// CHECK-ARM64-ERROR: error: expected floating-point constant #0.0
 // CHECK-ARM64-ERROR:        fcmle v17.8h, v15.2d, #-1.0
 // CHECK-ARM64-ERROR:                               ^
 // CHECK-ARM64-ERROR: error: invalid operand for instruction
 // CHECK-AARCH64-ERROR:        fcmlt v29.2d, v5.2d, #255
 // CHECK-AARCH64-ERROR:                              ^
 
-// CHECK-ARM64-ERROR: error: only valid floating-point immediate is #0.0
+// CHECK-ARM64-ERROR: error: expected floating-point constant #0.0
 // CHECK-ARM64-ERROR:        fcmlt v29.2d, v5.2d, #255.0
 // CHECK-ARM64-ERROR:                              ^
 // CHECK-ARM64-ERROR: error: invalid operand for instruction
 // CHECK-AARCH64-ERROR:        fcmle v17.2d, v15.2d, #15
 // CHECK-AARCH64-ERROR:                              ^
 
-// CHECK-ARM64-ERROR: error: only valid floating-point immediate is #0.0
+// CHECK-ARM64-ERROR: error: expected floating-point constant #0.0
 // CHECK-ARM64-ERROR:        fcmle v17.2d, v15.2d, #15.0
 // CHECK-ARM64-ERROR:                               ^
 // CHECK-ARM64-ERROR: error: invalid operand for instruction
 // CHECK-AARCH64-ERROR:        fcmlt v29.2d, v5.2d, #2
 // CHECK-AARCH64-ERROR:                              ^
 
-// CHECK-ARM64-ERROR: error: only valid floating-point immediate is #0.0
+// CHECK-ARM64-ERROR: error: expected floating-point constant #0.0
 // CHECK-ARM64-ERROR:        fcmlt v29.2d, v5.2d, #16.0
 // CHECK-ARM64-ERROR:                              ^
 // CHECK-ARM64-ERROR: error: invalid operand for instruction