188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner//===- CallingConvEmitter.cpp - Generate calling conventions --------------===//
288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner//
388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner//                     The LLVM Compiler Infrastructure
488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner//
53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source
63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details.
788ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner//
888ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner//===----------------------------------------------------------------------===//
988ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner//
1088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner// This tablegen backend is responsible for emitting descriptions of the calling
1188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner// conventions supported by this target.
1288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner//
1388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner//===----------------------------------------------------------------------===//
1488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
1588ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner#include "CodeGenTarget.h"
1661131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger#include "llvm/TableGen/Error.h"
177c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Record.h"
186f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h"
196f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <cassert>
2088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattnerusing namespace llvm;
2188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
226f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace {
236f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass CallingConvEmitter {
246f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  RecordKeeper &Records;
256f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic:
266f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {}
276f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
286f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void run(raw_ostream &o);
296f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
306f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenprivate:
316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void EmitCallingConv(Record *CC, raw_ostream &O);
326f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void EmitAction(Record *Action, unsigned Indent, raw_ostream &O);
336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  unsigned Counter;
346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen};
356f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace
366f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
371a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid CallingConvEmitter::run(raw_ostream &O) {
3888ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
3988ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv");
4088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
4188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  // Emit prototypes for all of the CC's so that they can forward ref each
4288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  // other.
4388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  for (unsigned i = 0, e = CCs.size(); i != e; ++i) {
4488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    O << "static bool " << CCs[i]->getName()
451e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sands      << "(unsigned ValNo, MVT ValVT,\n"
4688ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      << std::string(CCs[i]->getName().size()+13, ' ')
471440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands      << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
482092c8ac9c8647d31fd4d01d74d361f01ca05e38Chris Lattner      << std::string(CCs[i]->getName().size()+13, ' ')
49276dcbdc8db6614cfd5004dc7dc35e437ddf9c58Duncan Sands      << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n";
5088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  }
5188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
5288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  // Emit each calling convention description in full.
5388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  for (unsigned i = 0, e = CCs.size(); i != e; ++i)
5488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    EmitCallingConv(CCs[i], O);
5588ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner}
5688ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
5788ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
581a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) {
5905bce0beee87512e52428d4b80f5a8e79a949576David Greene  ListInit *CCActions = CC->getValueAsListInit("Actions");
6088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  Counter = 0;
6188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
6288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  O << "\n\nstatic bool " << CC->getName()
631e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sands    << "(unsigned ValNo, MVT ValVT,\n"
642092c8ac9c8647d31fd4d01d74d361f01ca05e38Chris Lattner    << std::string(CC->getName().size()+13, ' ')
651440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands    << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
6688ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    << std::string(CC->getName().size()+13, ' ')
67276dcbdc8db6614cfd5004dc7dc35e437ddf9c58Duncan Sands    << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n";
6888ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  // Emit all of the actions, in order.
6988ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) {
7088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    O << "\n";
7188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    EmitAction(CCActions->getElementAsRecord(i), 2, O);
7288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  }
7388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
7488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  O << "\n  return true;  // CC didn't match.\n";
7588ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  O << "}\n";
7688ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner}
7788ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
7888ee2a18a77438e3f26efc87bded672db041fe09Chris Lattnervoid CallingConvEmitter::EmitAction(Record *Action,
791a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar                                    unsigned Indent, raw_ostream &O) {
8088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  std::string IndentStr = std::string(Indent, ' ');
8188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
8288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  if (Action->isSubClassOf("CCPredicateAction")) {
8388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    O << IndentStr << "if (";
8488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
85e3bab80e338ac81b5b911c6ebc513aeafc335ce5Chris Lattner    if (Action->isSubClassOf("CCIfType")) {
8605bce0beee87512e52428d4b80f5a8e79a949576David Greene      ListInit *VTs = Action->getValueAsListInit("VTs");
8788ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) {
8888ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        Record *VT = VTs->getElementAsRecord(i);
892092c8ac9c8647d31fd4d01d74d361f01ca05e38Chris Lattner        if (i != 0) O << " ||\n    " << IndentStr;
9088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        O << "LocVT == " << getEnumName(getValueType(VT));
9188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      }
9288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
93e3bab80e338ac81b5b911c6ebc513aeafc335ce5Chris Lattner    } else if (Action->isSubClassOf("CCIf")) {
9488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      O << Action->getValueAsString("Predicate");
9588ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    } else {
9688ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      Action->dump();
9761131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger      PrintFatalError("Unknown CCPredicateAction!");
9888ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    }
9988ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner
10088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    O << ") {\n";
10188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O);
10288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    O << IndentStr << "}\n";
10388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  } else {
10488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    if (Action->isSubClassOf("CCDelegateTo")) {
10588ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      Record *CC = Action->getValueAsDef("CC");
10688ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      O << IndentStr << "if (!" << CC->getName()
10788ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n"
10888ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        << IndentStr << "  return false;\n";
10988ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    } else if (Action->isSubClassOf("CCAssignToReg")) {
11005bce0beee87512e52428d4b80f5a8e79a949576David Greene      ListInit *RegList = Action->getValueAsListInit("RegList");
11188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      if (RegList->getSize() == 1) {
11288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
11388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n";
11488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      } else {
115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        O << IndentStr << "static const MCPhysReg RegList" << ++Counter
11688ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner          << "[] = {\n";
11788ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        O << IndentStr << "  ";
11888ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
11988ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner          if (i != 0) O << ", ";
12088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner          O << getQualifiedName(RegList->getElementAsRecord(i));
12188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        }
12288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        O << "\n" << IndentStr << "};\n";
12388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
12488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner          << Counter << ", " << RegList->getSize() << ")) {\n";
12588ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      }
12688ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
12788ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        << "Reg, LocVT, LocInfo));\n";
12888ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      O << IndentStr << "  return false;\n";
12988ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      O << IndentStr << "}\n";
13067073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov    } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) {
13105bce0beee87512e52428d4b80f5a8e79a949576David Greene      ListInit *RegList = Action->getValueAsListInit("RegList");
13205bce0beee87512e52428d4b80f5a8e79a949576David Greene      ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
13367073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov      if (ShadowRegList->getSize() >0 &&
13467073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov          ShadowRegList->getSize() != RegList->getSize())
13561131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger        PrintFatalError("Invalid length of list of shadowed registers");
13667073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov
13767073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov      if (RegList->getSize() == 1) {
13867073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
13967073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        O << getQualifiedName(RegList->getElementAsRecord(0));
14067073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0));
14167073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        O << ")) {\n";
14267073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov      } else {
14367073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        unsigned RegListNumber = ++Counter;
14467073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        unsigned ShadowRegListNumber = ++Counter;
14567073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov
146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        O << IndentStr << "static const MCPhysReg RegList" << RegListNumber
14767073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov          << "[] = {\n";
14867073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        O << IndentStr << "  ";
14967073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
15067073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov          if (i != 0) O << ", ";
15167073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov          O << getQualifiedName(RegList->getElementAsRecord(i));
15267073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        }
15367073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        O << "\n" << IndentStr << "};\n";
15467073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov
155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        O << IndentStr << "static const MCPhysReg RegList"
15667073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov          << ShadowRegListNumber << "[] = {\n";
15767073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        O << IndentStr << "  ";
15867073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) {
15967073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov          if (i != 0) O << ", ";
16067073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov          O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
16167073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        }
16267073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        O << "\n" << IndentStr << "};\n";
16367073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov
16467073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
16567073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov          << RegListNumber << ", " << "RegList" << ShadowRegListNumber
16667073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov          << ", " << RegList->getSize() << ")) {\n";
16767073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov      }
16867073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov      O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
16967073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov        << "Reg, LocVT, LocInfo));\n";
17067073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov      O << IndentStr << "  return false;\n";
17167073f1cbd95f61a8db01ac479f5e60c0a048ac0Anton Korobeynikov      O << IndentStr << "}\n";
17288ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    } else if (Action->isSubClassOf("CCAssignToStack")) {
17388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      int Size = Action->getValueAsInt("Size");
17488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      int Align = Action->getValueAsInt("Align");
17587b665d3dee92ef5f30d9eb1afdb64448bc3e2efDuncan Sands
1765daafa9b1b5279ba6a5032a4a841abb20b4023efEvan Cheng      O << IndentStr << "unsigned Offset" << ++Counter
1775daafa9b1b5279ba6a5032a4a841abb20b4023efEvan Cheng        << " = State.AllocateStack(";
17887b665d3dee92ef5f30d9eb1afdb64448bc3e2efDuncan Sands      if (Size)
1795daafa9b1b5279ba6a5032a4a841abb20b4023efEvan Cheng        O << Size << ", ";
18087b665d3dee92ef5f30d9eb1afdb64448bc3e2efDuncan Sands      else
181791cfc211a9801002bfda6b3eb4de7e041f04f53Micah Villmow        O << "\n" << IndentStr << "  State.getTarget().getDataLayout()"
1821440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands          "->getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())), ";
18387b665d3dee92ef5f30d9eb1afdb64448bc3e2efDuncan Sands      if (Align)
18487b665d3dee92ef5f30d9eb1afdb64448bc3e2efDuncan Sands        O << Align;
18587b665d3dee92ef5f30d9eb1afdb64448bc3e2efDuncan Sands      else
186791cfc211a9801002bfda6b3eb4de7e041f04f53Micah Villmow        O << "\n" << IndentStr << "  State.getTarget().getDataLayout()"
1871440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands          "->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))";
1885daafa9b1b5279ba6a5032a4a841abb20b4023efEvan Cheng      O << ");\n" << IndentStr
18987b665d3dee92ef5f30d9eb1afdb64448bc3e2efDuncan Sands        << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
19088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner        << Counter << ", LocVT, LocInfo));\n";
19188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      O << IndentStr << "return false;\n";
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else if (Action->isSubClassOf("CCAssignToStackWithShadow")) {
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      int Size = Action->getValueAsInt("Size");
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      int Align = Action->getValueAsInt("Align");
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned ShadowRegListNumber = ++Counter;
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      O << IndentStr << "static const MCPhysReg ShadowRegList"
20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          << ShadowRegListNumber << "[] = {\n";
20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      O << IndentStr << "  ";
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) {
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (i != 0) O << ", ";
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      O << "\n" << IndentStr << "};\n";
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      O << IndentStr << "unsigned Offset" << ++Counter
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        << " = State.AllocateStack("
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        << Size << ", " << Align << ", "
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        << "ShadowRegList" << ShadowRegListNumber << ", "
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        << ShadowRegList->getSize() << ");\n";
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        << Counter << ", LocVT, LocInfo));\n";
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      O << IndentStr << "return false;\n";
21688ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    } else if (Action->isSubClassOf("CCPromoteToType")) {
2172092c8ac9c8647d31fd4d01d74d361f01ca05e38Chris Lattner      Record *DestTy = Action->getValueAsDef("DestTy");
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MVT::SimpleValueType DestVT = getValueType(DestTy);
21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      O << IndentStr << "LocVT = " << getEnumName(DestVT) <<";\n";
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (MVT(DestVT).isFloatingPoint()) {
22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        O << IndentStr << "LocInfo = CCValAssign::FPExt;\n";
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      } else {
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        O << IndentStr << "if (ArgFlags.isSExt())\n"
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n"
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          << IndentStr << "else if (ArgFlags.isZExt())\n"
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n"
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          << IndentStr << "else\n"
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
2301f595bb42950088ccb8246e6b065a96027b46ec6Bob Wilson    } else if (Action->isSubClassOf("CCBitConvertToType")) {
2311f595bb42950088ccb8246e6b065a96027b46ec6Bob Wilson      Record *DestTy = Action->getValueAsDef("DestTy");
2321f595bb42950088ccb8246e6b065a96027b46ec6Bob Wilson      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
2331f595bb42950088ccb8246e6b065a96027b46ec6Bob Wilson      O << IndentStr << "LocInfo = CCValAssign::BCvt;\n";
2344ab15535e7028a48d75c9d08ed57e9b3b05b1f53Anton Korobeynikov    } else if (Action->isSubClassOf("CCPassIndirect")) {
2354ab15535e7028a48d75c9d08ed57e9b3b05b1f53Anton Korobeynikov      Record *DestTy = Action->getValueAsDef("DestTy");
2364ab15535e7028a48d75c9d08ed57e9b3b05b1f53Anton Korobeynikov      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
2374ab15535e7028a48d75c9d08ed57e9b3b05b1f53Anton Korobeynikov      O << IndentStr << "LocInfo = CCValAssign::Indirect;\n";
2386bfa8a121d69f16ca2cb48360a182f52e5930f0eEvan Cheng    } else if (Action->isSubClassOf("CCPassByVal")) {
2396bfa8a121d69f16ca2cb48360a182f52e5930f0eEvan Cheng      int Size = Action->getValueAsInt("Size");
2406bfa8a121d69f16ca2cb48360a182f52e5930f0eEvan Cheng      int Align = Action->getValueAsInt("Align");
2416bfa8a121d69f16ca2cb48360a182f52e5930f0eEvan Cheng      O << IndentStr
2426bfa8a121d69f16ca2cb48360a182f52e5930f0eEvan Cheng        << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, "
2436bfa8a121d69f16ca2cb48360a182f52e5930f0eEvan Cheng        << Size << ", " << Align << ", ArgFlags);\n";
244594d37e21aea4ef841d9ee5d9c328c4bf1c6bed7Rafael Espindola      O << IndentStr << "return false;\n";
2451f595bb42950088ccb8246e6b065a96027b46ec6Bob Wilson    } else if (Action->isSubClassOf("CCCustom")) {
2461f595bb42950088ccb8246e6b065a96027b46ec6Bob Wilson      O << IndentStr
2471f595bb42950088ccb8246e6b065a96027b46ec6Bob Wilson        << "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, "
2481f595bb42950088ccb8246e6b065a96027b46ec6Bob Wilson        << "LocVT, LocInfo, ArgFlags, State))\n";
2491f595bb42950088ccb8246e6b065a96027b46ec6Bob Wilson      O << IndentStr << IndentStr << "return false;\n";
25088ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    } else {
25188ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner      Action->dump();
25261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger      PrintFatalError("Unknown CCAction!");
25388ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner    }
25488ee2a18a77438e3f26efc87bded672db041fe09Chris Lattner  }
25550d456539dea5e61d7a1592a78f1861fb35b0063Chris Lattner}
2566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
2576f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm {
2586f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
2596f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitCallingConv(RecordKeeper &RK, raw_ostream &OS) {
2606f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  emitSourceFileHeader("Calling Convention Implementation Fragment", OS);
2616f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  CallingConvEmitter(RK).run(OS);
2626f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}
2636f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
2646f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace
265