From 42c1227fd99a396d83e15317c4cc17d6552379c3 Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Thu, 7 Aug 2014 05:47:00 +0000 Subject: [PATCH] Change TableGen so that binary literals such as 0b001 are now sized. Instead of these becoming an integer literal internally, they now become bits values. Prior to this change, 0b001 was 1 bit long. This is confusing as clearly the user gave 3 bits. This new type holds both the literal value and the size, and so can ensure sizes match on initializers. For example, this used to be legal bits<1> x = 0b00; but now it must be written as bits<2> x = 0b00; git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215084 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/TableGen/TGLexer.cpp | 2 +- lib/TableGen/TGLexer.h | 9 +++++++++ lib/TableGen/TGParser.cpp | 9 +++++++++ test/TableGen/BitsInit.td | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/lib/TableGen/TGLexer.cpp b/lib/TableGen/TGLexer.cpp index cfcc119f82d..63b85842d6a 100644 --- a/lib/TableGen/TGLexer.cpp +++ b/lib/TableGen/TGLexer.cpp @@ -411,7 +411,7 @@ tgtok::TokKind TGLexer::LexNumber() { if (CurPtr == NumStart) return ReturnError(CurPtr-2, "Invalid binary number"); CurIntVal = strtoll(NumStart, nullptr, 2); - return tgtok::IntVal; + return tgtok::BinaryIntVal; } } diff --git a/lib/TableGen/TGLexer.h b/lib/TableGen/TGLexer.h index c7f7306a149..9fb2e3536e0 100644 --- a/lib/TableGen/TGLexer.h +++ b/lib/TableGen/TGLexer.h @@ -52,6 +52,10 @@ namespace tgtok { // Integer value. IntVal, + + // Binary constant. Note that these are sized according to the number of + // bits given. + BinaryIntVal, // String valued tokens. Id, StrVal, VarName, CodeFragment @@ -105,6 +109,11 @@ public: assert(CurCode == tgtok::IntVal && "This token isn't an integer"); return CurIntVal; } + std::pair getCurBinaryIntVal() const { + assert(CurCode == tgtok::BinaryIntVal && + "This token isn't a binary integer"); + return std::make_pair(CurIntVal, (CurPtr - TokStart)-2); + } SMLoc getLoc() const; diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp index d020a8bdc1a..709c7a52b9f 100644 --- a/lib/TableGen/TGParser.cpp +++ b/lib/TableGen/TGParser.cpp @@ -1182,6 +1182,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, Lex.Lex(); // Skip '#'. return ParseSimpleValue(CurRec, ItemType, Mode); case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break; + case tgtok::BinaryIntVal: { + auto BinaryVal = Lex.getCurBinaryIntVal(); + SmallVector Bits(BinaryVal.second); + for (unsigned i = 0, e = BinaryVal.second; i != e; ++i) + Bits[i] = BitInit::get(BinaryVal.first & (1 << i)); + R = BitsInit::get(Bits); + Lex.Lex(); + break; + } case tgtok::StrVal: { std::string Val = Lex.getCurStrVal(); Lex.Lex(); diff --git a/test/TableGen/BitsInit.td b/test/TableGen/BitsInit.td index 28fd3196fd0..c3d5113ebdb 100644 --- a/test/TableGen/BitsInit.td +++ b/test/TableGen/BitsInit.td @@ -20,3 +20,40 @@ def a { // CHECK: bits<2> b = { 1, 0 }; // CHECK: bits<2> c = { 1, 1 }; // CHECK: } + +def { + bits<2> B1 = 0b011; // bitfield is too small, reject + bits<3> B2 = 0b011; // ok + + bits<2> C1 = 0b111; // bitfield is too small, reject + bits<3> C2 = 0b111; // ok + + bits<2> D1 = { 0, 0 }; // ok + bits<2> D2 = { 0b00 }; // ok + bits<3> D3 = { 0, 0 }; // type mismatch. RHS doesn't have enough bits + bits<3> D4 = { 0b00 }; // type mismatch. RHS doesn't have enough bits + bits<1> D5 = { 0 }; // ok + bits<1> D6 = { 1 }; // ok + bits<1> D7 = { 3 }; // type mismatch. LHS doesn't have enough bits + bits<2> D8 = { 0 }; // type mismatch. RHS doesn't have enough bits + + bits<8> E; + let E{7-0} = {0,0,1,?,?,?,?,?}; + let E{3-0} = 0b0010; +} + +// CHECK: def {{.*}} { +// CHECK: bits<2> B1; +// CHECK: bits<3> B2 = { 0, 1, 1 }; +// CHECK: bits<2> C1; +// CHECK: bits<3> C2 = { 1, 1, 1 }; +// CHECK: bits<2> D1 = { 0, 0 }; +// CHECK: bits<2> D2 = { 0, 0 }; +// CHECK: bits<3> D3; +// CHECK: bits<3> D4; +// CHECK: bits<1> D5 = { 0 }; +// CHECK: bits<1> D6 = { 1 }; +// CHECK: bits<1> D7 = { ? }; +// CHECK: bits<2> D8; +// CHECK: bits<8> E = { 0, 0, 1, ?, 0, 0, 1, 0 }; +// CHECK: } -- 2.11.0