//===- CallingConvEmitter.cpp - Generate calling conventions --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend is responsible for emitting descriptions of the calling
// conventions supported by this target.
//
//===----------------------------------------------------------------------===//

#include "CodeGenTarget.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
using namespace llvm;

namespace {
class CallingConvEmitter {
  RecordKeeper &Records;
  unsigned Counter;
  std::string CurrentAction;
  bool SwiftAction;

  std::map<std::string, std::set<std::string>> AssignedRegsMap;
  std::map<std::string, std::set<std::string>> AssignedSwiftRegsMap;
  std::map<std::string, std::set<std::string>> DelegateToMap;

public:
  explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {}

  void run(raw_ostream &o);

private:
  void EmitCallingConv(Record *CC, raw_ostream &O);
  void EmitAction(Record *Action, unsigned Indent, raw_ostream &O);
  void EmitArgRegisterLists(raw_ostream &O);
};
} // End anonymous namespace

void CallingConvEmitter::run(raw_ostream &O) {
  std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv");

  // Emit prototypes for all of the non-custom CC's so that they can forward ref
  // each other.
  Records.startTimer("Emit prototypes");
  O << "#ifndef GET_CC_REGISTER_LISTS\n\n";
  for (Record *CC : CCs) {
    if (!CC->getValueAsBit("Custom")) {
      unsigned Pad = CC->getName().size();
      if (CC->getValueAsBit("Entry")) {
        O << "bool llvm::";
        Pad += 12;
      } else {
        O << "static bool ";
        Pad += 13;
      }
      O << CC->getName() << "(unsigned ValNo, MVT ValVT,\n"
        << std::string(Pad, ' ') << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
        << std::string(Pad, ' ')
        << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n";
    }
  }

  // Emit each non-custom calling convention description in full.
  Records.startTimer("Emit full descriptions");
  for (Record *CC : CCs) {
    if (!CC->getValueAsBit("Custom")) {
      EmitCallingConv(CC, O);
    }
  }

  EmitArgRegisterLists(O);

  O << "\n#endif // CC_REGISTER_LIST\n";
}

void CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) {
  ListInit *CCActions = CC->getValueAsListInit("Actions");
  Counter = 0;

  CurrentAction = CC->getName().str();
  // Call upon the creation of a map entry from the void!
  // We want an entry in AssignedRegsMap for every action, even if that
  // entry is empty.
  AssignedRegsMap[CurrentAction] = {};

  O << "\n\n";
  unsigned Pad = CurrentAction.size();
  if (CC->getValueAsBit("Entry")) {
    O << "bool llvm::";
    Pad += 12;
  } else {
    O << "static bool ";
    Pad += 13;
  }
  O << CurrentAction << "(unsigned ValNo, MVT ValVT,\n"
    << std::string(Pad, ' ') << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
    << std::string(Pad, ' ') << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n";
  // Emit all of the actions, in order.
  for (unsigned i = 0, e = CCActions->size(); i != e; ++i) {
    Record *Action = CCActions->getElementAsRecord(i);
    SwiftAction = llvm::any_of(Action->getSuperClasses(),
                               [](const std::pair<Record *, SMRange> &Class) {
                                 std::string Name =
                                     Class.first->getNameInitAsString();
                                 return StringRef(Name).startswith("CCIfSwift");
                               });

    O << "\n";
    EmitAction(Action, 2, O);
  }
  
  O << "\n  return true; // CC didn't match.\n";
  O << "}\n";
}

