mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-11 13:37:07 +00:00
f579c9339d
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
86 lines
2.5 KiB
TableGen
86 lines
2.5 KiB
TableGen
|
|
// 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 };
|
|
// CHECK: bits<2> 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;
|
|
|
|
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 };
|
|
bits<16> I = { G1, G2 };
|
|
|
|
// Make sure we can initialise ints with bits<> values.
|
|
int J = H;
|
|
int K = { 0, 1 };
|
|
}
|
|
|
|
// 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 = { !cast<bit>(3) };
|
|
// CHECK: bits<2> D8;
|
|
// CHECK: bits<8> E = { 0, 0, 1, ?, 0, 0, 1, 0 };
|
|
// 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 };
|
|
// CHECK: bits<16> I = { 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0 };
|
|
// CHECK: int J = 52275;
|
|
// CHECK: int K = 1;
|
|
// CHECK: }
|