Index: llvm/trunk/lib/CodeGen/MIRParser/MILexer.h =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MILexer.h +++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.h @@ -118,6 +118,7 @@ // Other tokens IntegerLiteral, FloatingPointLiteral, + HexLiteral, VirtualRegister, ConstantPoolItem, JumpTableIndex, Index: llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp +++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp @@ -424,19 +424,6 @@ return C == 'H' || C == 'K' || C == 'L' || C == 'M'; } -static Cursor maybeLexHexFloatingPointLiteral(Cursor C, MIToken &Token) { - if (C.peek() != '0' || C.peek(1) != 'x') - return None; - Cursor Range = C; - C.advance(2); // Skip '0x' - if (isValidHexFloatingPointPrefix(C.peek())) - C.advance(); - while (isxdigit(C.peek())) - C.advance(); - Token.reset(MIToken::FloatingPointLiteral, Range.upto(C)); - return C; -} - static Cursor lexFloatingPointLiteral(Cursor Range, Cursor C, MIToken &Token) { C.advance(); // Skip over [0-9]*([eE][-+]?[0-9]+)? @@ -453,6 +440,28 @@ return C; } +static Cursor maybeLexHexadecimalLiteral(Cursor C, MIToken &Token) { + if (C.peek() != '0' || (C.peek(1) != 'x' && C.peek(1) != 'X')) + return None; + Cursor Range = C; + C.advance(2); + unsigned PrefLen = 2; + if (isValidHexFloatingPointPrefix(C.peek())) { + C.advance(); + PrefLen++; + } + while (isxdigit(C.peek())) + C.advance(); + StringRef StrVal = Range.upto(C); + if (StrVal.size() <= PrefLen) + return None; + if (PrefLen == 2) + Token.reset(MIToken::HexLiteral, Range.upto(C)); + else // It must be 3, which means that there was a floating-point prefix. + Token.reset(MIToken::FloatingPointLiteral, Range.upto(C)); + return C; +} + static Cursor maybeLexNumericalLiteral(Cursor C, MIToken &Token) { if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1)))) return None; @@ -609,7 +618,7 @@ return R.remaining(); if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback)) return R.remaining(); - if (Cursor R = maybeLexHexFloatingPointLiteral(C, Token)) + if (Cursor R = maybeLexHexadecimalLiteral(C, Token)) return R.remaining(); if (Cursor R = maybeLexNumericalLiteral(C, Token)) return R.remaining(); Index: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp +++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp @@ -36,6 +36,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetIntrinsicInfo.h" #include "llvm/Target/TargetSubtargetInfo.h" +#include using namespace llvm; @@ -453,8 +454,19 @@ unsigned Reg = 0; if (parseNamedRegister(Reg)) return true; - MBB.addLiveIn(Reg); lex(); + LaneBitmask Mask = ~LaneBitmask(0); + if (consumeIfPresent(MIToken::colon)) { + // Parse lane mask. + if (Token.isNot(MIToken::IntegerLiteral) && + Token.isNot(MIToken::HexLiteral)) + return error("expected a lane mask"); + static_assert(sizeof(LaneBitmask) == sizeof(unsigned), ""); + if (getUnsigned(Mask)) + return error("invalid lane mask value"); + lex(); + } + MBB.addLiveIn(Reg, Mask); } while (consumeIfPresent(MIToken::comma)); return false; } @@ -1107,7 +1119,8 @@ bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) { auto Loc = Token.location(); lex(); - if (Token.isNot(MIToken::FloatingPointLiteral)) + if (Token.isNot(MIToken::FloatingPointLiteral) && + Token.isNot(MIToken::HexLiteral)) return error("expected a floating point literal"); const Constant *C = nullptr; if (parseIRConstant(Loc, C)) @@ -1117,13 +1130,30 @@ } bool MIParser::getUnsigned(unsigned &Result) { - assert(Token.hasIntegerValue() && "Expected a token with an integer value"); - const uint64_t Limit = uint64_t(std::numeric_limits::max()) + 1; - uint64_t Val64 = Token.integerValue().getLimitedValue(Limit); - if (Val64 == Limit) - return error("expected 32-bit integer (too large)"); - Result = Val64; - return false; + if (Token.hasIntegerValue()) { + const uint64_t Limit = uint64_t(std::numeric_limits::max()) + 1; + uint64_t Val64 = Token.integerValue().getLimitedValue(Limit); + if (Val64 == Limit) + return error("expected 32-bit integer (too large)"); + Result = Val64; + return false; + } + if (Token.is(MIToken::HexLiteral)) { + StringRef S = Token.range(); + assert(S[0] == '0' && tolower(S[1]) == 'x'); + // This could be a floating point literal with a special prefix. + if (!isxdigit(S[2])) + return true; + StringRef V = S.substr(2); + unsigned BW = std::min(V.size()*4, 32); + APInt A(BW, V, 16); + APInt Limit = APInt(BW, std::numeric_limits::max()); + if (A.ugt(Limit)) + return error("expected 32-bit integer (too large)"); + Result = A.getZExtValue(); + return false; + } + return true; } bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) { Index: llvm/trunk/lib/CodeGen/MIRPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRPrinter.cpp +++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp @@ -499,7 +499,7 @@ First = false; printReg(LI.PhysReg, OS, TRI); if (LI.LaneMask != ~0u) - OS << ':' << PrintLaneMask(LI.LaneMask); + OS << ":0x" << PrintLaneMask(LI.LaneMask); } OS << "\n"; HasLineAttributes = true; Index: llvm/trunk/test/CodeGen/MIR/Hexagon/parse-lane-masks.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/Hexagon/parse-lane-masks.mir +++ llvm/trunk/test/CodeGen/MIR/Hexagon/parse-lane-masks.mir @@ -0,0 +1,23 @@ +# RUN: llc -march=hexagon -run-pass none -o - %s | FileCheck %s +# Check that the MIR parser can parse lane masks in block liveins. + +# CHECK-LABEL: name: foo +# CHECK: bb.0: +# CHECK: liveins: %d0:0x00000002, %d1, %d2:0x00000010 + +--- | + define void @foo() { + ret void + } +... + +--- +name: foo +tracksRegLiveness: true + +body: | + bb.0: + liveins: %d0:0x00002, %d1, %d2:16 + A2_nop +... +