Index: lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp =================================================================== --- lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -363,6 +363,28 @@ 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 @@ 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 @@ } 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: test/MC/WebAssembly/basic-assembly.s =================================================================== --- test/MC/WebAssembly/basic-assembly.s +++ test/MC/WebAssembly/basic-assembly.s @@ -14,6 +14,8 @@ 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 @@ # 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