blob: 730eca1b3ca5d94e087e3b6c8e4271587ef65788 [file] [log] [blame]
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001//===- Record.cpp - Record implementation ---------------------------------===//
Misha Brukman650ba8e2005-04-22 00:00:37 +00002//
John Criswelld3032032003-10-20 20:20:30 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner8adcd9f2007-12-29 20:37:13 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Misha Brukman650ba8e2005-04-22 00:00:37 +00007//
John Criswelld3032032003-10-20 20:20:30 +00008//===----------------------------------------------------------------------===//
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00009//
Chris Lattner51ffbf12006-03-31 21:53:49 +000010// Implement the tablegen record classes.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000011//
12//===----------------------------------------------------------------------===//
13
14#include "Record.h"
Jim Grosbach797cff02011-06-21 22:55:50 +000015#include "Error.h"
Michael J. Spencer447762d2010-11-29 18:16:10 +000016#include "llvm/Support/DataTypes.h"
Daniel Dunbar38a22bf2009-07-03 00:10:29 +000017#include "llvm/Support/Format.h"
Chris Lattner8b9ecda2007-11-20 22:25:16 +000018#include "llvm/ADT/StringExtras.h"
Duraid Madina14492af2005-12-26 05:08:55 +000019
Chris Lattner68478662004-08-01 03:55:39 +000020using namespace llvm;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000021
22//===----------------------------------------------------------------------===//
23// Type implementations
24//===----------------------------------------------------------------------===//
25
Daniel Dunbar38a22bf2009-07-03 00:10:29 +000026void RecTy::dump() const { print(errs()); }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000027
Eric Christopher71520a82011-07-11 23:06:52 +000028Init *BitRecTy::convertValue(BitsInit *BI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000029 if (BI->getNumBits() != 1) return 0; // Only accept if just one bit!
30 return BI->getBit(0);
31}
32
33bool BitRecTy::baseClassOf(const BitsRecTy *RHS) const {
34 return RHS->getNumBits() == 1;
35}
36
Eric Christopher71520a82011-07-11 23:06:52 +000037Init *BitRecTy::convertValue(IntInit *II) {
Dan Gohmanca0546f2008-10-17 01:33:43 +000038 int64_t Val = II->getValue();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000039 if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit!
Misha Brukman650ba8e2005-04-22 00:00:37 +000040
Eric Christopher71520a82011-07-11 23:06:52 +000041 return new BitInit(Val != 0);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000042}
43
Eric Christopher71520a82011-07-11 23:06:52 +000044Init *BitRecTy::convertValue(TypedInit *VI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000045 if (dynamic_cast<BitRecTy*>(VI->getType()))
46 return VI; // Accept variable if it is already of bit type!
47 return 0;
48}
49
Chris Lattner8b9ecda2007-11-20 22:25:16 +000050std::string BitsRecTy::getAsString() const {
51 return "bits<" + utostr(Size) + ">";
52}
53
Eric Christopher71520a82011-07-11 23:06:52 +000054Init *BitsRecTy::convertValue(UnsetInit *UI) {
55 BitsInit *Ret = new BitsInit(Size);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000056
57 for (unsigned i = 0; i != Size; ++i)
Eric Christopher71520a82011-07-11 23:06:52 +000058 Ret->setBit(i, new UnsetInit());
59 return Ret;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000060}
61
Eric Christopher71520a82011-07-11 23:06:52 +000062Init *BitsRecTy::convertValue(BitInit *UI) {
Bill Wendling73a48d82010-12-10 22:54:30 +000063 if (Size != 1) return 0; // Can only convert single bit.
Eric Christopher71520a82011-07-11 23:06:52 +000064 BitsInit *Ret = new BitsInit(1);
65 Ret->setBit(0, UI);
66 return Ret;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000067}
68
Bill Wendling73ce4a62010-12-13 01:46:19 +000069/// canFitInBitfield - Return true if the number of bits is large enough to hold
70/// the integer value.
71static bool canFitInBitfield(int64_t Value, unsigned NumBits) {
Nick Lewycky79286bf2011-06-03 08:25:39 +000072 // For example, with NumBits == 4, we permit Values from [-7 .. 15].
73 return (NumBits >= sizeof(Value) * 8) ||
74 (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);
Bill Wendling73ce4a62010-12-13 01:46:19 +000075}
76
Eric Christopher71520a82011-07-11 23:06:52 +000077/// convertValue from Int initializer to bits type: Split the integer up into the
78/// appropriate bits.
Bill Wendling73ce4a62010-12-13 01:46:19 +000079///
Eric Christopher71520a82011-07-11 23:06:52 +000080Init *BitsRecTy::convertValue(IntInit *II) {
Misha Brukman6752fb52004-06-21 18:01:47 +000081 int64_t Value = II->getValue();
Bill Wendling73a48d82010-12-10 22:54:30 +000082 // Make sure this bitfield is large enough to hold the integer value.
Bill Wendling73ce4a62010-12-13 01:46:19 +000083 if (!canFitInBitfield(Value, Size))
84 return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000085
Eric Christopher71520a82011-07-11 23:06:52 +000086 BitsInit *Ret = new BitsInit(Size);
David Greeneaf973b42011-07-11 18:25:51 +000087 for (unsigned i = 0; i != Size; ++i)
Eric Christopher71520a82011-07-11 23:06:52 +000088 Ret->setBit(i, new BitInit(Value & (1LL << i)));
David Greeneaf973b42011-07-11 18:25:51 +000089
Eric Christopher71520a82011-07-11 23:06:52 +000090 return Ret;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000091}
92
Eric Christopher71520a82011-07-11 23:06:52 +000093Init *BitsRecTy::convertValue(BitsInit *BI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000094 // If the number of bits is right, return it. Otherwise we need to expand or
Bill Wendling73a48d82010-12-10 22:54:30 +000095 // truncate.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000096 if (BI->getNumBits() == Size) return BI;
97 return 0;
98}
99
Eric Christopher71520a82011-07-11 23:06:52 +0000100Init *BitsRecTy::convertValue(TypedInit *VI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000101 if (BitsRecTy *BRT = dynamic_cast<BitsRecTy*>(VI->getType()))
102 if (BRT->Size == Size) {
Eric Christopher71520a82011-07-11 23:06:52 +0000103 BitsInit *Ret = new BitsInit(Size);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000104 for (unsigned i = 0; i != Size; ++i)
Eric Christopher71520a82011-07-11 23:06:52 +0000105 Ret->setBit(i, new VarBitInit(VI, i));
106 return Ret;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000107 }
Bill Wendling73ce4a62010-12-13 01:46:19 +0000108
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000109 if (Size == 1 && dynamic_cast<BitRecTy*>(VI->getType())) {
Eric Christopher71520a82011-07-11 23:06:52 +0000110 BitsInit *Ret = new BitsInit(1);
111 Ret->setBit(0, VI);
112 return Ret;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000113 }
Misha Brukman650ba8e2005-04-22 00:00:37 +0000114
Eric Christopher71520a82011-07-11 23:06:52 +0000115 if (TernOpInit *Tern = dynamic_cast<TernOpInit*>(VI)) {
Bill Wendling73ce4a62010-12-13 01:46:19 +0000116 if (Tern->getOpcode() == TernOpInit::IF) {
Eric Christopher71520a82011-07-11 23:06:52 +0000117 Init *LHS = Tern->getLHS();
118 Init *MHS = Tern->getMHS();
119 Init *RHS = Tern->getRHS();
Bill Wendling73ce4a62010-12-13 01:46:19 +0000120
Eric Christopher71520a82011-07-11 23:06:52 +0000121 IntInit *MHSi = dynamic_cast<IntInit*>(MHS);
122 IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
Bill Wendling73ce4a62010-12-13 01:46:19 +0000123
124 if (MHSi && RHSi) {
125 int64_t MHSVal = MHSi->getValue();
126 int64_t RHSVal = RHSi->getValue();
127
128 if (canFitInBitfield(MHSVal, Size) && canFitInBitfield(RHSVal, Size)) {
Eric Christopher71520a82011-07-11 23:06:52 +0000129 BitsInit *Ret = new BitsInit(Size);
Bill Wendling73ce4a62010-12-13 01:46:19 +0000130
131 for (unsigned i = 0; i != Size; ++i)
Eric Christopher71520a82011-07-11 23:06:52 +0000132 Ret->setBit(i, new TernOpInit(TernOpInit::IF, LHS,
133 new IntInit((MHSVal & (1LL << i)) ? 1 : 0),
134 new IntInit((RHSVal & (1LL << i)) ? 1 : 0),
135 VI->getType()));
136
137 return Ret;
Bill Wendling73ce4a62010-12-13 01:46:19 +0000138 }
139 } else {
Eric Christopher71520a82011-07-11 23:06:52 +0000140 BitsInit *MHSbs = dynamic_cast<BitsInit*>(MHS);
141 BitsInit *RHSbs = dynamic_cast<BitsInit*>(RHS);
Bill Wendling73ce4a62010-12-13 01:46:19 +0000142
143 if (MHSbs && RHSbs) {
Eric Christopher71520a82011-07-11 23:06:52 +0000144 BitsInit *Ret = new BitsInit(Size);
Bill Wendling73ce4a62010-12-13 01:46:19 +0000145
146 for (unsigned i = 0; i != Size; ++i)
Eric Christopher71520a82011-07-11 23:06:52 +0000147 Ret->setBit(i, new TernOpInit(TernOpInit::IF, LHS,
148 MHSbs->getBit(i),
149 RHSbs->getBit(i),
150 VI->getType()));
Bill Wendling73ce4a62010-12-13 01:46:19 +0000151
Eric Christopher71520a82011-07-11 23:06:52 +0000152 return Ret;
Bill Wendling73ce4a62010-12-13 01:46:19 +0000153 }
154 }
155 }
156 }
157
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000158 return 0;
159}
160
Eric Christopher71520a82011-07-11 23:06:52 +0000161Init *IntRecTy::convertValue(BitInit *BI) {
162 return new IntInit(BI->getValue());
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000163}
164
Eric Christopher71520a82011-07-11 23:06:52 +0000165Init *IntRecTy::convertValue(BitsInit *BI) {
Dan Gohmanca0546f2008-10-17 01:33:43 +0000166 int64_t Result = 0;
Misha Brukman650ba8e2005-04-22 00:00:37 +0000167 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
Eric Christopher71520a82011-07-11 23:06:52 +0000168 if (BitInit *Bit = dynamic_cast<BitInit*>(BI->getBit(i))) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000169 Result |= Bit->getValue() << i;
170 } else {
171 return 0;
172 }
Eric Christopher71520a82011-07-11 23:06:52 +0000173 return new IntInit(Result);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000174}
175
Eric Christopher71520a82011-07-11 23:06:52 +0000176Init *IntRecTy::convertValue(TypedInit *TI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000177 if (TI->getType()->typeIsConvertibleTo(this))
178 return TI; // Accept variable if already of the right type!
179 return 0;
180}
181
Eric Christopher71520a82011-07-11 23:06:52 +0000182Init *StringRecTy::convertValue(UnOpInit *BO) {
David Greenee8f3b272009-05-14 21:22:49 +0000183 if (BO->getOpcode() == UnOpInit::CAST) {
Eric Christopher71520a82011-07-11 23:06:52 +0000184 Init *L = BO->getOperand()->convertInitializerTo(this);
David Greenee8f3b272009-05-14 21:22:49 +0000185 if (L == 0) return 0;
186 if (L != BO->getOperand())
Eric Christopher71520a82011-07-11 23:06:52 +0000187 return new UnOpInit(UnOpInit::CAST, L, new StringRecTy);
David Greenee8f3b272009-05-14 21:22:49 +0000188 return BO;
189 }
David Greene5d0c0512009-05-14 20:54:48 +0000190
Eric Christopher71520a82011-07-11 23:06:52 +0000191 return convertValue((TypedInit*)BO);
David Greenee8f3b272009-05-14 21:22:49 +0000192}
David Greene5d0c0512009-05-14 20:54:48 +0000193
Eric Christopher71520a82011-07-11 23:06:52 +0000194Init *StringRecTy::convertValue(BinOpInit *BO) {
Chris Lattner51ffbf12006-03-31 21:53:49 +0000195 if (BO->getOpcode() == BinOpInit::STRCONCAT) {
Eric Christopher71520a82011-07-11 23:06:52 +0000196 Init *L = BO->getLHS()->convertInitializerTo(this);
197 Init *R = BO->getRHS()->convertInitializerTo(this);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000198 if (L == 0 || R == 0) return 0;
199 if (L != BO->getLHS() || R != BO->getRHS())
Eric Christopher71520a82011-07-11 23:06:52 +0000200 return new BinOpInit(BinOpInit::STRCONCAT, L, R, new StringRecTy);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000201 return BO;
202 }
David Greene196ac3c2009-04-23 21:25:15 +0000203
Eric Christopher71520a82011-07-11 23:06:52 +0000204 return convertValue((TypedInit*)BO);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000205}
206
207
Eric Christopher71520a82011-07-11 23:06:52 +0000208Init *StringRecTy::convertValue(TypedInit *TI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000209 if (dynamic_cast<StringRecTy*>(TI->getType()))
210 return TI; // Accept variable if already of the right type!
211 return 0;
212}
213
Chris Lattner8b9ecda2007-11-20 22:25:16 +0000214std::string ListRecTy::getAsString() const {
215 return "list<" + Ty->getAsString() + ">";
216}
217
Eric Christopher71520a82011-07-11 23:06:52 +0000218Init *ListRecTy::convertValue(ListInit *LI) {
219 std::vector<Init*> Elements;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000220
221 // Verify that all of the elements of the list are subclasses of the
222 // appropriate class!
223 for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
Eric Christopher71520a82011-07-11 23:06:52 +0000224 if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000225 Elements.push_back(CI);
226 else
227 return 0;
228
David Greene8618f952009-06-08 20:23:18 +0000229 ListRecTy *LType = dynamic_cast<ListRecTy*>(LI->getType());
230 if (LType == 0) {
231 return 0;
232 }
233
Eric Christopher71520a82011-07-11 23:06:52 +0000234 return new ListInit(Elements, new ListRecTy(Ty));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000235}
236
Eric Christopher71520a82011-07-11 23:06:52 +0000237Init *ListRecTy::convertValue(TypedInit *TI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000238 // Ensure that TI is compatible with our class.
239 if (ListRecTy *LRT = dynamic_cast<ListRecTy*>(TI->getType()))
240 if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
241 return TI;
242 return 0;
243}
244
Eric Christopher71520a82011-07-11 23:06:52 +0000245Init *CodeRecTy::convertValue(TypedInit *TI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000246 if (TI->getType()->typeIsConvertibleTo(this))
247 return TI;
248 return 0;
249}
250
Eric Christopher71520a82011-07-11 23:06:52 +0000251Init *DagRecTy::convertValue(TypedInit *TI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000252 if (TI->getType()->typeIsConvertibleTo(this))
253 return TI;
254 return 0;
255}
256
Eric Christopher71520a82011-07-11 23:06:52 +0000257Init *DagRecTy::convertValue(UnOpInit *BO) {
David Greenee8f3b272009-05-14 21:22:49 +0000258 if (BO->getOpcode() == UnOpInit::CAST) {
Eric Christopher71520a82011-07-11 23:06:52 +0000259 Init *L = BO->getOperand()->convertInitializerTo(this);
David Greenee8f3b272009-05-14 21:22:49 +0000260 if (L == 0) return 0;
261 if (L != BO->getOperand())
Eric Christopher71520a82011-07-11 23:06:52 +0000262 return new UnOpInit(UnOpInit::CAST, L, new DagRecTy);
David Greenee8f3b272009-05-14 21:22:49 +0000263 return BO;
264 }
265 return 0;
266}
David Greene5d0c0512009-05-14 20:54:48 +0000267
Eric Christopher71520a82011-07-11 23:06:52 +0000268Init *DagRecTy::convertValue(BinOpInit *BO) {
Evan Chenga32dee22007-05-15 01:23:24 +0000269 if (BO->getOpcode() == BinOpInit::CONCAT) {
Eric Christopher71520a82011-07-11 23:06:52 +0000270 Init *L = BO->getLHS()->convertInitializerTo(this);
271 Init *R = BO->getRHS()->convertInitializerTo(this);
Evan Chenga32dee22007-05-15 01:23:24 +0000272 if (L == 0 || R == 0) return 0;
273 if (L != BO->getLHS() || R != BO->getRHS())
Eric Christopher71520a82011-07-11 23:06:52 +0000274 return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
Evan Chenga32dee22007-05-15 01:23:24 +0000275 return BO;
276 }
277 return 0;
278}
279
Chris Lattner8b9ecda2007-11-20 22:25:16 +0000280std::string RecordRecTy::getAsString() const {
281 return Rec->getName();
282}
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000283
Eric Christopher71520a82011-07-11 23:06:52 +0000284Init *RecordRecTy::convertValue(DefInit *DI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000285 // Ensure that DI is a subclass of Rec.
286 if (!DI->getDef()->isSubClassOf(Rec))
287 return 0;
288 return DI;
289}
290
Eric Christopher71520a82011-07-11 23:06:52 +0000291Init *RecordRecTy::convertValue(TypedInit *TI) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000292 // Ensure that TI is compatible with Rec.
293 if (RecordRecTy *RRT = dynamic_cast<RecordRecTy*>(TI->getType()))
294 if (RRT->getRecord()->isSubClassOf(getRecord()) ||
295 RRT->getRecord() == getRecord())
296 return TI;
297 return 0;
298}
299
300bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
Bruno Cardoso Lopesdeb20022010-06-17 23:00:16 +0000301 if (Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec))
302 return true;
303
304 const std::vector<Record*> &SC = Rec->getSuperClasses();
305 for (unsigned i = 0, e = SC.size(); i != e; ++i)
306 if (RHS->getRecord()->isSubClassOf(SC[i]))
307 return true;
308
309 return false;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000310}
311
312
Bob Wilson7248f862009-11-22 04:24:42 +0000313/// resolveTypes - Find a common type that T1 and T2 convert to.
David Greene8618f952009-06-08 20:23:18 +0000314/// Return 0 if no such type exists.
315///
316RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
317 if (!T1->typeIsConvertibleTo(T2)) {
318 if (!T2->typeIsConvertibleTo(T1)) {
319 // If one is a Record type, check superclasses
320 RecordRecTy *RecTy1 = dynamic_cast<RecordRecTy*>(T1);
321 if (RecTy1) {
322 // See if T2 inherits from a type T1 also inherits from
Bob Wilson7248f862009-11-22 04:24:42 +0000323 const std::vector<Record *> &T1SuperClasses =
324 RecTy1->getRecord()->getSuperClasses();
David Greene8618f952009-06-08 20:23:18 +0000325 for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
326 iend = T1SuperClasses.end();
327 i != iend;
328 ++i) {
329 RecordRecTy *SuperRecTy1 = new RecordRecTy(*i);
330 RecTy *NewType1 = resolveTypes(SuperRecTy1, T2);
331 if (NewType1 != 0) {
332 if (NewType1 != SuperRecTy1) {
333 delete SuperRecTy1;
334 }
335 return NewType1;
336 }
337 }
338 }
339 RecordRecTy *RecTy2 = dynamic_cast<RecordRecTy*>(T2);
340 if (RecTy2) {
341 // See if T1 inherits from a type T2 also inherits from
Bob Wilson7248f862009-11-22 04:24:42 +0000342 const std::vector<Record *> &T2SuperClasses =
343 RecTy2->getRecord()->getSuperClasses();
344 for (std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
David Greene8618f952009-06-08 20:23:18 +0000345 iend = T2SuperClasses.end();
346 i != iend;
347 ++i) {
348 RecordRecTy *SuperRecTy2 = new RecordRecTy(*i);
349 RecTy *NewType2 = resolveTypes(T1, SuperRecTy2);
350 if (NewType2 != 0) {
351 if (NewType2 != SuperRecTy2) {
352 delete SuperRecTy2;
353 }
354 return NewType2;
355 }
356 }
357 }
358 return 0;
359 }
360 return T2;
361 }
362 return T1;
363}
364
365
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000366//===----------------------------------------------------------------------===//
367// Initializer implementations
368//===----------------------------------------------------------------------===//
369
Daniel Dunbar38a22bf2009-07-03 00:10:29 +0000370void Init::dump() const { return print(errs()); }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000371
Eric Christopher71520a82011-07-11 23:06:52 +0000372Init *BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
373 BitsInit *BI = new BitsInit(Bits.size());
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000374 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
375 if (Bits[i] >= getNumBits()) {
Eric Christopher71520a82011-07-11 23:06:52 +0000376 delete BI;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000377 return 0;
378 }
Eric Christopher71520a82011-07-11 23:06:52 +0000379 BI->setBit(i, getBit(Bits[i]));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000380 }
Eric Christopher71520a82011-07-11 23:06:52 +0000381 return BI;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000382}
383
Chris Lattner695506c2007-11-22 21:05:25 +0000384std::string BitsInit::getAsString() const {
Chris Lattner695506c2007-11-22 21:05:25 +0000385 std::string Result = "{ ";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000386 for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
Chris Lattner695506c2007-11-22 21:05:25 +0000387 if (i) Result += ", ";
Eric Christopher71520a82011-07-11 23:06:52 +0000388 if (Init *Bit = getBit(e-i-1))
Chris Lattner695506c2007-11-22 21:05:25 +0000389 Result += Bit->getAsString();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000390 else
Chris Lattner695506c2007-11-22 21:05:25 +0000391 Result += "*";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000392 }
Chris Lattner695506c2007-11-22 21:05:25 +0000393 return Result + " }";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000394}
395
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000396// resolveReferences - If there are any field references that refer to fields
397// that have been filled in, we can propagate the values now.
398//
Eric Christopher71520a82011-07-11 23:06:52 +0000399Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000400 bool Changed = false;
Eric Christopher71520a82011-07-11 23:06:52 +0000401 BitsInit *New = new BitsInit(getNumBits());
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000402
Eric Christopher71520a82011-07-11 23:06:52 +0000403 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
404 Init *B;
405 Init *CurBit = getBit(i);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000406
407 do {
408 B = CurBit;
Chris Lattneref943742005-04-19 03:36:21 +0000409 CurBit = CurBit->resolveReferences(R, RV);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000410 Changed |= B != CurBit;
411 } while (B != CurBit);
Eric Christopher71520a82011-07-11 23:06:52 +0000412 New->setBit(i, CurBit);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000413 }
414
415 if (Changed)
Eric Christopher71520a82011-07-11 23:06:52 +0000416 return New;
417 delete New;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000418 return this;
419}
420
Chris Lattner695506c2007-11-22 21:05:25 +0000421std::string IntInit::getAsString() const {
422 return itostr(Value);
423}
424
Eric Christopher71520a82011-07-11 23:06:52 +0000425Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
426 BitsInit *BI = new BitsInit(Bits.size());
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000427
428 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
Eric Christopher71520a82011-07-11 23:06:52 +0000429 if (Bits[i] >= 64) {
430 delete BI;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000431 return 0;
Eric Christopher71520a82011-07-11 23:06:52 +0000432 }
433 BI->setBit(i, new BitInit(Value & (INT64_C(1) << Bits[i])));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000434 }
Eric Christopher71520a82011-07-11 23:06:52 +0000435 return BI;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000436}
437
Eric Christopher71520a82011-07-11 23:06:52 +0000438Init *ListInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
439 std::vector<Init*> Vals;
Chris Lattner8bf9e062004-07-26 23:21:34 +0000440 for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
441 if (Elements[i] >= getSize())
442 return 0;
443 Vals.push_back(getElement(Elements[i]));
444 }
Eric Christopher71520a82011-07-11 23:06:52 +0000445 return new ListInit(Vals, getType());
Chris Lattner8bf9e062004-07-26 23:21:34 +0000446}
447
Chris Lattnercbebe462007-02-27 22:08:27 +0000448Record *ListInit::getElementAsRecord(unsigned i) const {
449 assert(i < Values.size() && "List element index out of range!");
Eric Christopher71520a82011-07-11 23:06:52 +0000450 DefInit *DI = dynamic_cast<DefInit*>(Values[i]);
Chris Lattnercbebe462007-02-27 22:08:27 +0000451 if (DI == 0) throw "Expected record in list!";
452 return DI->getDef();
453}
454
Eric Christopher71520a82011-07-11 23:06:52 +0000455Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) {
456 std::vector<Init*> Resolved;
Chris Lattner577fc3f2004-07-27 01:01:21 +0000457 Resolved.reserve(getSize());
458 bool Changed = false;
459
460 for (unsigned i = 0, e = getSize(); i != e; ++i) {
Eric Christopher71520a82011-07-11 23:06:52 +0000461 Init *E;
462 Init *CurElt = getElement(i);
Chris Lattner577fc3f2004-07-27 01:01:21 +0000463
464 do {
465 E = CurElt;
Chris Lattneref943742005-04-19 03:36:21 +0000466 CurElt = CurElt->resolveReferences(R, RV);
Chris Lattner577fc3f2004-07-27 01:01:21 +0000467 Changed |= E != CurElt;
468 } while (E != CurElt);
469 Resolved.push_back(E);
470 }
471
472 if (Changed)
Eric Christopher71520a82011-07-11 23:06:52 +0000473 return new ListInit(Resolved, getType());
Chris Lattner577fc3f2004-07-27 01:01:21 +0000474 return this;
475}
476
Eric Christopher71520a82011-07-11 23:06:52 +0000477Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
478 unsigned Elt) {
David Greene8618f952009-06-08 20:23:18 +0000479 if (Elt >= getSize())
480 return 0; // Out of range reference.
Eric Christopher71520a82011-07-11 23:06:52 +0000481 Init *E = getElement(Elt);
Bob Wilson67e6cab2009-11-22 03:58:57 +0000482 // If the element is set to some value, or if we are resolving a reference
483 // to a specific variable and that variable is explicitly unset, then
484 // replace the VarListElementInit with it.
Eric Christopher71520a82011-07-11 23:06:52 +0000485 if (IRV || !dynamic_cast<UnsetInit*>(E))
Bob Wilson67e6cab2009-11-22 03:58:57 +0000486 return E;
David Greene8618f952009-06-08 20:23:18 +0000487 return 0;
488}
489
Chris Lattner695506c2007-11-22 21:05:25 +0000490std::string ListInit::getAsString() const {
491 std::string Result = "[";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000492 for (unsigned i = 0, e = Values.size(); i != e; ++i) {
Chris Lattner695506c2007-11-22 21:05:25 +0000493 if (i) Result += ", ";
494 Result += Values[i]->getAsString();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000495 }
Chris Lattner695506c2007-11-22 21:05:25 +0000496 return Result + "]";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000497}
498
Eric Christopher71520a82011-07-11 23:06:52 +0000499Init *OpInit::resolveBitReference(Record &R, const RecordVal *IRV,
500 unsigned Bit) {
501 Init *Folded = Fold(&R, 0);
David Greene5d0c0512009-05-14 20:54:48 +0000502
503 if (Folded != this) {
Eric Christopher71520a82011-07-11 23:06:52 +0000504 TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
David Greene5d0c0512009-05-14 20:54:48 +0000505 if (Typed) {
506 return Typed->resolveBitReference(R, IRV, Bit);
Bob Wilson7248f862009-11-22 04:24:42 +0000507 }
David Greene5d0c0512009-05-14 20:54:48 +0000508 }
Bob Wilson7248f862009-11-22 04:24:42 +0000509
David Greene5d0c0512009-05-14 20:54:48 +0000510 return 0;
511}
512
Eric Christopher71520a82011-07-11 23:06:52 +0000513Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
514 unsigned Elt) {
515 Init *Folded = Fold(&R, 0);
David Greene5d0c0512009-05-14 20:54:48 +0000516
517 if (Folded != this) {
Eric Christopher71520a82011-07-11 23:06:52 +0000518 TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
David Greene5d0c0512009-05-14 20:54:48 +0000519 if (Typed) {
520 return Typed->resolveListElementReference(R, IRV, Elt);
Bob Wilson7248f862009-11-22 04:24:42 +0000521 }
David Greene5d0c0512009-05-14 20:54:48 +0000522 }
Bob Wilson7248f862009-11-22 04:24:42 +0000523
David Greene5d0c0512009-05-14 20:54:48 +0000524 return 0;
525}
526
Eric Christopher71520a82011-07-11 23:06:52 +0000527Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
David Greenee8f3b272009-05-14 21:22:49 +0000528 switch (getOpcode()) {
529 default: assert(0 && "Unknown unop");
530 case CAST: {
David Greeneefa19612009-06-29 20:05:29 +0000531 if (getType()->getAsString() == "string") {
Eric Christopher71520a82011-07-11 23:06:52 +0000532 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
David Greeneefa19612009-06-29 20:05:29 +0000533 if (LHSs) {
534 return LHSs;
535 }
David Greene5d0c0512009-05-14 20:54:48 +0000536
Eric Christopher71520a82011-07-11 23:06:52 +0000537 DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
David Greeneefa19612009-06-29 20:05:29 +0000538 if (LHSd) {
Eric Christopher71520a82011-07-11 23:06:52 +0000539 return new StringInit(LHSd->getDef()->getName());
David Greeneefa19612009-06-29 20:05:29 +0000540 }
Bob Wilson7248f862009-11-22 04:24:42 +0000541 } else {
Eric Christopher71520a82011-07-11 23:06:52 +0000542 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
David Greeneefa19612009-06-29 20:05:29 +0000543 if (LHSs) {
544 std::string Name = LHSs->getValue();
545
546 // From TGParser::ParseIDValue
547 if (CurRec) {
548 if (const RecordVal *RV = CurRec->getValue(Name)) {
Chris Lattner94026332010-10-06 00:19:21 +0000549 if (RV->getType() != getType())
550 throw "type mismatch in cast";
Eric Christopher71520a82011-07-11 23:06:52 +0000551 return new VarInit(Name, RV->getType());
David Greenee8f3b272009-05-14 21:22:49 +0000552 }
David Greeneefa19612009-06-29 20:05:29 +0000553
554 std::string TemplateArgName = CurRec->getName()+":"+Name;
555 if (CurRec->isTemplateArg(TemplateArgName)) {
556 const RecordVal *RV = CurRec->getValue(TemplateArgName);
557 assert(RV && "Template arg doesn't exist??");
558
Chris Lattner94026332010-10-06 00:19:21 +0000559 if (RV->getType() != getType())
560 throw "type mismatch in cast";
David Greeneefa19612009-06-29 20:05:29 +0000561
Eric Christopher71520a82011-07-11 23:06:52 +0000562 return new VarInit(TemplateArgName, RV->getType());
David Greeneefa19612009-06-29 20:05:29 +0000563 }
564 }
565
566 if (CurMultiClass) {
567 std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
568 if (CurMultiClass->Rec.isTemplateArg(MCName)) {
569 const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
570 assert(RV && "Template arg doesn't exist??");
Bob Wilson7248f862009-11-22 04:24:42 +0000571
Chris Lattner94026332010-10-06 00:19:21 +0000572 if (RV->getType() != getType())
573 throw "type mismatch in cast";
Bob Wilson7248f862009-11-22 04:24:42 +0000574
Eric Christopher71520a82011-07-11 23:06:52 +0000575 return new VarInit(MCName, RV->getType());
David Greeneefa19612009-06-29 20:05:29 +0000576 }
David Greenee8f3b272009-05-14 21:22:49 +0000577 }
Bob Wilson7248f862009-11-22 04:24:42 +0000578
Chris Lattner77d369c2010-12-13 00:23:57 +0000579 if (Record *D = (CurRec->getRecords()).getDef(Name))
Eric Christopher71520a82011-07-11 23:06:52 +0000580 return new DefInit(D);
David Greene5d0c0512009-05-14 20:54:48 +0000581
Jim Grosbach59ddb732011-05-06 18:47:45 +0000582 throw TGError(CurRec->getLoc(), "Undefined reference:'" + Name + "'\n");
David Greenee8f3b272009-05-14 21:22:49 +0000583 }
David Greenee8f3b272009-05-14 21:22:49 +0000584 }
585 break;
586 }
David Greene2f7cf7f2011-01-07 17:05:37 +0000587 case HEAD: {
Eric Christopher71520a82011-07-11 23:06:52 +0000588 ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
David Greened571b3c2009-05-14 22:38:31 +0000589 if (LHSl) {
590 if (LHSl->getSize() == 0) {
591 assert(0 && "Empty list in car");
592 return 0;
593 }
594 return LHSl->getElement(0);
595 }
596 break;
597 }
David Greene2f7cf7f2011-01-07 17:05:37 +0000598 case TAIL: {
Eric Christopher71520a82011-07-11 23:06:52 +0000599 ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
David Greened571b3c2009-05-14 22:38:31 +0000600 if (LHSl) {
601 if (LHSl->getSize() == 0) {
602 assert(0 && "Empty list in cdr");
603 return 0;
604 }
Eric Christopher71520a82011-07-11 23:06:52 +0000605 ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(),
606 LHSl->getType());
David Greened571b3c2009-05-14 22:38:31 +0000607 return Result;
608 }
609 break;
610 }
David Greene2f7cf7f2011-01-07 17:05:37 +0000611 case EMPTY: {
Eric Christopher71520a82011-07-11 23:06:52 +0000612 ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
David Greened571b3c2009-05-14 22:38:31 +0000613 if (LHSl) {
614 if (LHSl->getSize() == 0) {
Eric Christopher71520a82011-07-11 23:06:52 +0000615 return new IntInit(1);
Bob Wilson7248f862009-11-22 04:24:42 +0000616 } else {
Eric Christopher71520a82011-07-11 23:06:52 +0000617 return new IntInit(0);
David Greened571b3c2009-05-14 22:38:31 +0000618 }
619 }
Eric Christopher71520a82011-07-11 23:06:52 +0000620 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
David Greene8618f952009-06-08 20:23:18 +0000621 if (LHSs) {
622 if (LHSs->getValue().empty()) {
Eric Christopher71520a82011-07-11 23:06:52 +0000623 return new IntInit(1);
Bob Wilson7248f862009-11-22 04:24:42 +0000624 } else {
Eric Christopher71520a82011-07-11 23:06:52 +0000625 return new IntInit(0);
David Greene8618f952009-06-08 20:23:18 +0000626 }
627 }
Bob Wilson7248f862009-11-22 04:24:42 +0000628
David Greened571b3c2009-05-14 22:38:31 +0000629 break;
630 }
David Greenee8f3b272009-05-14 21:22:49 +0000631 }
632 return this;
633}
David Greene5d0c0512009-05-14 20:54:48 +0000634
Eric Christopher71520a82011-07-11 23:06:52 +0000635Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) {
636 Init *lhs = LHS->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +0000637
David Greenee8f3b272009-05-14 21:22:49 +0000638 if (LHS != lhs)
Eric Christopher71520a82011-07-11 23:06:52 +0000639 return (new UnOpInit(getOpcode(), lhs, getType()))->Fold(&R, 0);
David Greenee8f3b272009-05-14 21:22:49 +0000640 return Fold(&R, 0);
641}
David Greene5d0c0512009-05-14 20:54:48 +0000642
David Greenee8f3b272009-05-14 21:22:49 +0000643std::string UnOpInit::getAsString() const {
644 std::string Result;
645 switch (Opc) {
646 case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
David Greene2f7cf7f2011-01-07 17:05:37 +0000647 case HEAD: Result = "!head"; break;
648 case TAIL: Result = "!tail"; break;
649 case EMPTY: Result = "!empty"; break;
David Greenee8f3b272009-05-14 21:22:49 +0000650 }
651 return Result + "(" + LHS->getAsString() + ")";
652}
David Greene5d0c0512009-05-14 20:54:48 +0000653
Eric Christopher71520a82011-07-11 23:06:52 +0000654Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
Chris Lattner51ffbf12006-03-31 21:53:49 +0000655 switch (getOpcode()) {
656 default: assert(0 && "Unknown binop");
Evan Chenga32dee22007-05-15 01:23:24 +0000657 case CONCAT: {
Eric Christopher71520a82011-07-11 23:06:52 +0000658 DagInit *LHSs = dynamic_cast<DagInit*>(LHS);
659 DagInit *RHSs = dynamic_cast<DagInit*>(RHS);
Evan Chenga32dee22007-05-15 01:23:24 +0000660 if (LHSs && RHSs) {
Eric Christopher71520a82011-07-11 23:06:52 +0000661 DefInit *LOp = dynamic_cast<DefInit*>(LHSs->getOperator());
662 DefInit *ROp = dynamic_cast<DefInit*>(RHSs->getOperator());
Chris Lattner81fd1f22010-03-18 21:07:51 +0000663 if (LOp == 0 || ROp == 0 || LOp->getDef() != ROp->getDef())
664 throw "Concated Dag operators do not match!";
Eric Christopher71520a82011-07-11 23:06:52 +0000665 std::vector<Init*> Args;
Evan Chenga32dee22007-05-15 01:23:24 +0000666 std::vector<std::string> ArgNames;
667 for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
668 Args.push_back(LHSs->getArg(i));
669 ArgNames.push_back(LHSs->getArgName(i));
670 }
671 for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
672 Args.push_back(RHSs->getArg(i));
673 ArgNames.push_back(RHSs->getArgName(i));
674 }
Eric Christopher71520a82011-07-11 23:06:52 +0000675 return new DagInit(LHSs->getOperator(), "", Args, ArgNames);
Evan Chenga32dee22007-05-15 01:23:24 +0000676 }
677 break;
678 }
Chris Lattner51ffbf12006-03-31 21:53:49 +0000679 case STRCONCAT: {
Eric Christopher71520a82011-07-11 23:06:52 +0000680 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
681 StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000682 if (LHSs && RHSs)
Eric Christopher71520a82011-07-11 23:06:52 +0000683 return new StringInit(LHSs->getValue() + RHSs->getValue());
Chris Lattner51ffbf12006-03-31 21:53:49 +0000684 break;
685 }
David Greene297bfe62010-01-05 19:11:42 +0000686 case EQ: {
Bruno Cardoso Lopes77a4a562010-06-16 23:24:12 +0000687 // try to fold eq comparison for 'bit' and 'int', otherwise fallback
688 // to string objects.
Eric Christopher71520a82011-07-11 23:06:52 +0000689 IntInit* L =
690 dynamic_cast<IntInit*>(LHS->convertInitializerTo(new IntRecTy()));
691 IntInit* R =
692 dynamic_cast<IntInit*>(RHS->convertInitializerTo(new IntRecTy()));
Bruno Cardoso Lopes77a4a562010-06-16 23:24:12 +0000693
694 if (L && R)
Eric Christopher71520a82011-07-11 23:06:52 +0000695 return new IntInit(L->getValue() == R->getValue());
Bruno Cardoso Lopes77a4a562010-06-16 23:24:12 +0000696
Eric Christopher71520a82011-07-11 23:06:52 +0000697 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
698 StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
Bruno Cardoso Lopes77a4a562010-06-16 23:24:12 +0000699
700 // Make sure we've resolved
David Greene297bfe62010-01-05 19:11:42 +0000701 if (LHSs && RHSs)
Eric Christopher71520a82011-07-11 23:06:52 +0000702 return new IntInit(LHSs->getValue() == RHSs->getValue());
David Greene297bfe62010-01-05 19:11:42 +0000703
704 break;
705 }
Chris Lattner51ffbf12006-03-31 21:53:49 +0000706 case SHL:
707 case SRA:
708 case SRL: {
Eric Christopher71520a82011-07-11 23:06:52 +0000709 IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
710 IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000711 if (LHSi && RHSi) {
Dan Gohmanca0546f2008-10-17 01:33:43 +0000712 int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
713 int64_t Result;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000714 switch (getOpcode()) {
715 default: assert(0 && "Bad opcode!");
716 case SHL: Result = LHSv << RHSv; break;
717 case SRA: Result = LHSv >> RHSv; break;
Dan Gohmanca0546f2008-10-17 01:33:43 +0000718 case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000719 }
Eric Christopher71520a82011-07-11 23:06:52 +0000720 return new IntInit(Result);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000721 }
722 break;
723 }
724 }
725 return this;
726}
727
Eric Christopher71520a82011-07-11 23:06:52 +0000728Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) {
729 Init *lhs = LHS->resolveReferences(R, RV);
730 Init *rhs = RHS->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +0000731
Chris Lattner51ffbf12006-03-31 21:53:49 +0000732 if (LHS != lhs || RHS != rhs)
Eric Christopher71520a82011-07-11 23:06:52 +0000733 return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
David Greenea9c6c5d2009-04-22 20:18:10 +0000734 return Fold(&R, 0);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000735}
736
Chris Lattner695506c2007-11-22 21:05:25 +0000737std::string BinOpInit::getAsString() const {
738 std::string Result;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000739 switch (Opc) {
Chris Lattner695506c2007-11-22 21:05:25 +0000740 case CONCAT: Result = "!con"; break;
741 case SHL: Result = "!shl"; break;
742 case SRA: Result = "!sra"; break;
743 case SRL: Result = "!srl"; break;
David Greene297bfe62010-01-05 19:11:42 +0000744 case EQ: Result = "!eq"; break;
Chris Lattner695506c2007-11-22 21:05:25 +0000745 case STRCONCAT: Result = "!strconcat"; break;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000746 }
Chris Lattner695506c2007-11-22 21:05:25 +0000747 return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
Chris Lattner51ffbf12006-03-31 21:53:49 +0000748}
749
Eric Christopher71520a82011-07-11 23:06:52 +0000750static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
751 Record *CurRec, MultiClass *CurMultiClass);
David Greenee917fff2009-05-14 22:23:47 +0000752
Eric Christopher71520a82011-07-11 23:06:52 +0000753static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
754 RecTy *Type, Record *CurRec,
755 MultiClass *CurMultiClass) {
756 std::vector<Init *> NewOperands;
David Greenee917fff2009-05-14 22:23:47 +0000757
Eric Christopher71520a82011-07-11 23:06:52 +0000758 TypedInit *TArg = dynamic_cast<TypedInit*>(Arg);
David Greenee917fff2009-05-14 22:23:47 +0000759
760 // If this is a dag, recurse
761 if (TArg && TArg->getType()->getAsString() == "dag") {
Eric Christopher71520a82011-07-11 23:06:52 +0000762 Init *Result = ForeachHelper(LHS, Arg, RHSo, Type,
763 CurRec, CurMultiClass);
David Greenee917fff2009-05-14 22:23:47 +0000764 if (Result != 0) {
765 return Result;
Bob Wilson7248f862009-11-22 04:24:42 +0000766 } else {
David Greenee917fff2009-05-14 22:23:47 +0000767 return 0;
768 }
769 }
770
771 for (int i = 0; i < RHSo->getNumOperands(); ++i) {
Eric Christopher71520a82011-07-11 23:06:52 +0000772 OpInit *RHSoo = dynamic_cast<OpInit*>(RHSo->getOperand(i));
David Greenee917fff2009-05-14 22:23:47 +0000773
774 if (RHSoo) {
Eric Christopher71520a82011-07-11 23:06:52 +0000775 Init *Result = EvaluateOperation(RHSoo, LHS, Arg,
776 Type, CurRec, CurMultiClass);
David Greenee917fff2009-05-14 22:23:47 +0000777 if (Result != 0) {
778 NewOperands.push_back(Result);
Bob Wilson7248f862009-11-22 04:24:42 +0000779 } else {
David Greenee917fff2009-05-14 22:23:47 +0000780 NewOperands.push_back(Arg);
781 }
Bob Wilson7248f862009-11-22 04:24:42 +0000782 } else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
David Greenee917fff2009-05-14 22:23:47 +0000783 NewOperands.push_back(Arg);
Bob Wilson7248f862009-11-22 04:24:42 +0000784 } else {
David Greenee917fff2009-05-14 22:23:47 +0000785 NewOperands.push_back(RHSo->getOperand(i));
786 }
787 }
788
789 // Now run the operator and use its result as the new leaf
Eric Christopher71520a82011-07-11 23:06:52 +0000790 OpInit *NewOp = RHSo->clone(NewOperands);
791 Init *NewVal = NewOp->Fold(CurRec, CurMultiClass);
792 if (NewVal != NewOp) {
793 delete NewOp;
David Greenee917fff2009-05-14 22:23:47 +0000794 return NewVal;
795 }
796 return 0;
797}
798
Eric Christopher71520a82011-07-11 23:06:52 +0000799static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
800 Record *CurRec, MultiClass *CurMultiClass) {
801 DagInit *MHSd = dynamic_cast<DagInit*>(MHS);
802 ListInit *MHSl = dynamic_cast<ListInit*>(MHS);
David Greenee917fff2009-05-14 22:23:47 +0000803
804 DagRecTy *DagType = dynamic_cast<DagRecTy*>(Type);
805 ListRecTy *ListType = dynamic_cast<ListRecTy*>(Type);
806
Eric Christopher71520a82011-07-11 23:06:52 +0000807 OpInit *RHSo = dynamic_cast<OpInit*>(RHS);
David Greenee917fff2009-05-14 22:23:47 +0000808
809 if (!RHSo) {
Jim Grosbach59ddb732011-05-06 18:47:45 +0000810 throw TGError(CurRec->getLoc(), "!foreach requires an operator\n");
David Greenee917fff2009-05-14 22:23:47 +0000811 }
812
Eric Christopher71520a82011-07-11 23:06:52 +0000813 TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
David Greenee917fff2009-05-14 22:23:47 +0000814
815 if (!LHSt) {
Jim Grosbach59ddb732011-05-06 18:47:45 +0000816 throw TGError(CurRec->getLoc(), "!foreach requires typed variable\n");
David Greenee917fff2009-05-14 22:23:47 +0000817 }
818
Nick Lewycky94298222009-05-15 03:07:14 +0000819 if ((MHSd && DagType) || (MHSl && ListType)) {
David Greenee917fff2009-05-14 22:23:47 +0000820 if (MHSd) {
Eric Christopher71520a82011-07-11 23:06:52 +0000821 Init *Val = MHSd->getOperator();
822 Init *Result = EvaluateOperation(RHSo, LHS, Val,
823 Type, CurRec, CurMultiClass);
David Greenee917fff2009-05-14 22:23:47 +0000824 if (Result != 0) {
825 Val = Result;
826 }
827
Eric Christopher71520a82011-07-11 23:06:52 +0000828 std::vector<std::pair<Init *, std::string> > args;
David Greenee917fff2009-05-14 22:23:47 +0000829 for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
Eric Christopher71520a82011-07-11 23:06:52 +0000830 Init *Arg;
David Greenee917fff2009-05-14 22:23:47 +0000831 std::string ArgName;
832 Arg = MHSd->getArg(i);
833 ArgName = MHSd->getArgName(i);
834
835 // Process args
Eric Christopher71520a82011-07-11 23:06:52 +0000836 Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type,
837 CurRec, CurMultiClass);
David Greenee917fff2009-05-14 22:23:47 +0000838 if (Result != 0) {
839 Arg = Result;
840 }
841
842 // TODO: Process arg names
843 args.push_back(std::make_pair(Arg, ArgName));
844 }
845
Eric Christopher71520a82011-07-11 23:06:52 +0000846 return new DagInit(Val, "", args);
David Greenee917fff2009-05-14 22:23:47 +0000847 }
848 if (MHSl) {
Eric Christopher71520a82011-07-11 23:06:52 +0000849 std::vector<Init *> NewOperands;
850 std::vector<Init *> NewList(MHSl->begin(), MHSl->end());
David Greenee917fff2009-05-14 22:23:47 +0000851
Eric Christopher71520a82011-07-11 23:06:52 +0000852 for (ListInit::iterator li = NewList.begin(),
David Greenee917fff2009-05-14 22:23:47 +0000853 liend = NewList.end();
854 li != liend;
855 ++li) {
Eric Christopher71520a82011-07-11 23:06:52 +0000856 Init *Item = *li;
David Greenee917fff2009-05-14 22:23:47 +0000857 NewOperands.clear();
858 for(int i = 0; i < RHSo->getNumOperands(); ++i) {
859 // First, replace the foreach variable with the list item
860 if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
861 NewOperands.push_back(Item);
Bob Wilson7248f862009-11-22 04:24:42 +0000862 } else {
David Greenee917fff2009-05-14 22:23:47 +0000863 NewOperands.push_back(RHSo->getOperand(i));
864 }
865 }
866
867 // Now run the operator and use its result as the new list item
Eric Christopher71520a82011-07-11 23:06:52 +0000868 OpInit *NewOp = RHSo->clone(NewOperands);
869 Init *NewItem = NewOp->Fold(CurRec, CurMultiClass);
David Greenee917fff2009-05-14 22:23:47 +0000870 if (NewItem != NewOp) {
871 *li = NewItem;
Eric Christopher71520a82011-07-11 23:06:52 +0000872 delete NewOp;
David Greenee917fff2009-05-14 22:23:47 +0000873 }
874 }
Eric Christopher71520a82011-07-11 23:06:52 +0000875 return new ListInit(NewList, MHSl->getType());
David Greenee917fff2009-05-14 22:23:47 +0000876 }
877 }
878 return 0;
879}
880
Eric Christopher71520a82011-07-11 23:06:52 +0000881Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
David Greene98ed3c72009-05-14 21:54:42 +0000882 switch (getOpcode()) {
883 default: assert(0 && "Unknown binop");
884 case SUBST: {
Eric Christopher71520a82011-07-11 23:06:52 +0000885 DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
886 VarInit *LHSv = dynamic_cast<VarInit*>(LHS);
887 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
David Greene196ac3c2009-04-23 21:25:15 +0000888
Eric Christopher71520a82011-07-11 23:06:52 +0000889 DefInit *MHSd = dynamic_cast<DefInit*>(MHS);
890 VarInit *MHSv = dynamic_cast<VarInit*>(MHS);
891 StringInit *MHSs = dynamic_cast<StringInit*>(MHS);
David Greene5d0c0512009-05-14 20:54:48 +0000892
Eric Christopher71520a82011-07-11 23:06:52 +0000893 DefInit *RHSd = dynamic_cast<DefInit*>(RHS);
894 VarInit *RHSv = dynamic_cast<VarInit*>(RHS);
895 StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
David Greene5d0c0512009-05-14 20:54:48 +0000896
David Greene98ed3c72009-05-14 21:54:42 +0000897 if ((LHSd && MHSd && RHSd)
898 || (LHSv && MHSv && RHSv)
899 || (LHSs && MHSs && RHSs)) {
900 if (RHSd) {
901 Record *Val = RHSd->getDef();
902 if (LHSd->getAsString() == RHSd->getAsString()) {
903 Val = MHSd->getDef();
904 }
Eric Christopher71520a82011-07-11 23:06:52 +0000905 return new DefInit(Val);
David Greene98ed3c72009-05-14 21:54:42 +0000906 }
907 if (RHSv) {
908 std::string Val = RHSv->getName();
909 if (LHSv->getAsString() == RHSv->getAsString()) {
910 Val = MHSv->getName();
911 }
Eric Christopher71520a82011-07-11 23:06:52 +0000912 return new VarInit(Val, getType());
David Greene98ed3c72009-05-14 21:54:42 +0000913 }
914 if (RHSs) {
915 std::string Val = RHSs->getValue();
David Greene5d0c0512009-05-14 20:54:48 +0000916
David Greene98ed3c72009-05-14 21:54:42 +0000917 std::string::size_type found;
David Greenedbf70742009-12-21 21:21:34 +0000918 std::string::size_type idx = 0;
David Greene98ed3c72009-05-14 21:54:42 +0000919 do {
David Greenedbf70742009-12-21 21:21:34 +0000920 found = Val.find(LHSs->getValue(), idx);
David Greene98ed3c72009-05-14 21:54:42 +0000921 if (found != std::string::npos) {
922 Val.replace(found, LHSs->getValue().size(), MHSs->getValue());
923 }
David Greenedbf70742009-12-21 21:21:34 +0000924 idx = found + MHSs->getValue().size();
David Greene98ed3c72009-05-14 21:54:42 +0000925 } while (found != std::string::npos);
David Greene5d0c0512009-05-14 20:54:48 +0000926
Eric Christopher71520a82011-07-11 23:06:52 +0000927 return new StringInit(Val);
David Greene98ed3c72009-05-14 21:54:42 +0000928 }
929 }
930 break;
Bob Wilson7248f862009-11-22 04:24:42 +0000931 }
David Greene5d0c0512009-05-14 20:54:48 +0000932
David Greene98ed3c72009-05-14 21:54:42 +0000933 case FOREACH: {
Eric Christopher71520a82011-07-11 23:06:52 +0000934 Init *Result = ForeachHelper(LHS, MHS, RHS, getType(),
David Greenee917fff2009-05-14 22:23:47 +0000935 CurRec, CurMultiClass);
936 if (Result != 0) {
937 return Result;
David Greene98ed3c72009-05-14 21:54:42 +0000938 }
939 break;
940 }
David Greene3587eed2009-05-14 23:26:46 +0000941
942 case IF: {
Eric Christopher71520a82011-07-11 23:06:52 +0000943 IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
944 if (Init *I = LHS->convertInitializerTo(new IntRecTy()))
945 LHSi = dynamic_cast<IntInit*>(I);
David Greene3587eed2009-05-14 23:26:46 +0000946 if (LHSi) {
947 if (LHSi->getValue()) {
948 return MHS;
Bob Wilson7248f862009-11-22 04:24:42 +0000949 } else {
David Greene3587eed2009-05-14 23:26:46 +0000950 return RHS;
951 }
952 }
953 break;
954 }
David Greene98ed3c72009-05-14 21:54:42 +0000955 }
David Greene5d0c0512009-05-14 20:54:48 +0000956
David Greene98ed3c72009-05-14 21:54:42 +0000957 return this;
958}
David Greene5d0c0512009-05-14 20:54:48 +0000959
Eric Christopher71520a82011-07-11 23:06:52 +0000960Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
961 Init *lhs = LHS->resolveReferences(R, RV);
David Greeneb0354452009-06-08 19:16:56 +0000962
963 if (Opc == IF && lhs != LHS) {
Eric Christopher71520a82011-07-11 23:06:52 +0000964 IntInit *Value = dynamic_cast<IntInit*>(lhs);
965 if (Init *I = lhs->convertInitializerTo(new IntRecTy()))
966 Value = dynamic_cast<IntInit*>(I);
David Greeneb0354452009-06-08 19:16:56 +0000967 if (Value != 0) {
968 // Short-circuit
969 if (Value->getValue()) {
Eric Christopher71520a82011-07-11 23:06:52 +0000970 Init *mhs = MHS->resolveReferences(R, RV);
971 return (new TernOpInit(getOpcode(), lhs, mhs,
972 RHS, getType()))->Fold(&R, 0);
Bob Wilson7248f862009-11-22 04:24:42 +0000973 } else {
Eric Christopher71520a82011-07-11 23:06:52 +0000974 Init *rhs = RHS->resolveReferences(R, RV);
975 return (new TernOpInit(getOpcode(), lhs, MHS,
976 rhs, getType()))->Fold(&R, 0);
David Greeneb0354452009-06-08 19:16:56 +0000977 }
978 }
979 }
Bob Wilson7248f862009-11-22 04:24:42 +0000980
Eric Christopher71520a82011-07-11 23:06:52 +0000981 Init *mhs = MHS->resolveReferences(R, RV);
982 Init *rhs = RHS->resolveReferences(R, RV);
David Greeneb0354452009-06-08 19:16:56 +0000983
David Greene98ed3c72009-05-14 21:54:42 +0000984 if (LHS != lhs || MHS != mhs || RHS != rhs)
Eric Christopher71520a82011-07-11 23:06:52 +0000985 return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0);
David Greene98ed3c72009-05-14 21:54:42 +0000986 return Fold(&R, 0);
987}
David Greene196ac3c2009-04-23 21:25:15 +0000988
David Greene98ed3c72009-05-14 21:54:42 +0000989std::string TernOpInit::getAsString() const {
990 std::string Result;
991 switch (Opc) {
992 case SUBST: Result = "!subst"; break;
Bob Wilson7248f862009-11-22 04:24:42 +0000993 case FOREACH: Result = "!foreach"; break;
994 case IF: Result = "!if"; break;
David Greene98ed3c72009-05-14 21:54:42 +0000995 }
Bob Wilson7248f862009-11-22 04:24:42 +0000996 return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
David Greene98ed3c72009-05-14 21:54:42 +0000997 + RHS->getAsString() + ")";
998}
David Greene196ac3c2009-04-23 21:25:15 +0000999
David Greene2a9de4d2010-09-03 21:00:49 +00001000RecTy *TypedInit::getFieldType(const std::string &FieldName) const {
1001 RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType());
1002 if (RecordType) {
1003 RecordVal *Field = RecordType->getRecord()->getValue(FieldName);
1004 if (Field) {
1005 return Field->getType();
1006 }
1007 }
1008 return 0;
1009}
1010
Eric Christopher71520a82011-07-11 23:06:52 +00001011Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001012 BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
Bill Wendling73a48d82010-12-10 22:54:30 +00001013 if (T == 0) return 0; // Cannot subscript a non-bits variable.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001014 unsigned NumBits = T->getNumBits();
1015
Eric Christopher71520a82011-07-11 23:06:52 +00001016 BitsInit *BI = new BitsInit(Bits.size());
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001017 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
1018 if (Bits[i] >= NumBits) {
Eric Christopher71520a82011-07-11 23:06:52 +00001019 delete BI;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001020 return 0;
1021 }
Eric Christopher71520a82011-07-11 23:06:52 +00001022 BI->setBit(i, new VarBitInit(this, Bits[i]));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001023 }
Eric Christopher71520a82011-07-11 23:06:52 +00001024 return BI;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001025}
1026
Eric Christopher71520a82011-07-11 23:06:52 +00001027Init *TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
Chris Lattner577fc3f2004-07-27 01:01:21 +00001028 ListRecTy *T = dynamic_cast<ListRecTy*>(getType());
Bill Wendling73a48d82010-12-10 22:54:30 +00001029 if (T == 0) return 0; // Cannot subscript a non-list variable.
Chris Lattner577fc3f2004-07-27 01:01:21 +00001030
1031 if (Elements.size() == 1)
Eric Christopher71520a82011-07-11 23:06:52 +00001032 return new VarListElementInit(this, Elements[0]);
Chris Lattner577fc3f2004-07-27 01:01:21 +00001033
Eric Christopher71520a82011-07-11 23:06:52 +00001034 std::vector<Init*> ListInits;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001035 ListInits.reserve(Elements.size());
1036 for (unsigned i = 0, e = Elements.size(); i != e; ++i)
Eric Christopher71520a82011-07-11 23:06:52 +00001037 ListInits.push_back(new VarListElementInit(this, Elements[i]));
1038 return new ListInit(ListInits, T);
Chris Lattner577fc3f2004-07-27 01:01:21 +00001039}
1040
1041
Eric Christopher71520a82011-07-11 23:06:52 +00001042Init *VarInit::resolveBitReference(Record &R, const RecordVal *IRV,
1043 unsigned Bit) {
Chris Lattneref943742005-04-19 03:36:21 +00001044 if (R.isTemplateArg(getName())) return 0;
1045 if (IRV && IRV->getName() != getName()) return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001046
1047 RecordVal *RV = R.getValue(getName());
Bob Wilson159905a2009-11-21 22:44:20 +00001048 assert(RV && "Reference to a non-existent variable?");
Eric Christopher71520a82011-07-11 23:06:52 +00001049 assert(dynamic_cast<BitsInit*>(RV->getValue()));
1050 BitsInit *BI = (BitsInit*)RV->getValue();
Misha Brukman650ba8e2005-04-22 00:00:37 +00001051
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001052 assert(Bit < BI->getNumBits() && "Bit reference out of range!");
Eric Christopher71520a82011-07-11 23:06:52 +00001053 Init *B = BI->getBit(Bit);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001054
Bob Wilson67e6cab2009-11-22 03:58:57 +00001055 // If the bit is set to some value, or if we are resolving a reference to a
1056 // specific variable and that variable is explicitly unset, then replace the
1057 // VarBitInit with it.
Eric Christopher71520a82011-07-11 23:06:52 +00001058 if (IRV || !dynamic_cast<UnsetInit*>(B))
Bob Wilson67e6cab2009-11-22 03:58:57 +00001059 return B;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001060 return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001061}
1062
Eric Christopher71520a82011-07-11 23:06:52 +00001063Init *VarInit::resolveListElementReference(Record &R, const RecordVal *IRV,
1064 unsigned Elt) {
Chris Lattneref943742005-04-19 03:36:21 +00001065 if (R.isTemplateArg(getName())) return 0;
1066 if (IRV && IRV->getName() != getName()) return 0;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001067
1068 RecordVal *RV = R.getValue(getName());
Bob Wilson159905a2009-11-21 22:44:20 +00001069 assert(RV && "Reference to a non-existent variable?");
Eric Christopher71520a82011-07-11 23:06:52 +00001070 ListInit *LI = dynamic_cast<ListInit*>(RV->getValue());
David Greene9d3febe2009-05-14 20:38:52 +00001071 if (!LI) {
Eric Christopher71520a82011-07-11 23:06:52 +00001072 VarInit *VI = dynamic_cast<VarInit*>(RV->getValue());
David Greene9d3febe2009-05-14 20:38:52 +00001073 assert(VI && "Invalid list element!");
Eric Christopher71520a82011-07-11 23:06:52 +00001074 return new VarListElementInit(VI, Elt);
David Greene9d3febe2009-05-14 20:38:52 +00001075 }
Bob Wilson7248f862009-11-22 04:24:42 +00001076
Chris Lattner577fc3f2004-07-27 01:01:21 +00001077 if (Elt >= LI->getSize())
1078 return 0; // Out of range reference.
Eric Christopher71520a82011-07-11 23:06:52 +00001079 Init *E = LI->getElement(Elt);
Bob Wilson67e6cab2009-11-22 03:58:57 +00001080 // If the element is set to some value, or if we are resolving a reference
1081 // to a specific variable and that variable is explicitly unset, then
1082 // replace the VarListElementInit with it.
Eric Christopher71520a82011-07-11 23:06:52 +00001083 if (IRV || !dynamic_cast<UnsetInit*>(E))
Bob Wilson67e6cab2009-11-22 03:58:57 +00001084 return E;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001085 return 0;
1086}
1087
1088
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001089RecTy *VarInit::getFieldType(const std::string &FieldName) const {
1090 if (RecordRecTy *RTy = dynamic_cast<RecordRecTy*>(getType()))
1091 if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
1092 return RV->getType();
1093 return 0;
1094}
1095
Eric Christopher71520a82011-07-11 23:06:52 +00001096Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
1097 const std::string &FieldName) const {
Reid Spencer2a826862006-11-02 20:46:16 +00001098 if (dynamic_cast<RecordRecTy*>(getType()))
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001099 if (const RecordVal *Val = R.getValue(VarName)) {
Eric Christopher71520a82011-07-11 23:06:52 +00001100 if (RV != Val && (RV || dynamic_cast<UnsetInit*>(Val->getValue())))
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001101 return 0;
Eric Christopher71520a82011-07-11 23:06:52 +00001102 Init *TheInit = Val->getValue();
Chris Lattnerd959ab92004-02-28 16:31:53 +00001103 assert(TheInit != this && "Infinite loop detected!");
Eric Christopher71520a82011-07-11 23:06:52 +00001104 if (Init *I = TheInit->getFieldInit(R, RV, FieldName))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001105 return I;
1106 else
1107 return 0;
Chris Lattnerd959ab92004-02-28 16:31:53 +00001108 }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001109 return 0;
1110}
1111
1112/// resolveReferences - This method is used by classes that refer to other
Bob Wilson159905a2009-11-21 22:44:20 +00001113/// variables which may not be defined at the time the expression is formed.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001114/// If a value is set for the variable later, this method will be called on
1115/// users of the value to allow the value to propagate out.
1116///
Eric Christopher71520a82011-07-11 23:06:52 +00001117Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001118 if (RecordVal *Val = R.getValue(VarName))
Eric Christopher71520a82011-07-11 23:06:52 +00001119 if (RV == Val || (RV == 0 && !dynamic_cast<UnsetInit*>(Val->getValue())))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001120 return Val->getValue();
1121 return this;
1122}
Misha Brukman650ba8e2005-04-22 00:00:37 +00001123
Chris Lattner695506c2007-11-22 21:05:25 +00001124std::string VarBitInit::getAsString() const {
1125 return TI->getAsString() + "{" + utostr(Bit) + "}";
1126}
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001127
Eric Christopher71520a82011-07-11 23:06:52 +00001128Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) {
1129 if (Init *I = getVariable()->resolveBitReference(R, RV, getBitNum()))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001130 return I;
1131 return this;
1132}
1133
Chris Lattner695506c2007-11-22 21:05:25 +00001134std::string VarListElementInit::getAsString() const {
1135 return TI->getAsString() + "[" + utostr(Element) + "]";
1136}
1137
Eric Christopher71520a82011-07-11 23:06:52 +00001138Init *VarListElementInit::resolveReferences(Record &R, const RecordVal *RV) {
1139 if (Init *I = getVariable()->resolveListElementReference(R, RV,
1140 getElementNum()))
Chris Lattner577fc3f2004-07-27 01:01:21 +00001141 return I;
1142 return this;
1143}
1144
Eric Christopher71520a82011-07-11 23:06:52 +00001145Init *VarListElementInit::resolveBitReference(Record &R, const RecordVal *RV,
1146 unsigned Bit) {
Chris Lattner577fc3f2004-07-27 01:01:21 +00001147 // FIXME: This should be implemented, to support references like:
1148 // bit B = AA[0]{1};
1149 return 0;
1150}
1151
Eric Christopher71520a82011-07-11 23:06:52 +00001152Init *VarListElementInit::
1153resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) {
Chris Lattner577fc3f2004-07-27 01:01:21 +00001154 // FIXME: This should be implemented, to support references like:
1155 // int B = AA[0][1];
1156 return 0;
1157}
1158
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001159RecTy *DefInit::getFieldType(const std::string &FieldName) const {
1160 if (const RecordVal *RV = Def->getValue(FieldName))
1161 return RV->getType();
1162 return 0;
1163}
1164
Eric Christopher71520a82011-07-11 23:06:52 +00001165Init *DefInit::getFieldInit(Record &R, const RecordVal *RV,
1166 const std::string &FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001167 return Def->getValue(FieldName)->getValue();
1168}
1169
1170
Chris Lattner695506c2007-11-22 21:05:25 +00001171std::string DefInit::getAsString() const {
1172 return Def->getName();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001173}
1174
Eric Christopher71520a82011-07-11 23:06:52 +00001175Init *FieldInit::resolveBitReference(Record &R, const RecordVal *RV,
1176 unsigned Bit) {
1177 if (Init *BitsVal = Rec->getFieldInit(R, RV, FieldName))
1178 if (BitsInit *BI = dynamic_cast<BitsInit*>(BitsVal)) {
David Greeneaf973b42011-07-11 18:25:51 +00001179 assert(Bit < BI->getNumBits() && "Bit reference out of range!");
Eric Christopher71520a82011-07-11 23:06:52 +00001180 Init *B = BI->getBit(Bit);
David Greeneaf973b42011-07-11 18:25:51 +00001181
Eric Christopher71520a82011-07-11 23:06:52 +00001182 if (dynamic_cast<BitInit*>(B)) // If the bit is set.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001183 return B; // Replace the VarBitInit with it.
1184 }
Chris Lattner577fc3f2004-07-27 01:01:21 +00001185 return 0;
1186}
1187
Eric Christopher71520a82011-07-11 23:06:52 +00001188Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
1189 unsigned Elt) {
1190 if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName))
1191 if (ListInit *LI = dynamic_cast<ListInit*>(ListVal)) {
Chris Lattner577fc3f2004-07-27 01:01:21 +00001192 if (Elt >= LI->getSize()) return 0;
Eric Christopher71520a82011-07-11 23:06:52 +00001193 Init *E = LI->getElement(Elt);
Chris Lattner577fc3f2004-07-27 01:01:21 +00001194
Bob Wilson67e6cab2009-11-22 03:58:57 +00001195 // If the element is set to some value, or if we are resolving a
1196 // reference to a specific variable and that variable is explicitly
1197 // unset, then replace the VarListElementInit with it.
Eric Christopher71520a82011-07-11 23:06:52 +00001198 if (RV || !dynamic_cast<UnsetInit*>(E))
Bob Wilson67e6cab2009-11-22 03:58:57 +00001199 return E;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001200 }
1201 return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001202}
1203
Eric Christopher71520a82011-07-11 23:06:52 +00001204Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) {
1205 Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec;
Chris Lattneref943742005-04-19 03:36:21 +00001206
Eric Christopher71520a82011-07-11 23:06:52 +00001207 Init *BitsVal = NewRec->getFieldInit(R, RV, FieldName);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001208 if (BitsVal) {
Eric Christopher71520a82011-07-11 23:06:52 +00001209 Init *BVR = BitsVal->resolveReferences(R, RV);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001210 return BVR->isComplete() ? BVR : this;
1211 }
Chris Lattneref943742005-04-19 03:36:21 +00001212
1213 if (NewRec != Rec) {
Eric Christopher71520a82011-07-11 23:06:52 +00001214 return new FieldInit(NewRec, FieldName);
Chris Lattneref943742005-04-19 03:36:21 +00001215 }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001216 return this;
1217}
1218
Eric Christopher71520a82011-07-11 23:06:52 +00001219Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) {
1220 std::vector<Init*> NewArgs;
Chris Lattner0d3ef402006-01-31 06:02:35 +00001221 for (unsigned i = 0, e = Args.size(); i != e; ++i)
1222 NewArgs.push_back(Args[i]->resolveReferences(R, RV));
Bob Wilson7248f862009-11-22 04:24:42 +00001223
Eric Christopher71520a82011-07-11 23:06:52 +00001224 Init *Op = Val->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +00001225
Chris Lattnerb59cf3c2006-03-30 22:50:40 +00001226 if (Args != NewArgs || Op != Val)
Eric Christopher71520a82011-07-11 23:06:52 +00001227 return new DagInit(Op, ValName, NewArgs, ArgNames);
Bob Wilson7248f862009-11-22 04:24:42 +00001228
Chris Lattner0d3ef402006-01-31 06:02:35 +00001229 return this;
1230}
1231
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001232
Chris Lattner695506c2007-11-22 21:05:25 +00001233std::string DagInit::getAsString() const {
1234 std::string Result = "(" + Val->getAsString();
Nate Begemandbe3f772009-03-19 05:21:56 +00001235 if (!ValName.empty())
1236 Result += ":" + ValName;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001237 if (Args.size()) {
Chris Lattner695506c2007-11-22 21:05:25 +00001238 Result += " " + Args[0]->getAsString();
1239 if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0];
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001240 for (unsigned i = 1, e = Args.size(); i != e; ++i) {
Chris Lattner695506c2007-11-22 21:05:25 +00001241 Result += ", " + Args[i]->getAsString();
1242 if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i];
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001243 }
1244 }
Chris Lattner695506c2007-11-22 21:05:25 +00001245 return Result + ")";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001246}
1247
1248
1249//===----------------------------------------------------------------------===//
1250// Other implementations
1251//===----------------------------------------------------------------------===//
1252
1253RecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P)
1254 : Name(N), Ty(T), Prefix(P) {
Eric Christopher71520a82011-07-11 23:06:52 +00001255 Value = Ty->convertValue(new UnsetInit());
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001256 assert(Value && "Cannot create unset value for current type!");
1257}
1258
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001259void RecordVal::dump() const { errs() << *this; }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001260
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001261void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001262 if (getPrefix()) OS << "field ";
1263 OS << *getType() << " " << getName();
Chris Lattneref943742005-04-19 03:36:21 +00001264
1265 if (getValue())
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001266 OS << " = " << *getValue();
Chris Lattneref943742005-04-19 03:36:21 +00001267
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001268 if (PrintSem) OS << ";\n";
1269}
1270
Daniel Dunbarced00812009-08-23 09:47:37 +00001271unsigned Record::LastID = 0;
1272
Chris Lattnerac284252005-08-19 17:58:11 +00001273void Record::setName(const std::string &Name) {
Chris Lattner77d369c2010-12-13 00:23:57 +00001274 if (TrackedRecords.getDef(getName()) == this) {
1275 TrackedRecords.removeDef(getName());
Chris Lattnerac284252005-08-19 17:58:11 +00001276 this->Name = Name;
Chris Lattner77d369c2010-12-13 00:23:57 +00001277 TrackedRecords.addDef(this);
Chris Lattnerac284252005-08-19 17:58:11 +00001278 } else {
Chris Lattner77d369c2010-12-13 00:23:57 +00001279 TrackedRecords.removeClass(getName());
Chris Lattnerac284252005-08-19 17:58:11 +00001280 this->Name = Name;
Chris Lattner77d369c2010-12-13 00:23:57 +00001281 TrackedRecords.addClass(this);
Chris Lattnerac284252005-08-19 17:58:11 +00001282 }
1283}
1284
Chris Lattneref943742005-04-19 03:36:21 +00001285/// resolveReferencesTo - If anything in this record refers to RV, replace the
1286/// reference to RV with the RHS of RV. If RV is null, we resolve all possible
1287/// references.
1288void Record::resolveReferencesTo(const RecordVal *RV) {
1289 for (unsigned i = 0, e = Values.size(); i != e; ++i) {
Eric Christopher71520a82011-07-11 23:06:52 +00001290 if (Init *V = Values[i].getValue())
Chris Lattneref943742005-04-19 03:36:21 +00001291 Values[i].setValue(V->resolveReferences(*this, RV));
1292 }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001293}
1294
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001295void Record::dump() const { errs() << *this; }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001296
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001297raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001298 OS << R.getName();
1299
1300 const std::vector<std::string> &TArgs = R.getTemplateArgs();
1301 if (!TArgs.empty()) {
1302 OS << "<";
1303 for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
1304 if (i) OS << ", ";
1305 const RecordVal *RV = R.getValue(TArgs[i]);
1306 assert(RV && "Template argument record not found??");
1307 RV->print(OS, false);
1308 }
1309 OS << ">";
1310 }
1311
1312 OS << " {";
1313 const std::vector<Record*> &SC = R.getSuperClasses();
1314 if (!SC.empty()) {
1315 OS << "\t//";
1316 for (unsigned i = 0, e = SC.size(); i != e; ++i)
1317 OS << " " << SC[i]->getName();
1318 }
1319 OS << "\n";
1320
1321 const std::vector<RecordVal> &Vals = R.getValues();
1322 for (unsigned i = 0, e = Vals.size(); i != e; ++i)
1323 if (Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
1324 OS << Vals[i];
1325 for (unsigned i = 0, e = Vals.size(); i != e; ++i)
1326 if (!Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
1327 OS << Vals[i];
1328
1329 return OS << "}\n";
1330}
1331
1332/// getValueInit - Return the initializer for a value with the specified name,
1333/// or throw an exception if the field does not exist.
1334///
Eric Christopher71520a82011-07-11 23:06:52 +00001335Init *Record::getValueInit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001336 const RecordVal *R = getValue(FieldName);
1337 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001338 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001339 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001340 return R->getValue();
1341}
1342
1343
1344/// getValueAsString - This method looks up the specified field and returns its
1345/// value as a string, throwing an exception if the field does not exist or if
1346/// the value is not a string.
1347///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001348std::string Record::getValueAsString(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001349 const RecordVal *R = getValue(FieldName);
1350 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001351 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001352 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001353
1354 if (const StringInit *SI = dynamic_cast<const StringInit*>(R->getValue()))
1355 return SI->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001356 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001357 "' does not have a string initializer!";
1358}
1359
1360/// getValueAsBitsInit - This method looks up the specified field and returns
1361/// its value as a BitsInit, throwing an exception if the field does not exist
1362/// or if the value is not the right type.
1363///
Eric Christopher71520a82011-07-11 23:06:52 +00001364BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001365 const RecordVal *R = getValue(FieldName);
1366 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001367 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001368 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001369
Eric Christopher71520a82011-07-11 23:06:52 +00001370 if (BitsInit *BI = dynamic_cast<BitsInit*>(R->getValue()))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001371 return BI;
Chris Lattner42bb0c12009-09-18 18:31:37 +00001372 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001373 "' does not have a BitsInit initializer!";
1374}
1375
1376/// getValueAsListInit - This method looks up the specified field and returns
1377/// its value as a ListInit, throwing an exception if the field does not exist
1378/// or if the value is not the right type.
1379///
Eric Christopher71520a82011-07-11 23:06:52 +00001380ListInit *Record::getValueAsListInit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001381 const RecordVal *R = getValue(FieldName);
1382 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001383 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001384 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001385
Eric Christopher71520a82011-07-11 23:06:52 +00001386 if (ListInit *LI = dynamic_cast<ListInit*>(R->getValue()))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001387 return LI;
Chris Lattner42bb0c12009-09-18 18:31:37 +00001388 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001389 "' does not have a list initializer!";
1390}
1391
Chris Lattner7ad0bed2005-10-28 22:49:02 +00001392/// getValueAsListOfDefs - This method looks up the specified field and returns
Jim Laskeyb04feb62005-10-28 21:46:31 +00001393/// its value as a vector of records, throwing an exception if the field does
1394/// not exist or if the value is not the right type.
1395///
Bob Wilson7248f862009-11-22 04:24:42 +00001396std::vector<Record*>
Chris Lattner42bb0c12009-09-18 18:31:37 +00001397Record::getValueAsListOfDefs(StringRef FieldName) const {
Eric Christopher71520a82011-07-11 23:06:52 +00001398 ListInit *List = getValueAsListInit(FieldName);
Jim Laskeyb04feb62005-10-28 21:46:31 +00001399 std::vector<Record*> Defs;
1400 for (unsigned i = 0; i < List->getSize(); i++) {
Eric Christopher71520a82011-07-11 23:06:52 +00001401 if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i))) {
Jim Laskeyb04feb62005-10-28 21:46:31 +00001402 Defs.push_back(DI->getDef());
1403 } else {
Chris Lattner42bb0c12009-09-18 18:31:37 +00001404 throw "Record `" + getName() + "', field `" + FieldName.str() +
Jim Laskeyb04feb62005-10-28 21:46:31 +00001405 "' list is not entirely DefInit!";
1406 }
1407 }
1408 return Defs;
1409}
1410
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001411/// getValueAsInt - This method looks up the specified field and returns its
Dan Gohmanca0546f2008-10-17 01:33:43 +00001412/// value as an int64_t, throwing an exception if the field does not exist or if
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001413/// the value is not the right type.
1414///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001415int64_t Record::getValueAsInt(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001416 const RecordVal *R = getValue(FieldName);
1417 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001418 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001419 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001420
Eric Christopher71520a82011-07-11 23:06:52 +00001421 if (IntInit *II = dynamic_cast<IntInit*>(R->getValue()))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001422 return II->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001423 throw "Record `" + getName() + "', field `" + FieldName.str() +
Nate Begemanf621b332005-11-30 18:37:14 +00001424 "' does not have an int initializer!";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001425}
1426
Anton Korobeynikova468a112007-11-11 11:19:37 +00001427/// getValueAsListOfInts - This method looks up the specified field and returns
1428/// its value as a vector of integers, throwing an exception if the field does
1429/// not exist or if the value is not the right type.
1430///
Bob Wilson7248f862009-11-22 04:24:42 +00001431std::vector<int64_t>
Chris Lattner42bb0c12009-09-18 18:31:37 +00001432Record::getValueAsListOfInts(StringRef FieldName) const {
Eric Christopher71520a82011-07-11 23:06:52 +00001433 ListInit *List = getValueAsListInit(FieldName);
Dan Gohmanca0546f2008-10-17 01:33:43 +00001434 std::vector<int64_t> Ints;
Anton Korobeynikova468a112007-11-11 11:19:37 +00001435 for (unsigned i = 0; i < List->getSize(); i++) {
Eric Christopher71520a82011-07-11 23:06:52 +00001436 if (IntInit *II = dynamic_cast<IntInit*>(List->getElement(i))) {
Anton Korobeynikova468a112007-11-11 11:19:37 +00001437 Ints.push_back(II->getValue());
1438 } else {
Chris Lattner42bb0c12009-09-18 18:31:37 +00001439 throw "Record `" + getName() + "', field `" + FieldName.str() +
Anton Korobeynikova468a112007-11-11 11:19:37 +00001440 "' does not have a list of ints initializer!";
1441 }
1442 }
1443 return Ints;
1444}
1445
Owen Andersona84be6c2011-06-27 21:06:21 +00001446/// getValueAsListOfStrings - This method looks up the specified field and
1447/// returns its value as a vector of strings, throwing an exception if the
1448/// field does not exist or if the value is not the right type.
1449///
1450std::vector<std::string>
1451Record::getValueAsListOfStrings(StringRef FieldName) const {
Eric Christopher71520a82011-07-11 23:06:52 +00001452 ListInit *List = getValueAsListInit(FieldName);
Owen Andersona84be6c2011-06-27 21:06:21 +00001453 std::vector<std::string> Strings;
1454 for (unsigned i = 0; i < List->getSize(); i++) {
Eric Christopher71520a82011-07-11 23:06:52 +00001455 if (StringInit *II = dynamic_cast<StringInit*>(List->getElement(i))) {
Owen Andersona84be6c2011-06-27 21:06:21 +00001456 Strings.push_back(II->getValue());
1457 } else {
1458 throw "Record `" + getName() + "', field `" + FieldName.str() +
1459 "' does not have a list of strings initializer!";
1460 }
1461 }
1462 return Strings;
1463}
1464
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001465/// getValueAsDef - This method looks up the specified field and returns its
1466/// value as a Record, throwing an exception if the field does not exist or if
1467/// the value is not the right type.
1468///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001469Record *Record::getValueAsDef(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001470 const RecordVal *R = getValue(FieldName);
1471 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001472 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001473 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001474
Eric Christopher71520a82011-07-11 23:06:52 +00001475 if (DefInit *DI = dynamic_cast<DefInit*>(R->getValue()))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001476 return DI->getDef();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001477 throw "Record `" + getName() + "', field `" + FieldName.str() +
Nate Begemanf621b332005-11-30 18:37:14 +00001478 "' does not have a def initializer!";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001479}
1480
1481/// getValueAsBit - This method looks up the specified field and returns its
1482/// value as a bit, throwing an exception if the field does not exist or if
1483/// the value is not the right type.
1484///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001485bool Record::getValueAsBit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001486 const RecordVal *R = getValue(FieldName);
1487 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001488 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001489 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001490
Eric Christopher71520a82011-07-11 23:06:52 +00001491 if (BitInit *BI = dynamic_cast<BitInit*>(R->getValue()))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001492 return BI->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001493 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001494 "' does not have a bit initializer!";
1495}
1496
1497/// getValueAsDag - This method looks up the specified field and returns its
1498/// value as an Dag, throwing an exception if the field does not exist or if
1499/// the value is not the right type.
1500///
Eric Christopher71520a82011-07-11 23:06:52 +00001501DagInit *Record::getValueAsDag(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001502 const RecordVal *R = getValue(FieldName);
1503 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001504 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001505 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001506
Eric Christopher71520a82011-07-11 23:06:52 +00001507 if (DagInit *DI = dynamic_cast<DagInit*>(R->getValue()))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001508 return DI;
Chris Lattner42bb0c12009-09-18 18:31:37 +00001509 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001510 "' does not have a dag initializer!";
1511}
1512
Chris Lattner42bb0c12009-09-18 18:31:37 +00001513std::string Record::getValueAsCode(StringRef FieldName) const {
Chris Lattnerae939eb2005-09-13 21:44:28 +00001514 const RecordVal *R = getValue(FieldName);
1515 if (R == 0 || R->getValue() == 0)
1516 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001517 FieldName.str() + "'!\n";
Bob Wilson7248f862009-11-22 04:24:42 +00001518
Chris Lattnerae939eb2005-09-13 21:44:28 +00001519 if (const CodeInit *CI = dynamic_cast<const CodeInit*>(R->getValue()))
1520 return CI->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001521 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerae939eb2005-09-13 21:44:28 +00001522 "' does not have a code initializer!";
1523}
1524
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001525
David Greene7049e792009-04-24 16:55:41 +00001526void MultiClass::dump() const {
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001527 errs() << "Record:\n";
David Greene7049e792009-04-24 16:55:41 +00001528 Rec.dump();
Bob Wilson7248f862009-11-22 04:24:42 +00001529
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001530 errs() << "Defs:\n";
David Greene7049e792009-04-24 16:55:41 +00001531 for (RecordVector::const_iterator r = DefPrototypes.begin(),
1532 rend = DefPrototypes.end();
1533 r != rend;
1534 ++r) {
1535 (*r)->dump();
1536 }
1537}
1538
1539
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001540void RecordKeeper::dump() const { errs() << *this; }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001541
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001542raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001543 OS << "------------- Classes -----------------\n";
1544 const std::map<std::string, Record*> &Classes = RK.getClasses();
1545 for (std::map<std::string, Record*>::const_iterator I = Classes.begin(),
Jeff Cohen88e7b722005-04-22 04:13:13 +00001546 E = Classes.end(); I != E; ++I)
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001547 OS << "class " << *I->second;
Misha Brukman650ba8e2005-04-22 00:00:37 +00001548
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001549 OS << "------------- Defs -----------------\n";
1550 const std::map<std::string, Record*> &Defs = RK.getDefs();
1551 for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
Jeff Cohen88e7b722005-04-22 04:13:13 +00001552 E = Defs.end(); I != E; ++I)
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001553 OS << "def " << *I->second;
1554 return OS;
1555}
1556
1557
1558/// getAllDerivedDefinitions - This method returns all concrete definitions
1559/// that derive from the specified class name. If a class with the specified
1560/// name does not exist, an error is printed and true is returned.
1561std::vector<Record*>
1562RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const {
Chris Lattner97049072010-12-13 00:20:52 +00001563 Record *Class = getClass(ClassName);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001564 if (!Class)
Misha Brukman41f9f292004-10-08 14:59:05 +00001565 throw "ERROR: Couldn't find the `" + ClassName + "' class!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001566
1567 std::vector<Record*> Defs;
1568 for (std::map<std::string, Record*>::const_iterator I = getDefs().begin(),
1569 E = getDefs().end(); I != E; ++I)
1570 if (I->second->isSubClassOf(Class))
1571 Defs.push_back(I->second);
1572
1573 return Defs;
1574}
Brian Gaeke960707c2003-11-11 22:41:34 +00001575