diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-04-02 05:23:57 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-04-02 05:23:57 +0000 |
commit | 67073f1cbd95f61a8db01ac479f5e60c0a048ac0 (patch) | |
tree | 959c502ec8fecc71adff7f78e0b50e764d464188 /utils | |
parent | 52b1733df4bb3cafa7a81384da7e81a1fa66cea5 (diff) | |
download | llvm-67073f1cbd95f61a8db01ac479f5e60c0a048ac0.tar.gz llvm-67073f1cbd95f61a8db01ac479f5e60c0a048ac0.tar.bz2 llvm-67073f1cbd95f61a8db01ac479f5e60c0a048ac0.tar.xz |
Add new CC lowering rule: provide a list of registers, which can be 'shadowed',
when some another register is used for argument passing.
Currently is used on Win64.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49079 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/CallingConvEmitter.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/utils/TableGen/CallingConvEmitter.cpp b/utils/TableGen/CallingConvEmitter.cpp index 192bba5ee3..a211b6aecc 100644 --- a/utils/TableGen/CallingConvEmitter.cpp +++ b/utils/TableGen/CallingConvEmitter.cpp @@ -111,6 +111,48 @@ void CallingConvEmitter::EmitAction(Record *Action, << "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"); |