From 292e21d8bce463fb8bb833810f05d4382f61bdd0 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Mon, 15 Jul 2019 22:13:39 +0000 Subject: [PATCH] [WebAssembly] Assembler: support special floats: infinity / nan 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 llvm-svn: 366139 --- .../AsmParser/WebAssemblyAsmParser.cpp | 25 +++++++++++++++++++ llvm/test/MC/WebAssembly/basic-assembly.s | 4 +++ 2 files changed, 29 insertions(+) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index e82923519f4c..e9a7f6977c2d 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -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::infinity(); + } else if (S.compare_lower("nan") == 0) { + Val = std::numeric_limits::quiet_NaN(); + } else { + return true; + } + if (IsNegative) + Val = -Val; + Operands.push_back(make_unique( + 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()); diff --git a/llvm/test/MC/WebAssembly/basic-assembly.s b/llvm/test/MC/WebAssembly/basic-assembly.s index 81d6001175b6..c3b7e9da25de 100644 --- a/llvm/test/MC/WebAssembly/basic-assembly.s +++ b/llvm/test/MC/WebAssembly/basic-assembly.s @@ -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