void CallingConvEmitter::EmitAction(Record *Action,
                                    unsigned Indent, raw_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->size(); 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 {
      errs() << *Action;
      PrintFatalError(Action->getLoc(), "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";
      DelegateToMap[CurrentAction].insert(CC->getName().str());
    } else if (Action->isSubClassOf("CCAssignToReg") ||
               Action->isSubClassOf("CCAssignToRegAndStack")) {
      ListInit *RegList = Action->getValueAsListInit("RegList");
      if (RegList->size() == 1) {
        std::string Name = getQualifiedName(RegList->getElementAsRecord(0));
        O << IndentStr << "if (unsigned Reg = State.AllocateReg(" << Name
          << ")) {\n";
        if (SwiftAction)
          AssignedSwiftRegsMap[CurrentAction].insert(Name);
        else
          AssignedRegsMap[CurrentAction].insert(Name);
      } else {
        O << IndentStr << "static const MCPhysReg RegList" << ++Counter
          << "[] = {\n";
        O << IndentStr << "  ";
        ListSeparator LS;
        for (unsigned i = 0, e = RegList->size(); i != e; ++i) {
          std::string Name = getQualifiedName(RegList->getElementAsRecord(i));
          if (SwiftAction)
            AssignedSwiftRegsMap[CurrentAction].insert(Name);
          else
            AssignedRegsMap[CurrentAction].insert(Name);
          O << LS << Name;
        }
        O << "\n" << IndentStr << "};\n";
        O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
          << Counter << ")) {\n";
      }
      O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
        << "Reg, LocVT, LocInfo));\n";
      if (Action->isSubClassOf("CCAssignToRegAndStack")) {
        int Size = Action->getValueAsInt("Size");
        int Align = Action->getValueAsInt("Align");
        O << IndentStr << "  (void)State.AllocateStack(";
        if (Size)
          O << Size << ", ";
        else
          O << "\n"
            << IndentStr
            << "  State.getMachineFunction().getDataLayout()."
               "getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())),"
               " ";
        if (Align)
          O << "Align(" << Align << ")";
        else
          O << "\n"
            << IndentStr
            << "  State.getMachineFunction().getDataLayout()."
               "getABITypeAlign(EVT(LocVT).getTypeForEVT(State.getContext()"
               "))";
        O << ");\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->empty() && ShadowRegList->size() != RegList->size())
        PrintFatalError(Action->getLoc(),
                        "Invalid length of list of shadowed registers");

      if (RegList->size() == 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 MCPhysReg RegList" << RegListNumber
          << "[] = {\n";
        O << IndentStr << "  ";
        ListSeparator LS;
        for (unsigned i = 0, e = RegList->size(); i != e; ++i)
          O << LS << getQualifiedName(RegList->getElementAsRecord(i));
        O << "\n" << IndentStr << "};\n";

        O << IndentStr << "static const MCPhysReg RegList"
          << ShadowRegListNumber << "[] = {\n";
        O << IndentStr << "  ";
        ListSeparator LSS;
        for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i)
          O << LSS << getQualifiedName(ShadowRegList->getElementAsRecord(i));
        O << "\n" << IndentStr << "};\n";

        O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
          << RegListNumber << ", " << "RegList" << ShadowRegListNumber
          << ")) {\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.getMachineFunction().getDataLayout()."
             "getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())),"
             " ";
      if (Align)
        O << "Align(" << Align << ")";
      else
        O << "\n"
          << IndentStr
          << "  State.getMachineFunction().getDataLayout()."
             "getABITypeAlign(EVT(LocVT).getTypeForEVT(State.getContext()"
             "))";
      O << ");\n" << IndentStr
        << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
        << Counter << ", LocVT, LocInfo));\n";
      O << IndentStr << "return false;\n";
    } else if (Action->isSubClassOf("CCAssignToStackWithShadow")) {
      int Size = Action->getValueAsInt("Size");
      int Align = Action->getValueAsInt("Align");
      ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");

      unsigned ShadowRegListNumber = ++Counter;

      O << IndentStr << "static const MCPhysReg ShadowRegList"
          << ShadowRegListNumber << "[] = {\n";
      O << IndentStr << "  ";
      ListSeparator LS;
      for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i)
        O << LS << getQualifiedName(ShadowRegList->getElementAsRecord(i));
      O << "\n" << IndentStr << "};\n";

      O << IndentStr << "unsigned Offset" << ++Counter
        << " = State.AllocateStack(" << Size << ", Align(" << Align << "), "
        << "ShadowRegList" << ShadowRegListNumber << ");\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");
      MVT::SimpleValueType DestVT = getValueType(DestTy);
      O << IndentStr << "LocVT = " << getEnumName(DestVT) <<";\n";
      if (MVT(DestVT).isFloatingPoint()) {
        O << IndentStr << "LocInfo = CCValAssign::FPExt;\n";
      } else {
        O << IndentStr << "if (ArgFlags.isSExt())\n"
          << IndentStr << "  LocInfo = CCValAssign::SExt;\n"
          << IndentStr << "else if (ArgFlags.isZExt())\n"
          << IndentStr << "  LocInfo = CCValAssign::ZExt;\n"
          << IndentStr << "else\n"
          << IndentStr << "  LocInfo = CCValAssign::AExt;\n";
      }
    } else if (Action->isSubClassOf("CCPromoteToUpperBitsInType")) {
      Record *DestTy = Action->getValueAsDef("DestTy");
      MVT::SimpleValueType DestVT = getValueType(DestTy);
      O << IndentStr << "LocVT = " << getEnumName(DestVT) << ";\n";
      if (MVT(DestVT).isFloatingPoint()) {
        PrintFatalError(Action->getLoc(),
                        "CCPromoteToUpperBitsInType does not handle floating "
                        "point");
      } else {
        O << IndentStr << "if (ArgFlags.isSExt())\n"
          << IndentStr << "  LocInfo = CCValAssign::SExtUpper;\n"
          << IndentStr << "else if (ArgFlags.isZExt())\n"
          << IndentStr << "  LocInfo = CCValAssign::ZExtUpper;\n"
          << IndentStr << "else\n"
          << IndentStr << "  LocInfo = CCValAssign::AExtUpper;\n";
      }
    } else if (Action->isSubClassOf("CCBitConvertToType")) {
      Record *DestTy = Action->getValueAsDef("DestTy");
      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
      O << IndentStr << "LocInfo = CCValAssign::BCvt;\n";
    } else if (Action->isSubClassOf("CCTruncToType")) {
      Record *DestTy = Action->getValueAsDef("DestTy");
      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
      O << IndentStr << "LocInfo = CCValAssign::Trunc;\n";
    } else if (Action->isSubClassOf("CCPassIndirect")) {
      Record *DestTy = Action->getValueAsDef("DestTy");
      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
      O << IndentStr << "LocInfo = CCValAssign::Indirect;\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(" << Align << "), ArgFlags);\n";
      O << IndentStr << "return false;\n";
    } else if (Action->isSubClassOf("CCCustom")) {
      O << IndentStr
        << "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, "
        << "LocVT, LocInfo, ArgFlags, State))\n";
      O << IndentStr << "  return false;\n";
    } else {
      errs() << *Action;
      PrintFatalError(Action->getLoc(), "Unknown CCAction!");
    }
  }
}

