]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Assembler: support special floats: infinity / nan
authorWouter van Oortmerssen <aardappel@gmail.com>
Mon, 15 Jul 2019 22:13:39 +0000 (22:13 +0000)
committerWouter van Oortmerssen <aardappel@gmail.com>
Mon, 15 Jul 2019 22:13:39 +0000 (22:13 +0000)
Summary:
These are emitted as identifiers by the InstPrinter, so we should
parse them as such. These could potentially clash with symbols of
the same name, but that is out of our (the WebAssembly backend) control.

Reviewers: dschuff

Subscribers: sbc100, jgravelle-google, aheejin, sunfish, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D64770

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

lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
test/MC/WebAssembly/basic-assembly.s

index e82923519f4c1393fa5ced714164b78c869007f4..e9a7f6977c2d3dc713d232f44e357b4003461882 100644 (file)
@@ -363,6 +363,28 @@ public:
     return false;
   }
 
+  bool parseSpecialFloatMaybe(bool IsNegative, OperandVector &Operands) {
+    if (Lexer.isNot(AsmToken::Identifier))
+      return true;
+    auto &Flt = Lexer.getTok();
+    auto S = Flt.getString();
+    double Val;
+    if (S.compare_lower("infinity") == 0) {
+      Val = std::numeric_limits<double>::infinity();
+    } else if (S.compare_lower("nan") == 0) {
+      Val = std::numeric_limits<double>::quiet_NaN();
+    } else {
+      return true;
+    }
+    if (IsNegative)
+      Val = -Val;
+    Operands.push_back(make_unique<WebAssemblyOperand>(
+        WebAssemblyOperand::Float, Flt.getLoc(), Flt.getEndLoc(),
+        WebAssemblyOperand::FltOp{Val}));
+    Parser.Lex();
+    return false;
+  }
+
   bool checkForP2AlignIfLoadStore(OperandVector &Operands, StringRef InstName) {
     // FIXME: there is probably a cleaner way to do this.
     auto IsLoadStore = InstName.find(".load") != StringRef::npos ||
@@ -476,6 +498,8 @@ public:
       auto &Tok = Lexer.getTok();
       switch (Tok.getKind()) {
       case AsmToken::Identifier: {
+        if (!parseSpecialFloatMaybe(false, Operands))
+          break;
         auto &Id = Lexer.getTok();
         if (ExpectBlockType) {
           // Assume this identifier is a block_type.
@@ -507,6 +531,7 @@ public:
         } else if(Lexer.is(AsmToken::Real)) {
           if (parseSingleFloat(true, Operands))
             return true;
+        } else if (!parseSpecialFloatMaybe(true, Operands)) {
         } else {
           return error("Expected numeric constant instead got: ",
                        Lexer.getTok());
index 81d6001175b65bbe0c14bd4377e4da82187edfb5..c3b7e9da25de4e4515e9bbc5e55edf7a9415a875 100644 (file)
@@ -14,6 +14,8 @@ test0:
     i32.const   -1
     f64.const   0x1.999999999999ap1
     f32.const   -1.0
+    f32.const   -infinity
+    f32.const   nan
     v128.const  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
     v128.const  0, 1, 2, 3, 4, 5, 6, 7
     # Indirect addressing:
@@ -118,6 +120,8 @@ test0:
 # CHECK-NEXT:      i32.const   -1
 # CHECK-NEXT:      f64.const   0x1.999999999999ap1
 # CHECK-NEXT:      f32.const   -0x1p0
+# CHECK-NEXT:      f32.const   -infinity
+# CHECK-NEXT:      f32.const   nan
 # CHECK-NEXT:      v128.const  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
 # CHECK-NEXT:      v128.const  0, 1, 2, 3, 4, 5, 6, 7
 # CHECK-NEXT:      local.get   0