[PATCH] D31948: [AArch64] Fix handling of integer fp immediates

John Brawn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 11 10:23:01 PDT 2017


john.brawn updated this revision to Diff 94849.
john.brawn added a comment.

Accidentally used the wrong diff, attach the correct one.


https://reviews.llvm.org/D31948

Files:
  lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
  test/MC/AArch64/basic-a64-diagnostics.s


Index: test/MC/AArch64/basic-a64-diagnostics.s
===================================================================
--- test/MC/AArch64/basic-a64-diagnostics.s
+++ test/MC/AArch64/basic-a64-diagnostics.s
@@ -1781,12 +1781,20 @@
         ;; Exponent too large
         fmov d3, #0.0625
         fmov s2, #32.0
+        fmov s2, #32
+        fmov v0.4s, #-32
 // CHECK-ERROR: error: expected compatible register or floating-point constant
 // CHECK-ERROR-NEXT:           fmov d3, #0.0625
 // CHECK-ERROR-NEXT:                    ^
 // CHECK-ERROR-NEXT: error: expected compatible register or floating-point constant
 // CHECK-ERROR-NEXT:           fmov s2, #32.0
 // CHECK-ERROR-NEXT:                    ^
+// CHECK-ERROR-NEXT: error: expected compatible register or floating-point constant
+// CHECK-ERROR-NEXT:           fmov s2, #32
+// CHECK-ERROR-NEXT:                    ^
+// CHECK-ERROR-NEXT: error: expected compatible register or floating-point constant
+// CHECK-ERROR-NEXT:           fmov v0.4s, #-32
+// CHECK-ERROR-NEXT:                       ^
 
         ;; Fraction too precise
         fmov s9, #1.03125
@@ -1798,6 +1806,12 @@
 // CHECK-ERROR-NEXT:           fmov s28, #1.96875
 // CHECK-ERROR-NEXT:                     ^
 
+        ;; Explicitly encoded value too large
+        fmov s15, #0x100
+// CHECK-ERROR: error: encoded floating point value out of range
+// CHECK-ERROR-NEXT:           fmov s15, #0x100
+// CHECK-ERROR-NEXT:                     ^
+
         ;; No particular reason, but a striking omission
         fmov d0, #0.0
 // CHECK-ERROR-AARCH64: error: expected compatible register or floating-point constant
Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
===================================================================
--- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -2100,38 +2100,29 @@
   bool isNegative = parseOptionalToken(AsmToken::Minus);
 
   const AsmToken &Tok = Parser.getTok();
-  if (Tok.is(AsmToken::Real)) {
-    APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
-    if (isNegative)
-      RealVal.changeSign();
-
-    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
-    int Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
-    Parser.Lex(); // Eat the token.
-    // Check for out of range values. As an exception, we let Zero through,
-    // as we handle that special case in post-processing before matching in
-    // order to use the zero register for it.
-    if (Val == -1 && !RealVal.isPosZero()) {
-      TokError("expected compatible register or floating-point constant");
-      return MatchOperand_ParseFail;
-    }
-    Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
-    return MatchOperand_Success;
-  }
-  if (Tok.is(AsmToken::Integer)) {
+  if (Tok.is(AsmToken::Real) || Tok.is(AsmToken::Integer)) {
     int64_t Val;
-    if (!isNegative && Tok.getString().startswith("0x")) {
+    if (Tok.is(AsmToken::Integer) && !isNegative && Tok.getString().startswith("0x")) {
       Val = Tok.getIntVal();
       if (Val > 255 || Val < 0) {
         TokError("encoded floating point value out of range");
         return MatchOperand_ParseFail;
       }
     } else {
       APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
+      if (isNegative)
+        RealVal.changeSign();
+
       uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
-      // If we had a '-' in front, toggle the sign bit.
-      IntVal ^= (uint64_t)isNegative << 63;
       Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
+
+      // Check for out of range values. As an exception, we let Zero through,
+      // as we handle that special case in post-processing before matching in
+      // order to use the zero register for it.
+      if (Val == -1 && !RealVal.isPosZero()) {
+        TokError("expected compatible register or floating-point constant");
+        return MatchOperand_ParseFail;
+      }
     }
     Parser.Lex(); // Eat the token.
     Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D31948.94849.patch
Type: text/x-patch
Size: 4094 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170411/ca1d1be3/attachment.bin>


More information about the llvm-commits mailing list