void CallingConvEmitter::EmitArgRegisterLists(raw_ostream &O) {
  // Transitively merge all delegated CCs into AssignedRegsMap.
  using EntryTy = std::pair<std::string, std::set<std::string>>;
  bool Redo;
  do {
    Redo = false;
    std::deque<EntryTy> Worklist(DelegateToMap.begin(), DelegateToMap.end());

    while (!Worklist.empty()) {
      EntryTy Entry = Worklist.front();
      Worklist.pop_front();

      const std::string &CCName = Entry.first;
      std::set<std::string> &Registers = Entry.second;
      if (!Registers.empty())
        continue;

      for (auto &InnerEntry : Worklist) {
        const std::string &InnerCCName = InnerEntry.first;
        std::set<std::string> &InnerRegisters = InnerEntry.second;

        if (InnerRegisters.find(CCName) != InnerRegisters.end()) {
          AssignedRegsMap[InnerCCName].insert(
              AssignedRegsMap[CCName].begin(),
              AssignedRegsMap[CCName].end());
          InnerRegisters.erase(CCName);
        }
      }

      DelegateToMap.erase(CCName);
      Redo = true;
    }
  } while (Redo);

  if (AssignedRegsMap.empty())
    return;

  O << "\n#else\n\n";

  for (auto &Entry : AssignedRegsMap) {
    const std::string &RegName = Entry.first;
    std::set<std::string> &Registers = Entry.second;

    if (RegName.empty())
      continue;

    O << "const MCRegister " << Entry.first << "_ArgRegs[] = { ";

    if (Registers.empty()) {
      O << "0";
    } else {
      ListSeparator LS;
      for (const std::string &Reg : Registers)
        O << LS << Reg;
    }

    O << " };\n";
  }

  if (AssignedSwiftRegsMap.empty())
    return;

  O << "\n// Registers used by Swift.\n";
  for (auto &Entry : AssignedSwiftRegsMap) {
    const std::string &RegName = Entry.first;
    std::set<std::string> &Registers = Entry.second;

    O << "const MCRegister " << RegName << "_Swift_ArgRegs[] = { ";

    ListSeparator LS;
    for (const std::string &Reg : Registers)
      O << LS << Reg;

    O << " };\n";
  }
}

namespace llvm {

void EmitCallingConv(RecordKeeper &RK, raw_ostream &OS) {
  emitSourceFileHeader("Calling Convention Implementation Fragment", OS);
  CallingConvEmitter(RK).run(OS);
}

} // End llvm namespace
