aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen/TGParser.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2010-12-13 01:46:19 +0000
committerBill Wendling <isanbard@gmail.com>2010-12-13 01:46:19 +0000
commit548f5a0b751aafba88473e4863c2baf7741b56a5 (patch)
treea27b4776c6bc3c5ee1d938632121d9d6e2664e61 /utils/TableGen/TGParser.cpp
parentdcb54ce3da15ba41adeee020288e6c62cfae8c42 (diff)
Add support for using the `!if' operator when initializing variables:
class A<bit a, bits<3> x, bits<3> y> { bits<3> z; let z = !if(a, x, y); } The variable z will get the value of x when 'a' is 1 and 'y' when a is '0'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121666 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/TGParser.cpp')
-rw-r--r--utils/TableGen/TGParser.cpp44
1 files changed, 36 insertions, 8 deletions
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index d99632e9e4..57e9f83339 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -868,7 +868,6 @@ Init *TGParser::ParseOperation(Record *CurRec) {
TernOpInit::TernaryOp Code;
RecTy *Type = 0;
-
tgtok::TokKind LexCode = Lex.getCode();
Lex.Lex(); // eat the operation
switch (LexCode) {
@@ -919,16 +918,45 @@ Init *TGParser::ParseOperation(Record *CurRec) {
switch (LexCode) {
default: assert(0 && "Unhandled code!");
case tgtok::XIf: {
- TypedInit *MHSt = dynamic_cast<TypedInit *>(MHS);
- TypedInit *RHSt = dynamic_cast<TypedInit *>(RHS);
- if (MHSt == 0 || RHSt == 0) {
+ // FIXME: The `!if' operator doesn't handle non-TypedInit well at
+ // all. This can be made much more robust.
+ TypedInit *MHSt = dynamic_cast<TypedInit*>(MHS);
+ TypedInit *RHSt = dynamic_cast<TypedInit*>(RHS);
+
+ RecTy *MHSTy = 0;
+ RecTy *RHSTy = 0;
+
+ if (MHSt == 0 && RHSt == 0) {
+ BitsInit *MHSbits = dynamic_cast<BitsInit*>(MHS);
+ BitsInit *RHSbits = dynamic_cast<BitsInit*>(RHS);
+
+ if (MHSbits && RHSbits &&
+ MHSbits->getNumBits() == RHSbits->getNumBits()) {
+ Type = new BitRecTy();
+ break;
+ } else {
+ BitInit *MHSbit = dynamic_cast<BitInit*>(MHS);
+ BitInit *RHSbit = dynamic_cast<BitInit*>(RHS);
+
+ if (MHSbit && RHSbit) {
+ Type = new BitRecTy();
+ break;
+ }
+ }
+ } else if (MHSt != 0 && RHSt != 0) {
+ MHSTy = MHSt->getType();
+ RHSTy = RHSt->getType();
+ }
+
+ if (!MHSTy || !RHSTy) {
TokError("could not get type for !if");
return 0;
}
- if (MHSt->getType()->typeIsConvertibleTo(RHSt->getType())) {
- Type = RHSt->getType();
- } else if (RHSt->getType()->typeIsConvertibleTo(MHSt->getType())) {
- Type = MHSt->getType();
+
+ if (MHSTy->typeIsConvertibleTo(RHSTy)) {
+ Type = RHSTy;
+ } else if (RHSTy->typeIsConvertibleTo(MHSTy)) {
+ Type = MHSTy;
} else {
TokError("inconsistent types for !if");
return 0;