}
Init *BitRecTy::convertValue(IntInit *II) {
- int Val = II->getValue();
+ int64_t Val = II->getValue();
if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit!
return new BitInit(Val != 0);
}
Init *IntRecTy::convertValue(BitsInit *BI) {
- int Result = 0;
+ int64_t Result = 0;
for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
if (BitInit *Bit = dynamic_cast<BitInit*>(BI->getBit(i))) {
Result |= Bit->getValue() << i;
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 new BinOpInit(BinOpInit::STRCONCAT, L, R, new StringRecTy);
return BO;
}
- return 0;
+ if (BO->getOpcode() == BinOpInit::NAMECONCAT) {
+ if (BO->getType()->getAsString() == getAsString()) {
+ 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::NAMECONCAT, L, R, new StringRecTy);
+ return BO;
+ }
+ }
+
+ return convertValue((TypedInit*)BO);
}
Init *R = BO->getRHS()->convertInitializerTo(this);
if (L == 0 || R == 0) return 0;
if (L != BO->getLHS() || R != BO->getRHS())
- return new BinOpInit(BinOpInit::CONCAT, L, R);
+ return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
return BO;
}
+ if (BO->getOpcode() == BinOpInit::NAMECONCAT) {
+ if (BO->getType()->getAsString() == getAsString()) {
+ 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::CONCAT, L, R, new DagRecTy);
+ return BO;
+ }
+ }
return 0;
}
bool BitsInit::printInHex(std::ostream &OS) const {
// First, attempt to convert the value into an integer value...
- int Result = 0;
+ int64_t Result = 0;
for (unsigned i = 0, e = getNumBits(); i != e; ++i)
if (BitInit *Bit = dynamic_cast<BitInit*>(getBit(i))) {
Result |= Bit->getValue() << i;
BitsInit *BI = new BitsInit(Bits.size());
for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- if (Bits[i] >= 32) {
+ if (Bits[i] >= 64) {
delete BI;
return 0;
}
- BI->setBit(i, new BitInit(Value & (1 << Bits[i])));
+ BI->setBit(i, new BitInit(Value & (INT64_C(1) << Bits[i])));
}
return BI;
}
return Result + "]";
}
-Init *BinOpInit::Fold() {
+Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
switch (getOpcode()) {
default: assert(0 && "Unknown binop");
case CONCAT: {
Args.push_back(RHSs->getArg(i));
ArgNames.push_back(RHSs->getArgName(i));
}
- return new DagInit(LHSs->getOperator(), Args, ArgNames);
+ return new DagInit(LHSs->getOperator(), "", Args, ArgNames);
}
break;
}
return new StringInit(LHSs->getValue() + RHSs->getValue());
break;
}
+ case NAMECONCAT: {
+ StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+ StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
+ if (LHSs && RHSs) {
+ std::string Name(LHSs->getValue() + RHSs->getValue());
+
+ // From TGParser::ParseIDValue
+ if (CurRec) {
+ if (const RecordVal *RV = CurRec->getValue(Name)) {
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
+ return new VarInit(Name, RV->getType());
+ }
+
+ std::string TemplateArgName = CurRec->getName()+":"+Name;
+ if (CurRec->isTemplateArg(TemplateArgName)) {
+ const RecordVal *RV = CurRec->getValue(TemplateArgName);
+ assert(RV && "Template arg doesn't exist??");
+
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
+
+ return new VarInit(TemplateArgName, RV->getType());
+ }
+ }
+
+ if (CurMultiClass) {
+ std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
+ if (CurMultiClass->Rec.isTemplateArg(MCName)) {
+ const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
+ assert(RV && "Template arg doesn't exist??");
+
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
+
+ return new VarInit(MCName, RV->getType());
+ }
+ }
+
+ if (Record *D = Records.getDef(Name))
+ return new DefInit(D);
+
+ cerr << "Variable not defined: '" + Name + "'\n";
+ assert(0 && "Variable not found");
+ return 0;
+ }
+ 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;
+ int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
+ int64_t 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;
+ case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
}
return new IntInit(Result);
}
Init *rhs = RHS->resolveReferences(R, RV);
if (LHS != lhs || RHS != rhs)
- return (new BinOpInit(getOpcode(), lhs, rhs))->Fold();
- return Fold();
+ return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
+ return Fold(&R, 0);
}
std::string BinOpInit::getAsString() const {
case SRA: Result = "!sra"; break;
case SRL: Result = "!srl"; break;
case STRCONCAT: Result = "!strconcat"; break;
+ case NAMECONCAT:
+ Result = "!nameconcat<" + getType()->getAsString() + ">"; break;
}
return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
}
+Init *BinOpInit::resolveBitReference(Record &R, const RecordVal *IRV,
+ unsigned Bit) {
+ Init *Folded = Fold(&R, 0);
+
+ if (Folded != this) {
+ TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
+ if (Typed) {
+ return Typed->resolveBitReference(R, IRV, Bit);
+ }
+ }
+
+ return 0;
+}
+
+Init *BinOpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
+ unsigned Elt) {
+ Init *Folded = Fold(&R, 0);
+
+ if (Folded != this) {
+ TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
+ if (Typed) {
+ return Typed->resolveListElementReference(R, IRV, Elt);
+ }
+ }
+
+ return 0;
+}
+
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...
RecordVal *RV = R.getValue(getName());
assert(RV && "Reference to a non-existant variable?");
ListInit *LI = dynamic_cast<ListInit*>(RV->getValue());
- assert(LI && "Invalid list element!");
-
+ if (!LI) {
+ VarInit *VI = dynamic_cast<VarInit*>(RV->getValue());
+ assert(VI && "Invalid list element!");
+ return new VarListElementInit(VI, Elt);
+ }
+
if (Elt >= LI->getSize())
return 0; // Out of range reference.
Init *E = LI->getElement(Elt);
}
if (NewRec != Rec) {
- dump();
- NewRec->dump(); cerr << "\n";
return new FieldInit(NewRec, FieldName);
}
return this;
Init *Op = Val->resolveReferences(R, RV);
if (Args != NewArgs || Op != Val)
- return new DagInit(Op, NewArgs, ArgNames);
+ return new DagInit(Op, "", NewArgs, ArgNames);
return this;
}
std::string DagInit::getAsString() const {
std::string Result = "(" + Val->getAsString();
+ if (!ValName.empty())
+ Result += ":" + ValName;
if (Args.size()) {
Result += " " + Args[0]->getAsString();
if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0];
}
/// 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
+/// value as an int64_t, throwing an exception if the field does not exist or if
/// the value is not the right type.
///
-int Record::getValueAsInt(const std::string &FieldName) const {
+int64_t Record::getValueAsInt(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 `" +
/// its value as a vector of integers, throwing an exception if the field does
/// not exist or if the value is not the right type.
///
-std::vector<int>
+std::vector<int64_t>
Record::getValueAsListOfInts(const std::string &FieldName) const {
ListInit *List = getValueAsListInit(FieldName);
- std::vector<int> Ints;
+ std::vector<int64_t> Ints;
for (unsigned i = 0; i < List->getSize(); i++) {
if (IntInit *II = dynamic_cast<IntInit*>(List->getElement(i))) {
Ints.push_back(II->getValue());
}
+void MultiClass::dump() const {
+ cerr << "Record:\n";
+ Rec.dump();
+
+ cerr << "Defs:\n";
+ for (RecordVector::const_iterator r = DefPrototypes.begin(),
+ rend = DefPrototypes.end();
+ r != rend;
+ ++r) {
+ (*r)->dump();
+ }
+}
+
+
void RecordKeeper::dump() const { cerr << *this; }
std::ostream &llvm::operator<<(std::ostream &OS, const RecordKeeper &RK) {