mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-22 19:49:49 +00:00
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. llvm-svn: 49079
This commit is contained in:
parent
e2690ed8b6
commit
d3330dfbf6
@ -167,7 +167,15 @@ public:
|
||||
MarkAllocated(Reg);
|
||||
return Reg;
|
||||
}
|
||||
|
||||
|
||||
/// Version of AllocateReg with extra register to be shadowed.
|
||||
unsigned AllocateReg(unsigned Reg, unsigned ShadowReg) {
|
||||
if (isAllocated(Reg)) return 0;
|
||||
MarkAllocated(Reg);
|
||||
MarkAllocated(ShadowReg);
|
||||
return Reg;
|
||||
}
|
||||
|
||||
/// AllocateReg - Attempt to allocate one of the specified registers. If none
|
||||
/// are available, return zero. Otherwise, return the first one available,
|
||||
/// marking it and any aliases as allocated.
|
||||
@ -175,13 +183,27 @@ public:
|
||||
unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
|
||||
if (FirstUnalloc == NumRegs)
|
||||
return 0; // Didn't find the reg.
|
||||
|
||||
|
||||
// Mark the register and any aliases as allocated.
|
||||
unsigned Reg = Regs[FirstUnalloc];
|
||||
MarkAllocated(Reg);
|
||||
return Reg;
|
||||
}
|
||||
|
||||
|
||||
/// Version of AllocateReg with list of registers to be shadowed.
|
||||
unsigned AllocateReg(const unsigned *Regs, const unsigned *ShadowRegs,
|
||||
unsigned NumRegs) {
|
||||
unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
|
||||
if (FirstUnalloc == NumRegs)
|
||||
return 0; // Didn't find the reg.
|
||||
|
||||
// Mark the register and any aliases as allocated.
|
||||
unsigned Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc];
|
||||
MarkAllocated(Reg);
|
||||
MarkAllocated(ShadowReg);
|
||||
return Reg;
|
||||
}
|
||||
|
||||
/// AllocateStack - Allocate a chunk of stack space with the specified size
|
||||
/// and alignment.
|
||||
unsigned AllocateStack(unsigned Size, unsigned Align) {
|
||||
|
@ -59,6 +59,14 @@ class CCAssignToReg<list<Register> regList> : CCAction {
|
||||
list<Register> RegList = regList;
|
||||
}
|
||||
|
||||
/// CCAssignToRegWithShadow - Same as CCAssignToReg, but with list of registers
|
||||
/// which became shadowed, when some register is used.
|
||||
class CCAssignToRegWithShadow<list<Register> regList,
|
||||
list<Register> shadowList> : CCAction {
|
||||
list<Register> RegList = regList;
|
||||
list<Register> ShadowRegList = shadowList;
|
||||
}
|
||||
|
||||
/// CCAssignToStack - This action always matches: it assigns the value to a
|
||||
/// stack slot of the specified size and alignment on the stack. If size is
|
||||
/// zero then the ABI size is used; if align is zero then the ABI alignment
|
||||
|
@ -158,22 +158,29 @@ def CC_X86_64_C : CallingConv<[
|
||||
def CC_X86_Win64_C : CallingConv<[
|
||||
// FIXME: Handle byval stuff.
|
||||
// FIXME: Handle fp80.
|
||||
// FIXME: Handle shadowed arguments.
|
||||
// FIXME: Handle nested functions.
|
||||
// FIXME: Handle varargs.
|
||||
|
||||
// Promote i8/i16 arguments to i32.
|
||||
CCIfType<[i8, i16], CCPromoteToType<i32>>,
|
||||
|
||||
// The 'nest' parameter, if any, is passed in R10.
|
||||
CCIfNest<CCAssignToReg<[R10]>>,
|
||||
|
||||
// The first 4 integer arguments are passed in integer registers.
|
||||
CCIfType<[i32], CCAssignToReg<[ECX, EDX, R8D, R9D]>>,
|
||||
CCIfType<[i64], CCAssignToReg<[RCX, RDX, R8 , R9 ]>>,
|
||||
CCIfType<[i32], CCAssignToRegWithShadow<[ECX , EDX , R8D , R9D ],
|
||||
[XMM0, XMM1, XMM2, XMM3]>>,
|
||||
CCIfType<[i64], CCAssignToRegWithShadow<[RCX , RDX , R8 , R9 ],
|
||||
[XMM0, XMM1, XMM2, XMM3]>>,
|
||||
|
||||
// The first 4 FP/Vector arguments are passed in XMM registers.
|
||||
CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
|
||||
CCAssignToReg<[XMM0, XMM1, XMM2, XMM3]>>,
|
||||
CCAssignToRegWithShadow<[XMM0, XMM1, XMM2, XMM3],
|
||||
[RCX , RDX , R8 , R9 ]>>,
|
||||
|
||||
// The first 4 MMX vector arguments are passed in GPRs.
|
||||
CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToReg<[RCX, RDX, R8, R9]>>,
|
||||
CCIfType<[v8i8, v4i16, v2i32, v1i64],
|
||||
CCAssignToRegWithShadow<[RCX , RDX , R8 , R9 ],
|
||||
[XMM0, XMM1, XMM2, XMM3]>>,
|
||||
|
||||
// Integer/FP values get stored in stack slots that are 8 bytes in size and
|
||||
// 16-byte aligned if there are no more registers to hold them.
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user