2014-08-07 13:46:57 +08:00
|
|
|
|
|
|
|
// RUN: not llvm-tblgen %s 2>&1 > %t
|
|
|
|
// RUN: FileCheck %s < %t
|
|
|
|
|
|
|
|
def a {
|
|
|
|
bits<2> opc = { 0, 1 };
|
|
|
|
bits<2> opc2 = { 1, 0 };
|
|
|
|
bits<1> opc3 = { 1 };
|
|
|
|
bits<2> a = { opc, opc2 }; // error!
|
|
|
|
bits<2> b = { opc{0}, opc2{0} };
|
|
|
|
bits<2> c = { opc{1}, opc2{1} };
|
|
|
|
bits<2> c = { opc3{0}, opc3 };
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK: def a {
|
|
|
|
// CHECK: bits<2> opc = { 0, 1 };
|
|
|
|
// CHECK: bits<2> opc2 = { 1, 0 };
|
|
|
|
// CHECK: bits<1> opc3 = { 1 };
|
2014-08-30 03:41:04 +08:00
|
|
|
// CHECK: bits<2> a;
|
2014-08-07 13:46:57 +08:00
|
|
|
// CHECK: bits<2> b = { 1, 0 };
|
|
|
|
// CHECK: bits<2> c = { 1, 1 };
|
|
|
|
// CHECK: }
|
2014-08-07 13:47:00 +08:00
|
|
|
|
|
|
|
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;
|
Change the { } expression in tablegen to accept sized binary literals which are not just 0 and 1.
It also allows nested { } expressions, as now that they are sized, we can merge pull bits from the nested value.
In the current behaviour, everything in { } must have been convertible to a single bit.
However, now that binary literals are sized, its useful to be able to initialize a range of bits.
So, for example, its now possible to do
bits<8> x = { 0, 1, { 0b1001 }, 0, 0b0 }
llvm-svn: 215086
2014-08-07 13:47:07 +08:00
|
|
|
|
|
|
|
bits<8> F1 = { 0, 1, 0b1001, 0, 0b0 }; // ok
|
|
|
|
bits<7> F2 = { 0, 1, 0b1001, 0, 0b0 }; // LHS doesn't have enough bits
|
|
|
|
bits<9> F3 = { 0, 1, 0b1001, 0, 0b0 }; // RHS doesn't have enough bits
|
|
|
|
|
|
|
|
bits<8> G1 = { 0, { 1, 0b1001, 0 }, 0b0 }; // ok
|
|
|
|
bits<8> G2 = { 0, { 1, 0b1001 }, 0, 0b0 }; // ok
|
|
|
|
bits<8> G3 = { 0, 1, { 0b1001 }, 0, 0b0 }; // ok
|
|
|
|
|
|
|
|
bits<16> H;
|
|
|
|
let H{15-0} = { { 0b11001100 }, 0b00110011 };
|
2014-08-30 03:41:04 +08:00
|
|
|
bits<16> I = { G1, G2 };
|
Change the { } expression in tablegen to accept sized binary literals which are not just 0 and 1.
It also allows nested { } expressions, as now that they are sized, we can merge pull bits from the nested value.
In the current behaviour, everything in { } must have been convertible to a single bit.
However, now that binary literals are sized, its useful to be able to initialize a range of bits.
So, for example, its now possible to do
bits<8> x = { 0, 1, { 0b1001 }, 0, 0b0 }
llvm-svn: 215086
2014-08-07 13:47:07 +08:00
|
|
|
|
|
|
|
// Make sure we can initialise ints with bits<> values.
|
|
|
|
int J = H;
|
|
|
|
int K = { 0, 1 };
|
2014-08-07 13:47:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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 };
|
TableGen: Allow !cast of records, cleanup conversion machinery
Summary:
Distinguish two relationships between types: is-a and convertible-to.
For example, a bit is not an int or vice versa, but they can be
converted into each other (with range checks that you can think of
as "dynamic": unlike other type checks, those range checks do not
happen during parsing, but only once the final values have been
established).
Actually converting initializers between types is subtle: even
when values of type A can be converted to type B (e.g. int into
string), it may not be possible to do so with a concrete initializer
(e.g., a VarInit that refers to a variable of type int cannot
be immediately converted to a string).
For this reason, distinguish between getCastTo and convertInitializerTo:
the latter implements the actual conversion when appropriate, while
the former will first try to do the actual conversion and fall back
to introducing a !cast operation so that the conversion will be
delayed until variable references have been resolved.
To make the approach of adding !cast operations to work, !cast needs
to fallback to convertInitializerTo when the special string <-> record
logic does not apply.
This enables casting records to a subclass, although that new
functionality is only truly useful together with !isa, which will be
added in a later change.
The test is removed because it uses !srl on a bit sequence,
which cannot really be supported consistently, but luckily
isn't used anywhere either.
Change-Id: I98168bf52649176654ed2ec61a29bdb29970cfe7
Reviewers: arsenm, craig.topper, tra, MartinO
Subscribers: wdng, llvm-commits
Differential Revision: https://reviews.llvm.org/D43753
llvm-svn: 326785
2018-03-06 21:48:39 +08:00
|
|
|
// CHECK: bits<1> D7 = { !cast<bit>(3) };
|
2014-08-07 13:47:00 +08:00
|
|
|
// CHECK: bits<2> D8;
|
|
|
|
// CHECK: bits<8> E = { 0, 0, 1, ?, 0, 0, 1, 0 };
|
Change the { } expression in tablegen to accept sized binary literals which are not just 0 and 1.
It also allows nested { } expressions, as now that they are sized, we can merge pull bits from the nested value.
In the current behaviour, everything in { } must have been convertible to a single bit.
However, now that binary literals are sized, its useful to be able to initialize a range of bits.
So, for example, its now possible to do
bits<8> x = { 0, 1, { 0b1001 }, 0, 0b0 }
llvm-svn: 215086
2014-08-07 13:47:07 +08:00
|
|
|
// CHECK: bits<8> F1 = { 0, 1, 1, 0, 0, 1, 0, 0 };
|
|
|
|
// CHECK: bits<7> F2;
|
|
|
|
// CHECK: bits<9> F3;
|
|
|
|
// CHECK: bits<8> G1 = { 0, 1, 1, 0, 0, 1, 0, 0 };
|
|
|
|
// CHECK: bits<8> G2 = { 0, 1, 1, 0, 0, 1, 0, 0 };
|
|
|
|
// CHECK: bits<8> G3 = { 0, 1, 1, 0, 0, 1, 0, 0 };
|
|
|
|
// CHECK: bits<16> H = { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1 };
|
2014-08-30 03:41:04 +08:00
|
|
|
// CHECK: bits<16> I = { 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0 };
|
Change the { } expression in tablegen to accept sized binary literals which are not just 0 and 1.
It also allows nested { } expressions, as now that they are sized, we can merge pull bits from the nested value.
In the current behaviour, everything in { } must have been convertible to a single bit.
However, now that binary literals are sized, its useful to be able to initialize a range of bits.
So, for example, its now possible to do
bits<8> x = { 0, 1, { 0b1001 }, 0, 0b0 }
llvm-svn: 215086
2014-08-07 13:47:07 +08:00
|
|
|
// CHECK: int J = 52275;
|
|
|
|
// CHECK: int K = 1;
|
2014-08-07 13:47:00 +08:00
|
|
|
// CHECK: }
|