OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 lowering -----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 //------------------------------------------------------------------------------ | 111 //------------------------------------------------------------------------------ |
112 namespace { | 112 namespace { |
113 static inline TargetX8664::Traits::RegisterSet::AllRegisters | 113 static inline TargetX8664::Traits::RegisterSet::AllRegisters |
114 getRegisterForXmmArgNum(uint32_t ArgNum) { | 114 getRegisterForXmmArgNum(uint32_t ArgNum) { |
115 assert(ArgNum < TargetX8664::Traits::X86_MAX_XMM_ARGS); | 115 assert(ArgNum < TargetX8664::Traits::X86_MAX_XMM_ARGS); |
116 return static_cast<TargetX8664::Traits::RegisterSet::AllRegisters>( | 116 return static_cast<TargetX8664::Traits::RegisterSet::AllRegisters>( |
117 TargetX8664::Traits::RegisterSet::Reg_xmm0 + ArgNum); | 117 TargetX8664::Traits::RegisterSet::Reg_xmm0 + ArgNum); |
118 } | 118 } |
119 | 119 |
120 static inline TargetX8664::Traits::RegisterSet::AllRegisters | 120 static inline TargetX8664::Traits::RegisterSet::AllRegisters |
121 getRegisterForGprArgNum(uint32_t ArgNum) { | 121 getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) { |
122 assert(ArgNum < TargetX8664::Traits::X86_MAX_GPR_ARGS); | 122 assert(ArgNum < TargetX8664::Traits::X86_MAX_GPR_ARGS); |
123 static const TargetX8664::Traits::RegisterSet::AllRegisters GprForArgNum[] = { | 123 static const TargetX8664::Traits::RegisterSet::AllRegisters GprForArgNum[] = { |
124 TargetX8664::Traits::RegisterSet::Reg_edi, | 124 TargetX8664::Traits::RegisterSet::Reg_rdi, |
125 TargetX8664::Traits::RegisterSet::Reg_esi, | 125 TargetX8664::Traits::RegisterSet::Reg_rsi, |
126 TargetX8664::Traits::RegisterSet::Reg_edx, | 126 TargetX8664::Traits::RegisterSet::Reg_rdx, |
127 TargetX8664::Traits::RegisterSet::Reg_ecx, | 127 TargetX8664::Traits::RegisterSet::Reg_rcx, |
128 TargetX8664::Traits::RegisterSet::Reg_r8d, | 128 TargetX8664::Traits::RegisterSet::Reg_r8, |
129 TargetX8664::Traits::RegisterSet::Reg_r9d, | 129 TargetX8664::Traits::RegisterSet::Reg_r9, |
130 }; | 130 }; |
131 static_assert(llvm::array_lengthof(GprForArgNum) == | 131 static_assert(llvm::array_lengthof(GprForArgNum) == |
132 TargetX8664::TargetX8664::Traits::X86_MAX_GPR_ARGS, | 132 TargetX8664::TargetX8664::Traits::X86_MAX_GPR_ARGS, |
133 "Mismatch between MAX_GPR_ARGS and GprForArgNum."); | 133 "Mismatch between MAX_GPR_ARGS and GprForArgNum."); |
134 return GprForArgNum[ArgNum]; | 134 assert(Ty == IceType_i64 || Ty == IceType_i32); |
| 135 return static_cast<TargetX8664::Traits::RegisterSet::AllRegisters>( |
| 136 TargetX8664::Traits::getGprForType(Ty, GprForArgNum[ArgNum])); |
135 } | 137 } |
136 | 138 |
137 // constexprMax returns a (constexpr) max(S0, S1), and it is used for defining | 139 // constexprMax returns a (constexpr) max(S0, S1), and it is used for defining |
138 // OperandList in lowerCall. std::max() is supposed to work, but it doesn't. | 140 // OperandList in lowerCall. std::max() is supposed to work, but it doesn't. |
139 constexpr SizeT constexprMax(SizeT S0, SizeT S1) { return S0 < S1 ? S1 : S0; } | 141 constexpr SizeT constexprMax(SizeT S0, SizeT S1) { return S0 < S1 ? S1 : S0; } |
140 | 142 |
141 } // end of anonymous namespace | 143 } // end of anonymous namespace |
142 | 144 |
143 void TargetX8664::lowerCall(const InstCall *Instr) { | 145 void TargetX8664::lowerCall(const InstCall *Instr) { |
144 // x86-64 calling convention: | 146 // x86-64 calling convention: |
(...skipping 16 matching lines...) Expand all Loading... |
161 // multiple of 16 bytes. Other stack arguments are aligned to 8 bytes. | 163 // multiple of 16 bytes. Other stack arguments are aligned to 8 bytes. |
162 // | 164 // |
163 // This intends to match the section "Function Calling Sequence" of the | 165 // This intends to match the section "Function Calling Sequence" of the |
164 // document "System V Application Binary Interface." | 166 // document "System V Application Binary Interface." |
165 NeedsStackAlignment = true; | 167 NeedsStackAlignment = true; |
166 | 168 |
167 using OperandList = | 169 using OperandList = |
168 llvm::SmallVector<Operand *, constexprMax(Traits::X86_MAX_XMM_ARGS, | 170 llvm::SmallVector<Operand *, constexprMax(Traits::X86_MAX_XMM_ARGS, |
169 Traits::X86_MAX_GPR_ARGS)>; | 171 Traits::X86_MAX_GPR_ARGS)>; |
170 OperandList XmmArgs; | 172 OperandList XmmArgs; |
171 OperandList GprArgs; | 173 CfgVector<std::pair<const Type, Operand *>> GprArgs; |
172 OperandList StackArgs, StackArgLocations; | 174 OperandList StackArgs, StackArgLocations; |
173 int32_t ParameterAreaSizeBytes = 0; | 175 int32_t ParameterAreaSizeBytes = 0; |
174 | 176 |
175 // Classify each argument operand according to the location where the | 177 // Classify each argument operand according to the location where the |
176 // argument is passed. | 178 // argument is passed. |
177 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { | 179 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { |
178 Operand *Arg = Instr->getArg(i); | 180 Operand *Arg = Instr->getArg(i); |
179 Type Ty = Arg->getType(); | 181 Type Ty = Arg->getType(); |
180 // The PNaCl ABI requires the width of arguments to be at least 32 bits. | 182 // The PNaCl ABI requires the width of arguments to be at least 32 bits. |
181 assert(typeWidthInBytes(Ty) >= 4); | 183 assert(typeWidthInBytes(Ty) >= 4); |
182 if (isVectorType(Ty) && XmmArgs.size() < Traits::X86_MAX_XMM_ARGS) { | 184 if (isVectorType(Ty) && XmmArgs.size() < Traits::X86_MAX_XMM_ARGS) { |
183 XmmArgs.push_back(Arg); | 185 XmmArgs.push_back(Arg); |
184 } else if (isScalarFloatingType(Ty) && | 186 } else if (isScalarFloatingType(Ty) && |
185 XmmArgs.size() < Traits::X86_MAX_XMM_ARGS) { | 187 XmmArgs.size() < Traits::X86_MAX_XMM_ARGS) { |
186 XmmArgs.push_back(Arg); | 188 XmmArgs.push_back(Arg); |
187 } else if (isScalarIntegerType(Ty) && | 189 } else if (isScalarIntegerType(Ty) && |
188 GprArgs.size() < Traits::X86_MAX_GPR_ARGS) { | 190 GprArgs.size() < Traits::X86_MAX_GPR_ARGS) { |
189 GprArgs.push_back(Arg); | 191 GprArgs.emplace_back(Ty, Arg); |
190 } else { | 192 } else { |
191 StackArgs.push_back(Arg); | 193 StackArgs.push_back(Arg); |
192 if (isVectorType(Arg->getType())) { | 194 if (isVectorType(Arg->getType())) { |
193 ParameterAreaSizeBytes = | 195 ParameterAreaSizeBytes = |
194 Traits::applyStackAlignment(ParameterAreaSizeBytes); | 196 Traits::applyStackAlignment(ParameterAreaSizeBytes); |
195 } | 197 } |
196 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_rsp); | 198 Variable *esp = |
| 199 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64); |
197 Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes); | 200 Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes); |
198 StackArgLocations.push_back( | 201 StackArgLocations.push_back( |
199 Traits::X86OperandMem::create(Func, Ty, esp, Loc)); | 202 Traits::X86OperandMem::create(Func, Ty, esp, Loc)); |
200 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Arg->getType()); | 203 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Arg->getType()); |
201 } | 204 } |
202 } | 205 } |
203 | 206 |
204 // Adjust the parameter area so that the stack is aligned. It is assumed that | 207 // Adjust the parameter area so that the stack is aligned. It is assumed that |
205 // the stack is already aligned at the start of the calling sequence. | 208 // the stack is already aligned at the start of the calling sequence. |
206 ParameterAreaSizeBytes = Traits::applyStackAlignment(ParameterAreaSizeBytes); | 209 ParameterAreaSizeBytes = Traits::applyStackAlignment(ParameterAreaSizeBytes); |
(...skipping 16 matching lines...) Expand all Loading... |
223 // done. | 226 // done. |
224 for (SizeT i = 0, NumXmmArgs = XmmArgs.size(); i < NumXmmArgs; ++i) { | 227 for (SizeT i = 0, NumXmmArgs = XmmArgs.size(); i < NumXmmArgs; ++i) { |
225 Variable *Reg = legalizeToReg(XmmArgs[i], getRegisterForXmmArgNum(i)); | 228 Variable *Reg = legalizeToReg(XmmArgs[i], getRegisterForXmmArgNum(i)); |
226 // Generate a FakeUse of register arguments so that they do not get dead | 229 // Generate a FakeUse of register arguments so that they do not get dead |
227 // code eliminated as a result of the FakeKill of scratch registers after | 230 // code eliminated as a result of the FakeKill of scratch registers after |
228 // the call. | 231 // the call. |
229 Context.insert<InstFakeUse>(Reg); | 232 Context.insert<InstFakeUse>(Reg); |
230 } | 233 } |
231 | 234 |
232 for (SizeT i = 0, NumGprArgs = GprArgs.size(); i < NumGprArgs; ++i) { | 235 for (SizeT i = 0, NumGprArgs = GprArgs.size(); i < NumGprArgs; ++i) { |
233 Variable *Reg = legalizeToReg(GprArgs[i], getRegisterForGprArgNum(i)); | 236 const Type SignatureTy = GprArgs[i].first; |
| 237 Operand *Arg = GprArgs[i].second; |
| 238 Variable *Reg = |
| 239 legalizeToReg(Arg, getRegisterForGprArgNum(Arg->getType(), i)); |
| 240 assert(SignatureTy == IceType_i64 || SignatureTy == IceType_i32); |
| 241 if (SignatureTy != Arg->getType()) { |
| 242 if (SignatureTy == IceType_i32) { |
| 243 assert(Arg->getType() == IceType_i64); |
| 244 Variable *T = makeReg( |
| 245 IceType_i32, Traits::getGprForType(IceType_i32, Reg->getRegNum())); |
| 246 _mov(T, Reg); |
| 247 Reg = T; |
| 248 } else { |
| 249 // This branch has never been reached, so we leave the assert(false) |
| 250 // here until we figure out how to exercise it. |
| 251 assert(false); |
| 252 assert(Arg->getType() == IceType_i32); |
| 253 Variable *T = makeReg( |
| 254 IceType_i64, Traits::getGprForType(IceType_i64, Reg->getRegNum())); |
| 255 _movzx(T, Reg); |
| 256 Reg = T; |
| 257 } |
| 258 } |
234 Context.insert<InstFakeUse>(Reg); | 259 Context.insert<InstFakeUse>(Reg); |
235 } | 260 } |
236 | 261 |
237 // Generate the call instruction. Assign its result to a temporary with high | 262 // Generate the call instruction. Assign its result to a temporary with high |
238 // register allocation weight. | 263 // register allocation weight. |
239 Variable *Dest = Instr->getDest(); | 264 Variable *Dest = Instr->getDest(); |
240 // ReturnReg doubles as ReturnRegLo as necessary. | 265 // ReturnReg doubles as ReturnRegLo as necessary. |
241 Variable *ReturnReg = nullptr; | 266 Variable *ReturnReg = nullptr; |
242 if (Dest) { | 267 if (Dest) { |
243 switch (Dest->getType()) { | 268 switch (Dest->getType()) { |
244 case IceType_NUM: | 269 case IceType_NUM: |
245 case IceType_void: | 270 case IceType_void: |
246 llvm::report_fatal_error("Invalid Call dest type"); | 271 llvm::report_fatal_error("Invalid Call dest type"); |
247 break; | 272 break; |
248 case IceType_i1: | 273 case IceType_i1: |
249 case IceType_i8: | 274 case IceType_i8: |
250 case IceType_i16: | 275 case IceType_i16: |
| 276 // The bitcode should never return an i1, i8, or i16. |
| 277 assert(false); |
| 278 // Fallthrough intended. |
251 case IceType_i32: | 279 case IceType_i32: |
| 280 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_eax); |
| 281 break; |
252 case IceType_i64: | 282 case IceType_i64: |
253 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_eax); | 283 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_rax); |
254 break; | 284 break; |
255 case IceType_f32: | 285 case IceType_f32: |
256 case IceType_f64: | 286 case IceType_f64: |
257 case IceType_v4i1: | 287 case IceType_v4i1: |
258 case IceType_v8i1: | 288 case IceType_v8i1: |
259 case IceType_v16i1: | 289 case IceType_v16i1: |
260 case IceType_v16i8: | 290 case IceType_v16i8: |
261 case IceType_v8i16: | 291 case IceType_v8i16: |
262 case IceType_v4i32: | 292 case IceType_v4i32: |
263 case IceType_v4f32: | 293 case IceType_v4f32: |
264 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0); | 294 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0); |
265 break; | 295 break; |
266 } | 296 } |
267 } | 297 } |
268 | 298 |
269 Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm); | 299 Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm); |
| 300 if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) { |
| 301 // x86-64 in Subzero is ILP32. Therefore, CallTarget is i32, but the emitted |
| 302 // call needs a i64 register (for textual asm.) |
| 303 Variable *T = makeReg(IceType_i64); |
| 304 _movzx(T, CallTargetR); |
| 305 CallTarget = T; |
| 306 } |
270 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); | 307 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
271 if (NeedSandboxing) { | 308 if (NeedSandboxing) { |
272 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); | 309 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); |
273 } | 310 } |
274 auto *NewCall = Context.insert<Traits::Insts::Call>(ReturnReg, CallTarget); | 311 auto *NewCall = Context.insert<Traits::Insts::Call>(ReturnReg, CallTarget); |
275 if (NeedSandboxing) { | 312 if (NeedSandboxing) { |
276 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); | 313 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); |
277 } | 314 } |
278 | 315 |
279 // Insert a register-kill pseudo instruction. | 316 // Insert a register-kill pseudo instruction. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 if (NumXmmArgs >= Traits::X86_MAX_XMM_ARGS) { | 360 if (NumXmmArgs >= Traits::X86_MAX_XMM_ARGS) { |
324 continue; | 361 continue; |
325 } | 362 } |
326 RegNum = getRegisterForXmmArgNum(NumXmmArgs); | 363 RegNum = getRegisterForXmmArgNum(NumXmmArgs); |
327 ++NumXmmArgs; | 364 ++NumXmmArgs; |
328 RegisterArg = Func->makeVariable(Ty); | 365 RegisterArg = Func->makeVariable(Ty); |
329 } else if (isScalarIntegerType(Ty)) { | 366 } else if (isScalarIntegerType(Ty)) { |
330 if (NumGprArgs >= Traits::X86_MAX_GPR_ARGS) { | 367 if (NumGprArgs >= Traits::X86_MAX_GPR_ARGS) { |
331 continue; | 368 continue; |
332 } | 369 } |
333 RegNum = getRegisterForGprArgNum(NumGprArgs); | 370 RegNum = getRegisterForGprArgNum(Ty, NumGprArgs); |
334 ++NumGprArgs; | 371 ++NumGprArgs; |
335 RegisterArg = Func->makeVariable(Ty); | 372 RegisterArg = Func->makeVariable(Ty); |
336 } | 373 } |
337 assert(RegNum != Variable::NoRegister); | 374 assert(RegNum != Variable::NoRegister); |
338 assert(RegisterArg != nullptr); | 375 assert(RegisterArg != nullptr); |
339 // Replace Arg in the argument list with the home register. Then generate | 376 // Replace Arg in the argument list with the home register. Then generate |
340 // an instruction in the prolog to copy the home register to the assigned | 377 // an instruction in the prolog to copy the home register to the assigned |
341 // location of Arg. | 378 // location of Arg. |
342 if (BuildDefs::dump()) | 379 if (BuildDefs::dump()) |
343 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); | 380 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); |
344 RegisterArg->setRegNum(RegNum); | 381 RegisterArg->setRegNum(RegNum); |
345 RegisterArg->setIsArg(); | 382 RegisterArg->setIsArg(); |
346 Arg->setIsArg(false); | 383 Arg->setIsArg(false); |
347 | 384 |
348 Args[i] = RegisterArg; | 385 Args[i] = RegisterArg; |
349 Context.insert<InstAssign>(Arg, RegisterArg); | 386 Context.insert<InstAssign>(Arg, RegisterArg); |
350 } | 387 } |
351 } | 388 } |
352 | 389 |
353 void TargetX8664::lowerRet(const InstRet *Inst) { | 390 void TargetX8664::lowerRet(const InstRet *Inst) { |
354 Variable *Reg = nullptr; | 391 Variable *Reg = nullptr; |
355 if (Inst->hasRetValue()) { | 392 if (Inst->hasRetValue()) { |
356 Operand *Src0 = legalize(Inst->getRetValue()); | 393 Operand *Src0 = legalize(Inst->getRetValue()); |
357 if (isVectorType(Src0->getType()) || | 394 if (isVectorType(Src0->getType()) || |
358 isScalarFloatingType(Src0->getType())) { | 395 isScalarFloatingType(Src0->getType())) { |
359 Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0); | 396 Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0); |
360 } else { | 397 } else { |
361 assert(isScalarIntegerType(Src0->getType())); | 398 assert(isScalarIntegerType(Src0->getType())); |
362 _mov(Reg, Src0, Traits::RegisterSet::Reg_eax); | 399 _mov(Reg, Src0, Traits::getGprForType(Src0->getType(), |
| 400 Traits::RegisterSet::Reg_rax)); |
363 } | 401 } |
364 } | 402 } |
365 // Add a ret instruction even if sandboxing is enabled, because addEpilog | 403 // Add a ret instruction even if sandboxing is enabled, because addEpilog |
366 // explicitly looks for a ret instruction as a marker for where to insert the | 404 // explicitly looks for a ret instruction as a marker for where to insert the |
367 // frame removal instructions. | 405 // frame removal instructions. |
368 _ret(Reg); | 406 _ret(Reg); |
369 // Add a fake use of esp to make sure esp stays alive for the entire | 407 // Add a fake use of esp to make sure esp stays alive for the entire |
370 // function. Otherwise post-call esp adjustments get dead-code eliminated. | 408 // function. Otherwise post-call esp adjustments get dead-code eliminated. |
371 keepEspLiveAtExit(); | 409 keepEspLiveAtExit(); |
372 } | 410 } |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64); | 510 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64); |
473 _push(getPhysicalRegister(i, IceType_i64)); | 511 _push(getPhysicalRegister(i, IceType_i64)); |
474 } | 512 } |
475 Ctx->statsUpdateRegistersSaved(NumCallee); | 513 Ctx->statsUpdateRegistersSaved(NumCallee); |
476 | 514 |
477 // Generate "push ebp; mov ebp, esp" | 515 // Generate "push ebp; mov ebp, esp" |
478 if (IsEbpBasedFrame) { | 516 if (IsEbpBasedFrame) { |
479 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None)) | 517 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None)) |
480 .count() == 0); | 518 .count() == 0); |
481 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64); | 519 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64); |
482 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_rbp); | 520 Variable *ebp = |
483 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_rsp); | 521 getPhysicalRegister(Traits::RegisterSet::Reg_rbp, IceType_i64); |
| 522 Variable *esp = |
| 523 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64); |
484 _push(ebp); | 524 _push(ebp); |
485 _mov(ebp, esp); | 525 _mov(ebp, esp); |
486 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode). | 526 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode). |
487 Context.insert<InstFakeUse>(ebp); | 527 Context.insert<InstFakeUse>(ebp); |
488 } | 528 } |
489 | 529 |
490 // Align the variables area. SpillAreaPaddingBytes is the size of the region | 530 // Align the variables area. SpillAreaPaddingBytes is the size of the region |
491 // after the preserved registers and before the spill areas. | 531 // after the preserved registers and before the spill areas. |
492 // LocalsSlotsPaddingBytes is the amount of padding between the globals and | 532 // LocalsSlotsPaddingBytes is the amount of padding between the globals and |
493 // locals area if they are separate. | 533 // locals area if they are separate. |
(...skipping 27 matching lines...) Expand all Loading... |
521 SpillAreaSizeBytes += FixedAllocaSizeBytes; | 561 SpillAreaSizeBytes += FixedAllocaSizeBytes; |
522 // Generate "sub esp, SpillAreaSizeBytes" | 562 // Generate "sub esp, SpillAreaSizeBytes" |
523 if (SpillAreaSizeBytes) { | 563 if (SpillAreaSizeBytes) { |
524 _sub(getPhysicalRegister(getStackReg(), IceType_i64), | 564 _sub(getPhysicalRegister(getStackReg(), IceType_i64), |
525 Ctx->getConstantInt32(SpillAreaSizeBytes)); | 565 Ctx->getConstantInt32(SpillAreaSizeBytes)); |
526 // If the fixed allocas are aligned more than the stack frame, align the | 566 // If the fixed allocas are aligned more than the stack frame, align the |
527 // stack pointer accordingly. | 567 // stack pointer accordingly. |
528 if (PrologEmitsFixedAllocas && | 568 if (PrologEmitsFixedAllocas && |
529 FixedAllocaAlignBytes > Traits::X86_STACK_ALIGNMENT_BYTES) { | 569 FixedAllocaAlignBytes > Traits::X86_STACK_ALIGNMENT_BYTES) { |
530 assert(IsEbpBasedFrame); | 570 assert(IsEbpBasedFrame); |
531 _and(getPhysicalRegister(Traits::RegisterSet::Reg_rsp), | 571 _and(getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64), |
532 Ctx->getConstantInt32(-FixedAllocaAlignBytes)); | 572 Ctx->getConstantInt32(-FixedAllocaAlignBytes)); |
533 } | 573 } |
534 } | 574 } |
535 | 575 |
536 // Account for alloca instructions with known frame offsets. | 576 // Account for alloca instructions with known frame offsets. |
537 if (!PrologEmitsFixedAllocas) | 577 if (!PrologEmitsFixedAllocas) |
538 SpillAreaSizeBytes += FixedAllocaSizeBytes; | 578 SpillAreaSizeBytes += FixedAllocaSizeBytes; |
539 | 579 |
540 Ctx->statsUpdateFrameBytes(SpillAreaSizeBytes); | 580 Ctx->statsUpdateFrameBytes(SpillAreaSizeBytes); |
541 | 581 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 if (RI == E) | 670 if (RI == E) |
631 return; | 671 return; |
632 | 672 |
633 // Convert the reverse_iterator position into its corresponding (forward) | 673 // Convert the reverse_iterator position into its corresponding (forward) |
634 // iterator position. | 674 // iterator position. |
635 InstList::iterator InsertPoint = RI.base(); | 675 InstList::iterator InsertPoint = RI.base(); |
636 --InsertPoint; | 676 --InsertPoint; |
637 Context.init(Node); | 677 Context.init(Node); |
638 Context.setInsertPoint(InsertPoint); | 678 Context.setInsertPoint(InsertPoint); |
639 | 679 |
640 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_rsp); | 680 Variable *esp = |
| 681 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64); |
641 if (IsEbpBasedFrame) { | 682 if (IsEbpBasedFrame) { |
642 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_rbp); | 683 Variable *ebp = |
| 684 getPhysicalRegister(Traits::RegisterSet::Reg_rbp, IceType_i64); |
643 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake | 685 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake |
644 // use of esp before the assignment of esp=ebp keeps previous esp | 686 // use of esp before the assignment of esp=ebp keeps previous esp |
645 // adjustments from being dead-code eliminated. | 687 // adjustments from being dead-code eliminated. |
646 Context.insert<InstFakeUse>(esp); | 688 Context.insert<InstFakeUse>(esp); |
647 _mov(esp, ebp); | 689 _mov(esp, ebp); |
648 _pop(ebp); | 690 _pop(ebp); |
649 } else { | 691 } else { |
650 // add esp, SpillAreaSizeBytes | 692 // add esp, SpillAreaSizeBytes |
651 if (SpillAreaSizeBytes) | 693 if (SpillAreaSizeBytes) |
652 _add(esp, Ctx->getConstantInt32(SpillAreaSizeBytes)); | 694 _add(esp, Ctx->getConstantInt32(SpillAreaSizeBytes)); |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 // case the high-level table has extra entries. | 1025 // case the high-level table has extra entries. |
984 #define X(tag, sizeLog2, align, elts, elty, str) \ | 1026 #define X(tag, sizeLog2, align, elts, elty, str) \ |
985 static_assert(_table1_##tag == _table2_##tag, \ | 1027 static_assert(_table1_##tag == _table2_##tag, \ |
986 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); | 1028 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); |
987 ICETYPE_TABLE | 1029 ICETYPE_TABLE |
988 #undef X | 1030 #undef X |
989 } // end of namespace dummy3 | 1031 } // end of namespace dummy3 |
990 } // end of anonymous namespace | 1032 } // end of anonymous namespace |
991 | 1033 |
992 } // end of namespace Ice | 1034 } // end of namespace Ice |
OLD | NEW |