static std::string getNodeName(Record *R) { RecordVal *RV = R->getValue("EnumName"); if (RV) if (Init *I = RV->getValue()) if (StringInit *SI = dynamic_cast<StringInit*>(I)) return SI->getValue(); return R->getName(); }
void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val, IntInit *ShiftInt, raw_ostream &OS) { if (Val == 0 || ShiftInt == 0) throw std::string("Illegal value or shift amount in TargetInfo*!"); RecordVal *RV = R->getValue(Val->getValue()); int Shift = ShiftInt->getValue(); if (RV == 0 || RV->getValue() == 0) { // This isn't an error if this is a builtin instruction. if (R->getName() != "PHI" && R->getName() != "INLINEASM" && R->getName() != "DBG_LABEL" && R->getName() != "EH_LABEL" && R->getName() != "GC_LABEL" && R->getName() != "DECLARE" && R->getName() != "EXTRACT_SUBREG" && R->getName() != "INSERT_SUBREG" && R->getName() != "IMPLICIT_DEF" && R->getName() != "SUBREG_TO_REG" && R->getName() != "COPY_TO_REGCLASS") throw R->getName() + " doesn't have a field named '" + Val->getValue() + "'!"; return; } Init *Value = RV->getValue(); if (BitInit *BI = dynamic_cast<BitInit*>(Value)) { if (BI->getValue()) OS << "|(1<<" << Shift << ")"; return; } else if (BitsInit *BI = dynamic_cast<BitsInit*>(Value)) { // Convert the Bits to an integer to print... Init *I = BI->convertInitializerTo(new IntRecTy()); if (I) if (IntInit *II = dynamic_cast<IntInit*>(I)) { if (II->getValue()) { if (Shift) OS << "|(" << II->getValue() << "<<" << Shift << ")"; else OS << "|" << II->getValue(); } return; } } else if (IntInit *II = dynamic_cast<IntInit*>(Value)) { if (II->getValue()) { if (Shift) OS << "|(" << II->getValue() << "<<" << Shift << ")"; else OS << II->getValue(); } return; } errs() << "Unhandled initializer: " << *Val << "\n"; throw "In record '" + R->getName() + "' for TSFlag emission."; }
bool MapTableEmitter::isKeyColInstr(Record* CurInstr) { ListInit *ColFields = InstrMapDesc.getColFields(); ListInit *KeyCol = InstrMapDesc.getKeyCol(); // Check if the instruction is a KeyCol instruction. bool MatchFound = true; for (unsigned j = 0, endCF = ColFields->size(); (j < endCF) && MatchFound; j++) { RecordVal *ColFieldName = CurInstr->getValue(ColFields->getElement(j)); std::string CurInstrVal = ColFieldName->getValue()->getAsUnquotedString(); std::string KeyColValue = KeyCol->getElement(j)->getAsUnquotedString(); MatchFound = (CurInstrVal == KeyColValue); } return MatchFound; }
bool TGParser::AddValue(Record *CurRec, TGLoc Loc, const RecordVal &RV) { if (CurRec == 0) CurRec = &CurMultiClass->Rec; if (RecordVal *ERV = CurRec->getValue(RV.getName())) { // The value already exists in the class, treat this as a set. if (ERV->setValue(RV.getValue())) return Error(Loc, "New definition of '" + RV.getName() + "' of type '" + RV.getType()->getAsString() + "' is incompatible with " + "previous definition of type '" + ERV->getType()->getAsString() + "'"); } else { CurRec->addValue(RV); } return false; }
static bool populateInstruction(const CodeGenInstruction &CGI, unsigned Opc, std::map<unsigned, std::vector<OperandInfo> >& Operands){ const Record &Def = *CGI.TheDef; // If all the bit positions are not specified; do not decode this instruction. // We are bound to fail! For proper disassembly, the well-known encoding bits // of the instruction must be fully specified. // // This also removes pseudo instructions from considerations of disassembly, // which is a better design and less fragile than the name matchings. // Ignore "asm parser only" instructions. if (Def.getValueAsBit("isAsmParserOnly") || Def.getValueAsBit("isCodeGenOnly")) return false; BitsInit &Bits = getBitsField(Def, "Inst"); if (Bits.allInComplete()) return false; std::vector<OperandInfo> InsnOperands; // If the instruction has specified a custom decoding hook, use that instead // of trying to auto-generate the decoder. std::string InstDecoder = Def.getValueAsString("DecoderMethod"); if (InstDecoder != "") { InsnOperands.push_back(OperandInfo(InstDecoder)); Operands[Opc] = InsnOperands; return true; } // Generate a description of the operand of the instruction that we know // how to decode automatically. // FIXME: We'll need to have a way to manually override this as needed. // Gather the outputs/inputs of the instruction, so we can find their // positions in the encoding. This assumes for now that they appear in the // MCInst in the order that they're listed. std::vector<std::pair<Init*, std::string> > InOutOperands; DagInit *Out = Def.getValueAsDag("OutOperandList"); DagInit *In = Def.getValueAsDag("InOperandList"); for (unsigned i = 0; i < Out->getNumArgs(); ++i) InOutOperands.push_back(std::make_pair(Out->getArg(i), Out->getArgName(i))); for (unsigned i = 0; i < In->getNumArgs(); ++i) InOutOperands.push_back(std::make_pair(In->getArg(i), In->getArgName(i))); // Search for tied operands, so that we can correctly instantiate // operands that are not explicitly represented in the encoding. std::map<std::string, std::string> TiedNames; for (unsigned i = 0; i < CGI.Operands.size(); ++i) { int tiedTo = CGI.Operands[i].getTiedRegister(); if (tiedTo != -1) { TiedNames[InOutOperands[i].second] = InOutOperands[tiedTo].second; TiedNames[InOutOperands[tiedTo].second] = InOutOperands[i].second; } } // For each operand, see if we can figure out where it is encoded. for (std::vector<std::pair<Init*, std::string> >::iterator NI = InOutOperands.begin(), NE = InOutOperands.end(); NI != NE; ++NI) { std::string Decoder = ""; // At this point, we can locate the field, but we need to know how to // interpret it. As a first step, require the target to provide callbacks // for decoding register classes. // FIXME: This need to be extended to handle instructions with custom // decoder methods, and operands with (simple) MIOperandInfo's. TypedInit *TI = dynamic_cast<TypedInit*>(NI->first); RecordRecTy *Type = dynamic_cast<RecordRecTy*>(TI->getType()); Record *TypeRecord = Type->getRecord(); bool isReg = false; if (TypeRecord->isSubClassOf("RegisterOperand")) TypeRecord = TypeRecord->getValueAsDef("RegClass"); if (TypeRecord->isSubClassOf("RegisterClass")) { Decoder = "Decode" + TypeRecord->getName() + "RegisterClass"; isReg = true; } RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod"); StringInit *String = DecoderString ? dynamic_cast<StringInit*>(DecoderString->getValue()) : 0; if (!isReg && String && String->getValue() != "") Decoder = String->getValue(); OperandInfo OpInfo(Decoder); unsigned Base = ~0U; unsigned Width = 0; unsigned Offset = 0; for (unsigned bi = 0; bi < Bits.getNumBits(); ++bi) { VarInit *Var = 0; VarBitInit *BI = dynamic_cast<VarBitInit*>(Bits.getBit(bi)); if (BI) Var = dynamic_cast<VarInit*>(BI->getVariable()); else Var = dynamic_cast<VarInit*>(Bits.getBit(bi)); if (!Var) { if (Base != ~0U) { OpInfo.addField(Base, Width, Offset); Base = ~0U; Width = 0; Offset = 0; } continue; } if (Var->getName() != NI->second && Var->getName() != TiedNames[NI->second]) { if (Base != ~0U) { OpInfo.addField(Base, Width, Offset); Base = ~0U; Width = 0; Offset = 0; } continue; } if (Base == ~0U) { Base = bi; Width = 1; Offset = BI ? BI->getBitNum() : 0; } else if (BI && BI->getBitNum() != Offset + Width) { OpInfo.addField(Base, Width, Offset); Base = bi; Width = 1; Offset = BI->getBitNum(); } else { ++Width; } } if (Base != ~0U) OpInfo.addField(Base, Width, Offset); if (OpInfo.numFields() > 0) InsnOperands.push_back(OpInfo); } Operands[Opc] = InsnOperands; #if 0 DEBUG({ // Dumps the instruction encoding bits. dumpBits(errs(), Bits); errs() << '\n'; // Dumps the list of operand info. for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) { const CGIOperandList::OperandInfo &Info = CGI.Operands[i]; const std::string &OperandName = Info.Name; const Record &OperandDef = *Info.Rec; errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n"; } });
/// SetValue - /// Return true on error, false on success. bool TGParser::SetValue(Record *CurRec, TGLoc Loc, const std::string &ValName, const std::vector<unsigned> &BitList, Init *V) { if (!V) return false; if (CurRec == 0) CurRec = &CurMultiClass->Rec; RecordVal *RV = CurRec->getValue(ValName); if (RV == 0) return Error(Loc, "Value '" + ValName + "' unknown!"); // Do not allow assignments like 'X = X'. This will just cause infinite loops // in the resolution machinery. if (BitList.empty()) if (VarInit *VI = dynamic_cast<VarInit*>(V)) if (VI->getName() == ValName) return false; // If we are assigning to a subset of the bits in the value... then we must be // assigning to a field of BitsRecTy, which must have a BitsInit // initializer. // if (!BitList.empty()) { BitsInit *CurVal = dynamic_cast<BitsInit*>(RV->getValue()); if (CurVal == 0) return Error(Loc, "Value '" + ValName + "' is not a bits type"); // Convert the incoming value to a bits type of the appropriate size... Init *BI = V->convertInitializerTo(new BitsRecTy(BitList.size())); if (BI == 0) { V->convertInitializerTo(new BitsRecTy(BitList.size())); return Error(Loc, "Initializer is not compatible with bit range"); } // We should have a BitsInit type now. BitsInit *BInit = dynamic_cast<BitsInit*>(BI); assert(BInit != 0); BitsInit *NewVal = new BitsInit(CurVal->getNumBits()); // Loop over bits, assigning values as appropriate. for (unsigned i = 0, e = BitList.size(); i != e; ++i) { unsigned Bit = BitList[i]; if (NewVal->getBit(Bit)) return Error(Loc, "Cannot set bit #" + utostr(Bit) + " of value '" + ValName + "' more than once"); NewVal->setBit(Bit, BInit->getBit(i)); } for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) if (NewVal->getBit(i) == 0) NewVal->setBit(i, CurVal->getBit(i)); V = NewVal; } if (RV->setValue(V)) return Error(Loc, "Value '" + ValName + "' of type '" + RV->getType()->getAsString() + "' is incompatible with initializer '" + V->getAsString() +"'"); return false; }