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 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 // Lowering register arguments after stack arguments may reduce register | 219 // Lowering register arguments after stack arguments may reduce register |
220 // pressure. On the other hand, lowering register arguments first (before | 220 // pressure. On the other hand, lowering register arguments first (before |
221 // stack arguments) may result in more compact code, as the memory operand | 221 // stack arguments) may result in more compact code, as the memory operand |
222 // displacements may end up being smaller before any stack adjustment is | 222 // displacements may end up being smaller before any stack adjustment is |
223 // done. | 223 // done. |
224 for (SizeT i = 0, NumXmmArgs = XmmArgs.size(); i < NumXmmArgs; ++i) { | 224 for (SizeT i = 0, NumXmmArgs = XmmArgs.size(); i < NumXmmArgs; ++i) { |
225 Variable *Reg = legalizeToReg(XmmArgs[i], getRegisterForXmmArgNum(i)); | 225 Variable *Reg = legalizeToReg(XmmArgs[i], getRegisterForXmmArgNum(i)); |
226 // Generate a FakeUse of register arguments so that they do not get dead | 226 // 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 | 227 // code eliminated as a result of the FakeKill of scratch registers after |
228 // the call. | 228 // the call. |
229 Context.insert(InstFakeUse::create(Func, Reg)); | 229 Context.insert<InstFakeUse>(Reg); |
230 } | 230 } |
231 | 231 |
232 for (SizeT i = 0, NumGprArgs = GprArgs.size(); i < NumGprArgs; ++i) { | 232 for (SizeT i = 0, NumGprArgs = GprArgs.size(); i < NumGprArgs; ++i) { |
233 Variable *Reg = legalizeToReg(GprArgs[i], getRegisterForGprArgNum(i)); | 233 Variable *Reg = legalizeToReg(GprArgs[i], getRegisterForGprArgNum(i)); |
234 Context.insert(InstFakeUse::create(Func, Reg)); | 234 Context.insert<InstFakeUse>(Reg); |
235 } | 235 } |
236 | 236 |
237 // Generate the call instruction. Assign its result to a temporary with high | 237 // Generate the call instruction. Assign its result to a temporary with high |
238 // register allocation weight. | 238 // register allocation weight. |
239 Variable *Dest = Instr->getDest(); | 239 Variable *Dest = Instr->getDest(); |
240 // ReturnReg doubles as ReturnRegLo as necessary. | 240 // ReturnReg doubles as ReturnRegLo as necessary. |
241 Variable *ReturnReg = nullptr; | 241 Variable *ReturnReg = nullptr; |
242 if (Dest) { | 242 if (Dest) { |
243 switch (Dest->getType()) { | 243 switch (Dest->getType()) { |
244 case IceType_NUM: | 244 case IceType_NUM: |
(...skipping 19 matching lines...) Expand all Loading... |
264 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0); | 264 ReturnReg = makeReg(Dest->getType(), Traits::RegisterSet::Reg_xmm0); |
265 break; | 265 break; |
266 } | 266 } |
267 } | 267 } |
268 | 268 |
269 Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm); | 269 Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm); |
270 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); | 270 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
271 if (NeedSandboxing) { | 271 if (NeedSandboxing) { |
272 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); | 272 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); |
273 } | 273 } |
274 Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget); | 274 auto *NewCall = Context.insert<Traits::Insts::Call>(ReturnReg, CallTarget); |
275 Context.insert(NewCall); | |
276 if (NeedSandboxing) { | 275 if (NeedSandboxing) { |
277 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); | 276 llvm_unreachable("X86-64 Sandboxing codegen not implemented."); |
278 } | 277 } |
279 | 278 |
280 // Add the appropriate offset to esp. The call instruction takes care of | 279 // Add the appropriate offset to esp. The call instruction takes care of |
281 // resetting the stack offset during emission. | 280 // resetting the stack offset during emission. |
282 if (ParameterAreaSizeBytes) { | 281 if (ParameterAreaSizeBytes) { |
283 Variable *Esp = | 282 Variable *Esp = |
284 Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp); | 283 Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp); |
285 _add(Esp, Ctx->getConstantInt32(ParameterAreaSizeBytes)); | 284 _add(Esp, Ctx->getConstantInt32(ParameterAreaSizeBytes)); |
286 } | 285 } |
287 | 286 |
288 // Insert a register-kill pseudo instruction. | 287 // Insert a register-kill pseudo instruction. |
289 Context.insert(InstFakeKill::create(Func, NewCall)); | 288 Context.insert<InstFakeKill>(NewCall); |
290 | 289 |
291 // Generate a FakeUse to keep the call live if necessary. | 290 // Generate a FakeUse to keep the call live if necessary. |
292 if (Instr->hasSideEffects() && ReturnReg) { | 291 if (Instr->hasSideEffects() && ReturnReg) { |
293 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); | 292 Context.insert<InstFakeUse>(ReturnReg); |
294 Context.insert(FakeUse); | |
295 } | 293 } |
296 | 294 |
297 if (!Dest) | 295 if (!Dest) |
298 return; | 296 return; |
299 | 297 |
300 assert(ReturnReg && "x86-64 always returns value on registers."); | 298 assert(ReturnReg && "x86-64 always returns value on registers."); |
301 | 299 |
302 if (isVectorType(Dest->getType())) { | 300 if (isVectorType(Dest->getType())) { |
303 _movp(Dest, ReturnReg); | 301 _movp(Dest, ReturnReg); |
304 } else { | 302 } else { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 // Replace Arg in the argument list with the home register. Then generate | 347 // Replace Arg in the argument list with the home register. Then generate |
350 // an instruction in the prolog to copy the home register to the assigned | 348 // an instruction in the prolog to copy the home register to the assigned |
351 // location of Arg. | 349 // location of Arg. |
352 if (BuildDefs::dump()) | 350 if (BuildDefs::dump()) |
353 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); | 351 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); |
354 RegisterArg->setRegNum(RegNum); | 352 RegisterArg->setRegNum(RegNum); |
355 RegisterArg->setIsArg(); | 353 RegisterArg->setIsArg(); |
356 Arg->setIsArg(false); | 354 Arg->setIsArg(false); |
357 | 355 |
358 Args[i] = RegisterArg; | 356 Args[i] = RegisterArg; |
359 Context.insert(InstAssign::create(Func, Arg, RegisterArg)); | 357 Context.insert<InstAssign>(Arg, RegisterArg); |
360 } | 358 } |
361 } | 359 } |
362 | 360 |
363 void TargetX8664::lowerRet(const InstRet *Inst) { | 361 void TargetX8664::lowerRet(const InstRet *Inst) { |
364 Variable *Reg = nullptr; | 362 Variable *Reg = nullptr; |
365 if (Inst->hasRetValue()) { | 363 if (Inst->hasRetValue()) { |
366 Operand *Src0 = legalize(Inst->getRetValue()); | 364 Operand *Src0 = legalize(Inst->getRetValue()); |
367 if (isVectorType(Src0->getType()) || | 365 if (isVectorType(Src0->getType()) || |
368 isScalarFloatingType(Src0->getType())) { | 366 isScalarFloatingType(Src0->getType())) { |
369 Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0); | 367 Reg = legalizeToReg(Src0, Traits::RegisterSet::Reg_xmm0); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 // Generate "push ebp; mov ebp, esp" | 477 // Generate "push ebp; mov ebp, esp" |
480 if (IsEbpBasedFrame) { | 478 if (IsEbpBasedFrame) { |
481 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None)) | 479 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None)) |
482 .count() == 0); | 480 .count() == 0); |
483 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64); | 481 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64); |
484 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp); | 482 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp); |
485 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); | 483 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); |
486 _push(ebp); | 484 _push(ebp); |
487 _mov(ebp, esp); | 485 _mov(ebp, esp); |
488 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode). | 486 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode). |
489 Context.insert(InstFakeUse::create(Func, ebp)); | 487 Context.insert<InstFakeUse>(ebp); |
490 } | 488 } |
491 | 489 |
492 // Align the variables area. SpillAreaPaddingBytes is the size of the region | 490 // Align the variables area. SpillAreaPaddingBytes is the size of the region |
493 // after the preserved registers and before the spill areas. | 491 // after the preserved registers and before the spill areas. |
494 // LocalsSlotsPaddingBytes is the amount of padding between the globals and | 492 // LocalsSlotsPaddingBytes is the amount of padding between the globals and |
495 // locals area if they are separate. | 493 // locals area if they are separate. |
496 assert(SpillAreaAlignmentBytes <= Traits::X86_STACK_ALIGNMENT_BYTES); | 494 assert(SpillAreaAlignmentBytes <= Traits::X86_STACK_ALIGNMENT_BYTES); |
497 assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes); | 495 assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes); |
498 uint32_t SpillAreaPaddingBytes = 0; | 496 uint32_t SpillAreaPaddingBytes = 0; |
499 uint32_t LocalsSlotsPaddingBytes = 0; | 497 uint32_t LocalsSlotsPaddingBytes = 0; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 --InsertPoint; | 636 --InsertPoint; |
639 Context.init(Node); | 637 Context.init(Node); |
640 Context.setInsertPoint(InsertPoint); | 638 Context.setInsertPoint(InsertPoint); |
641 | 639 |
642 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); | 640 Variable *esp = getPhysicalRegister(Traits::RegisterSet::Reg_esp); |
643 if (IsEbpBasedFrame) { | 641 if (IsEbpBasedFrame) { |
644 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp); | 642 Variable *ebp = getPhysicalRegister(Traits::RegisterSet::Reg_ebp); |
645 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake | 643 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake |
646 // use of esp before the assignment of esp=ebp keeps previous esp | 644 // use of esp before the assignment of esp=ebp keeps previous esp |
647 // adjustments from being dead-code eliminated. | 645 // adjustments from being dead-code eliminated. |
648 Context.insert(InstFakeUse::create(Func, esp)); | 646 Context.insert<InstFakeUse>(esp); |
649 _mov(esp, ebp); | 647 _mov(esp, ebp); |
650 _pop(ebp); | 648 _pop(ebp); |
651 } else { | 649 } else { |
652 // add esp, SpillAreaSizeBytes | 650 // add esp, SpillAreaSizeBytes |
653 if (SpillAreaSizeBytes) | 651 if (SpillAreaSizeBytes) |
654 _add(esp, Ctx->getConstantInt32(SpillAreaSizeBytes)); | 652 _add(esp, Ctx->getConstantInt32(SpillAreaSizeBytes)); |
655 } | 653 } |
656 | 654 |
657 // Add pop instructions for preserved registers. | 655 // Add pop instructions for preserved registers. |
658 llvm::SmallBitVector CalleeSaves = | 656 llvm::SmallBitVector CalleeSaves = |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 // case the high-level table has extra entries. | 977 // case the high-level table has extra entries. |
980 #define X(tag, sizeLog2, align, elts, elty, str) \ | 978 #define X(tag, sizeLog2, align, elts, elty, str) \ |
981 static_assert(_table1_##tag == _table2_##tag, \ | 979 static_assert(_table1_##tag == _table2_##tag, \ |
982 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); | 980 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); |
983 ICETYPE_TABLE | 981 ICETYPE_TABLE |
984 #undef X | 982 #undef X |
985 } // end of namespace dummy3 | 983 } // end of namespace dummy3 |
986 } // end of anonymous namespace | 984 } // end of anonymous namespace |
987 | 985 |
988 } // end of namespace Ice | 986 } // end of namespace Ice |
OLD | NEW |