void processRecord(raw_ostream& os, Record& rec, string arch) { if(!rec.getValue("GCCBuiltinName")) return; string builtinName = rec.getValueAsString("GCCBuiltinName"); string name = rec.getName(); if(name.substr(0, 4) != "int_" || name.find(arch) == string::npos) return; name = name.substr(4); replace(name.begin(), name.end(), '_', '.'); name = string("llvm.") + name; ListInit* paramsList = rec.getValueAsListInit("ParamTypes"); vector<string> params; for(unsigned int i = 0; i < paramsList->getSize(); i++) { string t = dtype(paramsList->getElementAsRecord(i)); if(t == "") return; params.push_back(t); } ListInit* retList = rec.getValueAsListInit("RetTypes"); string ret; if(retList->getSize() == 0) ret = "void"; else if(retList->getSize() == 1) { ret = dtype(retList->getElementAsRecord(0)); if(ret == "") return; } else return; os << "pragma(LDC_intrinsic, \"" + name + "\")\n "; os << ret + " " + builtinName + "("; if(params.size()) os << params[0]; for(size_t i = 1; i < params.size(); i++) os << ", " << params[i]; os << ")" + attributes(rec.getValueAsListInit("Properties")) + ";\n\n"; }
bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, unsigned Opc) { ListInit *Predicates = AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); for (unsigned i = 0; i < Predicates->getSize(); ++i) { Record *Pred = Predicates->getElementAsRecord(i); if (!Pred->getValue("AssemblerMatcherPredicate")) continue; std::string P = Pred->getValueAsString("AssemblerCondString"); if (!P.length()) continue; if (i != 0) o << " && "; StringRef SR(P); std::pair<StringRef, StringRef> pairs = SR.split(','); while (pairs.second.size()) { emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); o << " && "; pairs = pairs.second.split(','); } emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); } return Predicates->getSize() > 0; }
void CallingConvEmitter::EmitCallingConv(Record *CC, std::ostream &O) { ListInit *CCActions = CC->getValueAsListInit("Actions"); Counter = 0; O << "\n\nstatic bool " << CC->getName() << "(unsigned ValNo, MVT ValVT,\n" << std::string(CC->getName().size()+13, ' ') << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" << std::string(CC->getName().size()+13, ' ') << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n"; // Emit all of the actions, in order. for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) { O << "\n"; EmitAction(CCActions->getElementAsRecord(i), 2, O); } O << "\n return true; // CC didn't match.\n"; O << "}\n"; }
void CallingConvEmitter::EmitAction(Record *Action, unsigned Indent, std::ostream &O) { std::string IndentStr = std::string(Indent, ' '); if (Action->isSubClassOf("CCPredicateAction")) { O << IndentStr << "if ("; if (Action->isSubClassOf("CCIfType")) { ListInit *VTs = Action->getValueAsListInit("VTs"); for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) { Record *VT = VTs->getElementAsRecord(i); if (i != 0) O << " ||\n " << IndentStr; O << "LocVT == " << getEnumName(getValueType(VT)); } } else if (Action->isSubClassOf("CCIf")) { O << Action->getValueAsString("Predicate"); } else { Action->dump(); throw "Unknown CCPredicateAction!"; } O << ") {\n"; EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O); O << IndentStr << "}\n"; } else { if (Action->isSubClassOf("CCDelegateTo")) { Record *CC = Action->getValueAsDef("CC"); O << IndentStr << "if (!" << CC->getName() << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n" << IndentStr << " return false;\n"; } else if (Action->isSubClassOf("CCAssignToReg")) { ListInit *RegList = Action->getValueAsListInit("RegList"); if (RegList->getSize() == 1) { O << IndentStr << "if (unsigned Reg = State.AllocateReg("; O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n"; } else { O << IndentStr << "static const unsigned RegList" << ++Counter << "[] = {\n"; O << IndentStr << " "; for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { if (i != 0) O << ", "; O << getQualifiedName(RegList->getElementAsRecord(i)); } O << "\n" << IndentStr << "};\n"; O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" << Counter << ", " << RegList->getSize() << ")) {\n"; } O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " << "Reg, LocVT, LocInfo));\n"; O << IndentStr << " return false;\n"; O << IndentStr << "}\n"; } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) { ListInit *RegList = Action->getValueAsListInit("RegList"); ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList"); if (ShadowRegList->getSize() >0 && ShadowRegList->getSize() != RegList->getSize()) throw "Invalid length of list of shadowed registers"; if (RegList->getSize() == 1) { O << IndentStr << "if (unsigned Reg = State.AllocateReg("; O << getQualifiedName(RegList->getElementAsRecord(0)); O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0)); O << ")) {\n"; } else { unsigned RegListNumber = ++Counter; unsigned ShadowRegListNumber = ++Counter; O << IndentStr << "static const unsigned RegList" << RegListNumber << "[] = {\n"; O << IndentStr << " "; for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { if (i != 0) O << ", "; O << getQualifiedName(RegList->getElementAsRecord(i)); } O << "\n" << IndentStr << "};\n"; O << IndentStr << "static const unsigned RegList" << ShadowRegListNumber << "[] = {\n"; O << IndentStr << " "; for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) { if (i != 0) O << ", "; O << getQualifiedName(ShadowRegList->getElementAsRecord(i)); } O << "\n" << IndentStr << "};\n"; O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" << RegListNumber << ", " << "RegList" << ShadowRegListNumber << ", " << RegList->getSize() << ")) {\n"; } O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " << "Reg, LocVT, LocInfo));\n"; O << IndentStr << " return false;\n"; O << IndentStr << "}\n"; } else if (Action->isSubClassOf("CCAssignToStack")) { int Size = Action->getValueAsInt("Size"); int Align = Action->getValueAsInt("Align"); O << IndentStr << "unsigned Offset" << ++Counter << " = State.AllocateStack("; if (Size) O << Size << ", "; else O << "\n" << IndentStr << " State.getTarget().getTargetData()" "->getTypePaddedSize(LocVT.getTypeForMVT()), "; if (Align) O << Align; else O << "\n" << IndentStr << " State.getTarget().getTargetData()" "->getABITypeAlignment(LocVT.getTypeForMVT())"; O << ");\n" << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" << Counter << ", LocVT, LocInfo));\n"; O << IndentStr << "return false;\n"; } else if (Action->isSubClassOf("CCPromoteToType")) { Record *DestTy = Action->getValueAsDef("DestTy"); O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; O << IndentStr << "if (ArgFlags.isSExt())\n" << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n" << IndentStr << "else if (ArgFlags.isZExt())\n" << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n" << IndentStr << "else\n" << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n"; } else if (Action->isSubClassOf("CCPassByVal")) { int Size = Action->getValueAsInt("Size"); int Align = Action->getValueAsInt("Align"); O << IndentStr << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, " << Size << ", " << Align << ", ArgFlags);\n"; O << IndentStr << "return false;\n"; } else { Action->dump(); throw "Unknown CCAction!"; } } }
CodeGenIntrinsic::CodeGenIntrinsic(Record *R) { TheDef = R; std::string DefName = R->getName(); ModRef = ReadWriteMem; isOverloaded = false; isCommutative = false; canThrow = false; isNoReturn = false; isNoDuplicate = false; isConvergent = false; if (DefName.size() <= 4 || std::string(DefName.begin(), DefName.begin() + 4) != "int_") PrintFatalError("Intrinsic '" + DefName + "' does not start with 'int_'!"); EnumName = std::string(DefName.begin()+4, DefName.end()); if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field. GCCBuiltinName = R->getValueAsString("GCCBuiltinName"); if (R->getValue("MSBuiltinName")) // Ignore a missing MSBuiltinName field. MSBuiltinName = R->getValueAsString("MSBuiltinName"); TargetPrefix = R->getValueAsString("TargetPrefix"); Name = R->getValueAsString("LLVMName"); if (Name == "") { // If an explicit name isn't specified, derive one from the DefName. Name = "llvm."; for (unsigned i = 0, e = EnumName.size(); i != e; ++i) Name += (EnumName[i] == '_') ? '.' : EnumName[i]; } else { // Verify it starts with "llvm.". if (Name.size() <= 5 || std::string(Name.begin(), Name.begin() + 5) != "llvm.") PrintFatalError("Intrinsic '" + DefName + "'s name does not start with 'llvm.'!"); } // If TargetPrefix is specified, make sure that Name starts with // "llvm.<targetprefix>.". if (!TargetPrefix.empty()) { if (Name.size() < 6+TargetPrefix.size() || std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size()) != (TargetPrefix + ".")) PrintFatalError("Intrinsic '" + DefName + "' does not start with 'llvm." + TargetPrefix + ".'!"); } // Parse the list of return types. std::vector<MVT::SimpleValueType> OverloadedVTs; ListInit *TypeList = R->getValueAsListInit("RetTypes"); for (unsigned i = 0, e = TypeList->size(); i != e; ++i) { Record *TyEl = TypeList->getElementAsRecord(i); assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!"); MVT::SimpleValueType VT; if (TyEl->isSubClassOf("LLVMMatchType")) { unsigned MatchTy = TyEl->getValueAsInt("Number"); assert(MatchTy < OverloadedVTs.size() && "Invalid matching number!"); VT = OverloadedVTs[MatchTy]; // It only makes sense to use the extended and truncated vector element // variants with iAny types; otherwise, if the intrinsic is not // overloaded, all the types can be specified directly. assert(((!TyEl->isSubClassOf("LLVMExtendedType") && !TyEl->isSubClassOf("LLVMTruncatedType")) || VT == MVT::iAny || VT == MVT::vAny) && "Expected iAny or vAny type"); } else { VT = getValueType(TyEl->getValueAsDef("VT")); } if (MVT(VT).isOverloaded()) { OverloadedVTs.push_back(VT); isOverloaded = true; } // Reject invalid types. if (VT == MVT::isVoid) PrintFatalError("Intrinsic '" + DefName + " has void in result type list!"); IS.RetVTs.push_back(VT); IS.RetTypeDefs.push_back(TyEl); } // Parse the list of parameter types. TypeList = R->getValueAsListInit("ParamTypes"); for (unsigned i = 0, e = TypeList->size(); i != e; ++i) { Record *TyEl = TypeList->getElementAsRecord(i); assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!"); MVT::SimpleValueType VT; if (TyEl->isSubClassOf("LLVMMatchType")) { unsigned MatchTy = TyEl->getValueAsInt("Number"); assert(MatchTy < OverloadedVTs.size() && "Invalid matching number!"); VT = OverloadedVTs[MatchTy]; // It only makes sense to use the extended and truncated vector element // variants with iAny types; otherwise, if the intrinsic is not // overloaded, all the types can be specified directly. assert(((!TyEl->isSubClassOf("LLVMExtendedType") && !TyEl->isSubClassOf("LLVMTruncatedType") && !TyEl->isSubClassOf("LLVMVectorSameWidth")) || VT == MVT::iAny || VT == MVT::vAny) && "Expected iAny or vAny type"); } else VT = getValueType(TyEl->getValueAsDef("VT")); if (MVT(VT).isOverloaded()) { OverloadedVTs.push_back(VT); isOverloaded = true; } // Reject invalid types. if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/) PrintFatalError("Intrinsic '" + DefName + " has void in result type list!"); IS.ParamVTs.push_back(VT); IS.ParamTypeDefs.push_back(TyEl); } // Parse the intrinsic properties. ListInit *PropList = R->getValueAsListInit("IntrProperties"); for (unsigned i = 0, e = PropList->size(); i != e; ++i) { Record *Property = PropList->getElementAsRecord(i); assert(Property->isSubClassOf("IntrinsicProperty") && "Expected a property!"); if (Property->getName() == "IntrNoMem") ModRef = NoMem; else if (Property->getName() == "IntrReadMem") ModRef = ModRefBehavior(ModRef & ~MR_Mod); else if (Property->getName() == "IntrWriteMem") ModRef = ModRefBehavior(ModRef & ~MR_Ref); else if (Property->getName() == "IntrArgMemOnly") ModRef = ModRefBehavior(ModRef & ~MR_Anywhere); else if (Property->getName() == "Commutative") isCommutative = true; else if (Property->getName() == "Throws") canThrow = true; else if (Property->getName() == "IntrNoDuplicate") isNoDuplicate = true; else if (Property->getName() == "IntrConvergent") isConvergent = true; else if (Property->getName() == "IntrNoReturn") isNoReturn = true; else if (Property->isSubClassOf("NoCapture")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture)); } else if (Property->isSubClassOf("Returned")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, Returned)); } else if (Property->isSubClassOf("ReadOnly")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly)); } else if (Property->isSubClassOf("WriteOnly")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, WriteOnly)); } else if (Property->isSubClassOf("ReadNone")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone)); } else llvm_unreachable("Unknown property!"); } // Sort the argument attributes for later benefit. std::sort(ArgumentAttributes.begin(), ArgumentAttributes.end()); }
CodeGenIntrinsic::CodeGenIntrinsic(Record *R, CodeGenTarget *CGT) { TheDef = R; std::string DefName = R->getName(); ModRef = WriteMem; isOverloaded = false; if (DefName.size() <= 4 || std::string(DefName.begin(), DefName.begin()+4) != "int_") throw "Intrinsic '" + DefName + "' does not start with 'int_'!"; EnumName = std::string(DefName.begin()+4, DefName.end()); if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field. GCCBuiltinName = R->getValueAsString("GCCBuiltinName"); TargetPrefix = R->getValueAsString("TargetPrefix"); Name = R->getValueAsString("LLVMName"); if (Name == "") { // If an explicit name isn't specified, derive one from the DefName. Name = "llvm."; for (unsigned i = 0, e = EnumName.size(); i != e; ++i) if (EnumName[i] == '_') Name += '.'; else Name += EnumName[i]; } else { // Verify it starts with "llvm.". if (Name.size() <= 5 || std::string(Name.begin(), Name.begin()+5) != "llvm.") throw "Intrinsic '" + DefName + "'s name does not start with 'llvm.'!"; } // If TargetPrefix is specified, make sure that Name starts with // "llvm.<targetprefix>.". if (!TargetPrefix.empty()) { if (Name.size() < 6+TargetPrefix.size() || std::string(Name.begin()+5, Name.begin()+6+TargetPrefix.size()) != (TargetPrefix+".")) throw "Intrinsic '" + DefName + "' does not start with 'llvm." + TargetPrefix + ".'!"; } // Parse the list of argument types. ListInit *TypeList = R->getValueAsListInit("Types"); for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) { Record *TyEl = TypeList->getElementAsRecord(i); assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!"); ArgTypes.push_back(TyEl->getValueAsString("TypeVal")); MVT::ValueType VT = getValueType(TyEl->getValueAsDef("VT"), CGT); isOverloaded |= VT == MVT::iAny; ArgVTs.push_back(VT); ArgTypeDefs.push_back(TyEl); } if (ArgTypes.size() == 0) throw "Intrinsic '"+DefName+"' needs at least a type for the ret value!"; // Parse the intrinsic properties. ListInit *PropList = R->getValueAsListInit("Properties"); for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) { Record *Property = PropList->getElementAsRecord(i); assert(Property->isSubClassOf("IntrinsicProperty") && "Expected a property!"); if (Property->getName() == "IntrNoMem") ModRef = NoMem; else if (Property->getName() == "IntrReadArgMem") ModRef = ReadArgMem; else if (Property->getName() == "IntrReadMem") ModRef = ReadMem; else if (Property->getName() == "IntrWriteArgMem") ModRef = WriteArgMem; else if (Property->getName() == "IntrWriteMem") ModRef = WriteMem; else assert(0 && "Unknown property!"); } }
CodeGenIntrinsic::CodeGenIntrinsic(Record *R) { TheDef = R; std::string DefName = R->getName(); ModRef = WriteMem; isOverloaded = false; isCommutative = false; if (DefName.size() <= 4 || std::string(DefName.begin(), DefName.begin() + 4) != "int_") throw "Intrinsic '" + DefName + "' does not start with 'int_'!"; EnumName = std::string(DefName.begin()+4, DefName.end()); if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field. GCCBuiltinName = R->getValueAsString("GCCBuiltinName"); TargetPrefix = R->getValueAsString("TargetPrefix"); Name = R->getValueAsString("LLVMName"); if (Name == "") { // If an explicit name isn't specified, derive one from the DefName. Name = "llvm."; for (unsigned i = 0, e = EnumName.size(); i != e; ++i) Name += (EnumName[i] == '_') ? '.' : EnumName[i]; } else { // Verify it starts with "llvm.". if (Name.size() <= 5 || std::string(Name.begin(), Name.begin() + 5) != "llvm.") throw "Intrinsic '" + DefName + "'s name does not start with 'llvm.'!"; } // If TargetPrefix is specified, make sure that Name starts with // "llvm.<targetprefix>.". if (!TargetPrefix.empty()) { if (Name.size() < 6+TargetPrefix.size() || std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size()) != (TargetPrefix + ".")) throw "Intrinsic '" + DefName + "' does not start with 'llvm." + TargetPrefix + ".'!"; } // Parse the list of return types. std::vector<MVT::SimpleValueType> OverloadedVTs; ListInit *TypeList = R->getValueAsListInit("RetTypes"); for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) { Record *TyEl = TypeList->getElementAsRecord(i); assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!"); MVT::SimpleValueType VT; if (TyEl->isSubClassOf("LLVMMatchType")) { unsigned MatchTy = TyEl->getValueAsInt("Number"); assert(MatchTy < OverloadedVTs.size() && "Invalid matching number!"); VT = OverloadedVTs[MatchTy]; // It only makes sense to use the extended and truncated vector element // variants with iAny types; otherwise, if the intrinsic is not // overloaded, all the types can be specified directly. assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") && !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) || VT == MVT::iAny || VT == MVT::vAny) && "Expected iAny or vAny type"); } else { VT = getValueType(TyEl->getValueAsDef("VT")); } if (EVT(VT).isOverloaded()) { OverloadedVTs.push_back(VT); isOverloaded |= true; } IS.RetVTs.push_back(VT); IS.RetTypeDefs.push_back(TyEl); } if (IS.RetVTs.size() == 0) throw "Intrinsic '"+DefName+"' needs at least a type for the ret value!"; // Parse the list of parameter types. TypeList = R->getValueAsListInit("ParamTypes"); for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) { Record *TyEl = TypeList->getElementAsRecord(i); assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!"); MVT::SimpleValueType VT; if (TyEl->isSubClassOf("LLVMMatchType")) { unsigned MatchTy = TyEl->getValueAsInt("Number"); assert(MatchTy < OverloadedVTs.size() && "Invalid matching number!"); VT = OverloadedVTs[MatchTy]; // It only makes sense to use the extended and truncated vector element // variants with iAny types; otherwise, if the intrinsic is not // overloaded, all the types can be specified directly. assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") && !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) || VT == MVT::iAny || VT == MVT::vAny) && "Expected iAny or vAny type"); } else VT = getValueType(TyEl->getValueAsDef("VT")); if (EVT(VT).isOverloaded()) { OverloadedVTs.push_back(VT); isOverloaded |= true; } IS.ParamVTs.push_back(VT); IS.ParamTypeDefs.push_back(TyEl); } // Parse the intrinsic properties. ListInit *PropList = R->getValueAsListInit("Properties"); for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) { Record *Property = PropList->getElementAsRecord(i); assert(Property->isSubClassOf("IntrinsicProperty") && "Expected a property!"); if (Property->getName() == "IntrNoMem") ModRef = NoMem; else if (Property->getName() == "IntrReadArgMem") ModRef = ReadArgMem; else if (Property->getName() == "IntrReadMem") ModRef = ReadMem; else if (Property->getName() == "IntrWriteArgMem") ModRef = WriteArgMem; else if (Property->getName() == "IntrWriteMem") ModRef = WriteMem; else if (Property->getName() == "Commutative") isCommutative = true; else if (Property->isSubClassOf("NoCapture")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture)); } else assert(0 && "Unknown property!"); } }
void CallingConvEmitter::EmitAction(Record *Action, unsigned Indent, std::ostream &O) { std::string IndentStr = std::string(Indent, ' '); if (Action->isSubClassOf("CCPredicateAction")) { O << IndentStr << "if ("; if (Action->isSubClassOf("CCIfType")) { ListInit *VTs = Action->getValueAsListInit("VTs"); for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) { Record *VT = VTs->getElementAsRecord(i); if (i != 0) O << " ||\n " << IndentStr; O << "LocVT == " << getEnumName(getValueType(VT)); } } else if (Action->isSubClassOf("CCIf")) { O << Action->getValueAsString("Predicate"); } else { Action->dump(); throw "Unknown CCPredicateAction!"; } O << ") {\n"; EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O); O << IndentStr << "}\n"; } else { if (Action->isSubClassOf("CCDelegateTo")) { Record *CC = Action->getValueAsDef("CC"); O << IndentStr << "if (!" << CC->getName() << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n" << IndentStr << " return false;\n"; } else if (Action->isSubClassOf("CCAssignToReg")) { ListInit *RegList = Action->getValueAsListInit("RegList"); if (RegList->getSize() == 1) { O << IndentStr << "if (unsigned Reg = State.AllocateReg("; O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n"; } else { O << IndentStr << "static const unsigned RegList" << ++Counter << "[] = {\n"; O << IndentStr << " "; for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { if (i != 0) O << ", "; O << getQualifiedName(RegList->getElementAsRecord(i)); } O << "\n" << IndentStr << "};\n"; O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" << Counter << ", " << RegList->getSize() << ")) {\n"; } O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " << "Reg, LocVT, LocInfo));\n"; O << IndentStr << " return false;\n"; O << IndentStr << "}\n"; } else if (Action->isSubClassOf("CCAssignToStack")) { int Size = Action->getValueAsInt("Size"); int Align = Action->getValueAsInt("Align"); O << IndentStr << "unsigned Offset" << ++Counter << " = State.AllocateStack(" << Size << ", " << Align << ");\n"; O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" << Counter << ", LocVT, LocInfo));\n"; O << IndentStr << "return false;\n"; } else if (Action->isSubClassOf("CCPromoteToType")) { Record *DestTy = Action->getValueAsDef("DestTy"); O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; O << IndentStr << "if (ArgFlags & ISD::ParamFlags::SExt)\n" << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n" << IndentStr << "else if (ArgFlags & ISD::ParamFlags::ZExt)\n" << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n" << IndentStr << "else\n" << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n"; } else { Action->dump(); throw "Unknown CCAction!"; } } }