llvm.org GIT mirror llvm / 67073f1
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 Anton Korobeynikov 12 years ago
4 changed file(s) with 91 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
166166 MarkAllocated(Reg);
167167 return Reg;
168168 }
169
169
170 /// Version of AllocateReg with extra register to be shadowed.
171 unsigned AllocateReg(unsigned Reg, unsigned ShadowReg) {
172 if (isAllocated(Reg)) return 0;
173 MarkAllocated(Reg);
174 MarkAllocated(ShadowReg);
175 return Reg;
176 }
177
170178 /// AllocateReg - Attempt to allocate one of the specified registers. If none
171179 /// are available, return zero. Otherwise, return the first one available,
172180 /// marking it and any aliases as allocated.
174182 unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
175183 if (FirstUnalloc == NumRegs)
176184 return 0; // Didn't find the reg.
177
185
178186 // Mark the register and any aliases as allocated.
179187 unsigned Reg = Regs[FirstUnalloc];
180188 MarkAllocated(Reg);
181189 return Reg;
182190 }
183
191
192 /// Version of AllocateReg with list of registers to be shadowed.
193 unsigned AllocateReg(const unsigned *Regs, const unsigned *ShadowRegs,
194 unsigned NumRegs) {
195 unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
196 if (FirstUnalloc == NumRegs)
197 return 0; // Didn't find the reg.
198
199 // Mark the register and any aliases as allocated.
200 unsigned Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc];
201 MarkAllocated(Reg);
202 MarkAllocated(ShadowReg);
203 return Reg;
204 }
205
184206 /// AllocateStack - Allocate a chunk of stack space with the specified size
185207 /// and alignment.
186208 unsigned AllocateStack(unsigned Size, unsigned Align) {
5858 list RegList = regList;
5959 }
6060
61 /// CCAssignToRegWithShadow - Same as CCAssignToReg, but with list of registers
62 /// which became shadowed, when some register is used.
63 class CCAssignToRegWithShadow regList,
64 list shadowList> : CCAction {
65 list RegList = regList;
66 list ShadowRegList = shadowList;
67 }
68
6169 /// CCAssignToStack - This action always matches: it assigns the value to a
6270 /// stack slot of the specified size and alignment on the stack. If size is
6371 /// zero then the ABI size is used; if align is zero then the ABI alignment
157157 def CC_X86_Win64_C : CallingConv<[
158158 // FIXME: Handle byval stuff.
159159 // FIXME: Handle fp80.
160 // FIXME: Handle shadowed arguments.
161 // FIXME: Handle nested functions.
162
163 // Promote i8/i16 arguments to i32.
164 CCIfType<[i8, i16], CCPromoteToType>,
160 // FIXME: Handle varargs.
161
162 // Promote i8/i16 arguments to i32.
163 CCIfType<[i8, i16], CCPromoteToType>,
164
165 // The 'nest' parameter, if any, is passed in R10.
166 CCIfNest>,
165167
166168 // The first 4 integer arguments are passed in integer registers.
167 CCIfType<[i32], CCAssignToReg<[ECX, EDX, R8D, R9D]>>,
168 CCIfType<[i64], CCAssignToReg<[RCX, RDX, R8 , R9 ]>>,
169 CCIfType<[i32], CCAssignToRegWithShadow<[ECX , EDX , R8D , R9D ],
170 [XMM0, XMM1, XMM2, XMM3]>>,
171 CCIfType<[i64], CCAssignToRegWithShadow<[RCX , RDX , R8 , R9 ],
172 [XMM0, XMM1, XMM2, XMM3]>>,
169173
170174 // The first 4 FP/Vector arguments are passed in XMM registers.
171175 CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
172 CCAssignToReg<[XMM0, XMM1, XMM2, XMM3]>>,
176 CCAssignToRegWithShadow<[XMM0, XMM1, XMM2, XMM3],
177 [RCX , RDX , R8 , R9 ]>>,
173178
174179 // The first 4 MMX vector arguments are passed in GPRs.
175 CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToReg<[RCX, RDX, R8, R9]>>,
180 CCIfType<[v8i8, v4i16, v2i32, v1i64],
181 CCAssignToRegWithShadow<[RCX , RDX , R8 , R9 ],
182 [XMM0, XMM1, XMM2, XMM3]>>,
176183
177184 // Integer/FP values get stored in stack slots that are 8 bytes in size and
178185 // 16-byte aligned if there are no more registers to hold them.
110110 << "Reg, LocVT, LocInfo));\n";
111111 O << IndentStr << " return false;\n";
112112 O << IndentStr << "}\n";
113 } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) {
114 ListInit *RegList = Action->getValueAsListInit("RegList");
115 ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
116 if (ShadowRegList->getSize() >0 &&
117 ShadowRegList->getSize() != RegList->getSize())
118 throw "Invalid length of list of shadowed registers";
119
120 if (RegList->getSize() == 1) {
121 O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
122 O << getQualifiedName(RegList->getElementAsRecord(0));
123 O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0));
124 O << ")) {\n";
125 } else {
126 unsigned RegListNumber = ++Counter;
127 unsigned ShadowRegListNumber = ++Counter;
128
129 O << IndentStr << "static const unsigned RegList" << RegListNumber
130 << "[] = {\n";
131 O << IndentStr << " ";
132 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
133 if (i != 0) O << ", ";
134 O << getQualifiedName(RegList->getElementAsRecord(i));
135 }
136 O << "\n" << IndentStr << "};\n";
137
138 O << IndentStr << "static const unsigned RegList"
139 << ShadowRegListNumber << "[] = {\n";
140 O << IndentStr << " ";
141 for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) {
142 if (i != 0) O << ", ";
143 O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
144 }
145 O << "\n" << IndentStr << "};\n";
146
147 O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
148 << RegListNumber << ", " << "RegList" << ShadowRegListNumber
149 << ", " << RegList->getSize() << ")) {\n";
150 }
151 O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
152 << "Reg, LocVT, LocInfo));\n";
153 O << IndentStr << " return false;\n";
154 O << IndentStr << "}\n";
113155 } else if (Action->isSubClassOf("CCAssignToStack")) {
114156 int Size = Action->getValueAsInt("Size");
115157 int Align = Action->getValueAsInt("Align");