//
//===----------------------------------------------------------------------===//
//
+// Implement the tablegen record classes.
//
//===----------------------------------------------------------------------===//
#include "Record.h"
#include "llvm/Support/DataTypes.h"
+#include <ios>
+
using namespace llvm;
//===----------------------------------------------------------------------===//
if (Value & ~((1LL << Size)-1))
return 0;
} else {
- if ((Value >> Size) != -1 || ((Value & (1 << (Size-1))) == 0))
+ if ((Value >> Size) != -1 || ((Value & (1LL << (Size-1))) == 0))
return 0;
}
BitsInit *Ret = new BitsInit(Size);
for (unsigned i = 0; i != Size; ++i)
- Ret->setBit(i, new BitInit(Value & (1 << i)));
+ Ret->setBit(i, new BitInit(Value & (1LL << i)));
return Ret;
}
if (BRT->Size == Size) {
BitsInit *Ret = new BitsInit(Size);
for (unsigned i = 0; i != Size; ++i)
- Ret->setBit(i, new VarBitInit(VI, i));
+ Ret->setBit(i, new VarBitInit(VI, i));
return Ret;
}
if (Size == 1 && dynamic_cast<BitRecTy*>(VI->getType())) {
return 0;
}
+Init *StringRecTy::convertValue(BinOpInit *BO) {
+ if (BO->getOpcode() == BinOpInit::STRCONCAT) {
+ Init *L = BO->getLHS()->convertInitializerTo(this);
+ Init *R = BO->getRHS()->convertInitializerTo(this);
+ if (L == 0 || R == 0) return 0;
+ if (L != BO->getLHS() || R != BO->getRHS())
+ return new BinOpInit(BinOpInit::STRCONCAT, L, R);
+ return BO;
+ }
+ return 0;
+}
+
+
Init *StringRecTy::convertValue(TypedInit *TI) {
if (dynamic_cast<StringRecTy*>(TI->getType()))
return TI; // Accept variable if already of the right type!
return this;
}
-Init *IntInit::getBinaryOp(BinaryOp Op, Init *RHS) {
- IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
- if (RHSi == 0) return 0;
-
- int NewValue;
- switch (Op) {
- default: assert(0 && "Unknown binop");
- case SHL: NewValue = Value << RHSi->getValue(); break;
- case SRA: NewValue = Value >> RHSi->getValue(); break;
- case SRL: NewValue = (unsigned)Value >> (unsigned)RHSi->getValue(); break;
- }
- return new IntInit(NewValue);
-}
-
-
Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
BitsInit *BI = new BitsInit(Bits.size());
OS << "]";
}
+Init *BinOpInit::Fold() {
+ switch (getOpcode()) {
+ default: assert(0 && "Unknown binop");
+ case STRCONCAT: {
+ StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+ StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
+ if (LHSs && RHSs)
+ return new StringInit(LHSs->getValue() + RHSs->getValue());
+ break;
+ }
+ case SHL:
+ case SRA:
+ case SRL: {
+ IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
+ IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
+ if (LHSi && RHSi) {
+ int LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
+ int Result;
+ switch (getOpcode()) {
+ default: assert(0 && "Bad opcode!");
+ case SHL: Result = LHSv << RHSv; break;
+ case SRA: Result = LHSv >> RHSv; break;
+ case SRL: Result = (unsigned)LHSv >> (unsigned)RHSv; break;
+ }
+ return new IntInit(Result);
+ }
+ break;
+ }
+ }
+ return this;
+}
+
+Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) {
+ Init *lhs = LHS->resolveReferences(R, RV);
+ Init *rhs = RHS->resolveReferences(R, RV);
+
+ if (LHS != lhs || RHS != rhs)
+ return (new BinOpInit(getOpcode(), lhs, rhs))->Fold();
+ return Fold();
+}
+
+void BinOpInit::print(std::ostream &OS) const {
+ switch (Opc) {
+ case SHL: OS << "!shl"; break;
+ case SRA: OS << "!sra"; break;
+ case SRL: OS << "!srl"; break;
+ case STRCONCAT: OS << "!strconcat"; break;
+ }
+ OS << "(";
+ LHS->print(OS);
+ OS << ", ";
+ RHS->print(OS);
+ OS << ")";
+}
+
Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
if (T == 0) return 0; // Cannot subscript a non-bits variable...
return this;
}
+Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) {
+ std::vector<Init*> NewArgs;
+ for (unsigned i = 0, e = Args.size(); i != e; ++i)
+ NewArgs.push_back(Args[i]->resolveReferences(R, RV));
+
+ Init *Op = Val->resolveReferences(R, RV);
+
+ if (Args != NewArgs || Op != Val)
+ return new DagInit(Op, NewArgs, ArgNames);
+
+ return this;
+}
+
void DagInit::print(std::ostream &OS) const {
- OS << "(" << NodeTypeDef->getName();
+ OS << "(" << *Val;
if (Args.size()) {
OS << " " << *Args[0];
if (!ArgNames[0].empty()) OS << ":$" << ArgNames[0];
if (PrintSem) OS << ";\n";
}
+void Record::setName(const std::string &Name) {
+ if (Records.getDef(getName()) == this) {
+ Records.removeDef(getName());
+ this->Name = Name;
+ Records.addDef(this);
+ } else {
+ Records.removeClass(getName());
+ this->Name = Name;
+ Records.addClass(this);
+ }
+}
+
/// resolveReferencesTo - If anything in this record refers to RV, replace the
/// reference to RV with the RHS of RV. If RV is null, we resolve all possible
/// references.
"' does not have a list initializer!";
}
+/// getValueAsListOfDefs - This method looks up the specified field and returns
+/// its value as a vector of records, throwing an exception if the field does
+/// not exist or if the value is not the right type.
+///
+std::vector<Record*>
+Record::getValueAsListOfDefs(const std::string &FieldName) const {
+ ListInit *List = getValueAsListInit(FieldName);
+ std::vector<Record*> Defs;
+ for (unsigned i = 0; i < List->getSize(); i++) {
+ if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i))) {
+ Defs.push_back(DI->getDef());
+ } else {
+ throw "Record `" + getName() + "', field `" + FieldName +
+ "' list is not entirely DefInit!";
+ }
+ }
+ return Defs;
+}
+
/// getValueAsInt - This method looks up the specified field and returns its
/// value as an int, throwing an exception if the field does not exist or if
/// the value is not the right type.
if (IntInit *II = dynamic_cast<IntInit*>(R->getValue()))
return II->getValue();
throw "Record `" + getName() + "', field `" + FieldName +
- "' does not have a list initializer!";
+ "' does not have an int initializer!";
}
/// getValueAsDef - This method looks up the specified field and returns its
if (DefInit *DI = dynamic_cast<DefInit*>(R->getValue()))
return DI->getDef();
throw "Record `" + getName() + "', field `" + FieldName +
- "' does not have a list initializer!";
+ "' does not have a def initializer!";
}
/// getValueAsBit - This method looks up the specified field and returns its
"' does not have a dag initializer!";
}
+std::string Record::getValueAsCode(const std::string &FieldName) const {
+ const RecordVal *R = getValue(FieldName);
+ if (R == 0 || R->getValue() == 0)
+ throw "Record `" + getName() + "' does not have a field named `" +
+ FieldName + "'!\n";
+
+ if (const CodeInit *CI = dynamic_cast<const CodeInit*>(R->getValue()))
+ return CI->getValue();
+ throw "Record `" + getName() + "', field `" + FieldName +
+ "' does not have a code initializer!";
+}
+
void RecordKeeper::dump() const { std::cerr << *this; }
OS << "------------- Classes -----------------\n";
const std::map<std::string, Record*> &Classes = RK.getClasses();
for (std::map<std::string, Record*>::const_iterator I = Classes.begin(),
- E = Classes.end(); I != E; ++I)
+ E = Classes.end(); I != E; ++I)
OS << "class " << *I->second;
OS << "------------- Defs -----------------\n";
const std::map<std::string, Record*> &Defs = RK.getDefs();
for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
- E = Defs.end(); I != E; ++I)
+ E = Defs.end(); I != E; ++I)
OS << "def " << *I->second;
return OS;
}