diff --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp --- a/llvm/lib/MC/MCParser/MasmParser.cpp +++ b/llvm/lib/MC/MCParser/MasmParser.cpp @@ -1314,7 +1314,7 @@ /// primaryexpr ::= symbol /// primaryexpr ::= number /// primaryexpr ::= '.' -/// primaryexpr ::= ~,+,- primaryexpr +/// primaryexpr ::= ~,+,-,'not' primaryexpr bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { SMLoc FirstTokenLoc = getLexer().getLoc(); AsmToken::TokenKind FirstTokenKind = Lexer.getKind(); @@ -1352,6 +1352,13 @@ return Error(FirstTokenLoc, "invalid token in expression"); } } + // Parse named bitwise negation. + if (Identifier.equals_lower("not")) { + if (parsePrimaryExpr(Res, EndLoc)) + return true; + Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc); + return false; + } // Parse symbol variant. std::pair Split; if (!MAI.useParensForSymbolVariant()) { @@ -1772,8 +1779,18 @@ SMLoc &EndLoc) { SMLoc StartLoc = Lexer.getLoc(); while (true) { + AsmToken::TokenKind TokKind = Lexer.getKind(); + if (Lexer.getKind() == AsmToken::Identifier) { + StringRef Identifier = Lexer.getTok().getString(); + if (Identifier.equals_lower("and")) + TokKind = AsmToken::Amp; + else if (Identifier.equals_lower("not")) + TokKind = AsmToken::Exclaim; + else if (Identifier.equals_lower("or")) + TokKind = AsmToken::Pipe; + } MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; - unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); + unsigned TokPrec = getBinOpPrecedence(TokKind, Kind); // If the next token is lower precedence than we are allowed to eat, return // successfully with what we ate already. @@ -3229,7 +3246,7 @@ Lex(); } else { const MCExpr *Value; - if (checkForValidSection() || parseExpression(Value)) + if (parseExpression(Value)) return true; if (getTok().is(AsmToken::Identifier) && getTok().getString().equals_lower("dup")) { @@ -3449,6 +3466,9 @@ // Initialize real data values. bool MasmParser::emitRealValues(const fltSemantics &Semantics) { + if (checkForValidSection()) + return true; + SmallVector ValuesAsInt; if (parseRealInstList(Semantics, ValuesAsInt)) return true; @@ -3468,8 +3488,7 @@ Field.SizeOf = 0; - if (checkForValidSection() || - parseRealInstList(Semantics, RealInfo.AsIntValues)) + if (parseRealInstList(Semantics, RealInfo.AsIntValues)) return true; Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8; @@ -3486,9 +3505,6 @@ /// ::= (real4 | real8) [ expression (, expression)* ] bool MasmParser::parseDirectiveRealValue(StringRef IDVal, const fltSemantics &Semantics) { - if (checkForValidSection()) - return true; - if (StructInProgress.empty()) { // Initialize data value. if (emitRealValues(Semantics)) @@ -3504,9 +3520,6 @@ bool MasmParser::parseDirectiveNamedRealValue(StringRef IDVal, const fltSemantics &Semantics, StringRef Name, SMLoc NameLoc) { - if (checkForValidSection()) - return true; - if (StructInProgress.empty()) { // Initialize named data value. MCSymbol *Sym = getContext().getOrCreateSymbol(Name); diff --git a/llvm/test/tools/llvm-ml/named_bitwise_operators.test b/llvm/test/tools/llvm-ml/named_bitwise_operators.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-ml/named_bitwise_operators.test @@ -0,0 +1,20 @@ +; RUN: llvm-ml -filetype=asm %s | FileCheck %s + +.data + +t1 BYTE NOT 1 +; CHECK: t1: +; CHECK-NEXT: .byte -2 + +t2 BYTE 1 OR 2 +; CHECK: t2: +; CHECK-NEXT: .byte 3 + +t3 BYTE 6 AND 10 +; CHECK: t3: +; CHECK-NEXT: .byte 2 + +.code +xor eax, eax + +END