Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Side by Side Diff: src/IceTargetLoweringX8664.cpp

Issue 1616483003: Merged addProlog and addEpilog on x86. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 // push 0 208 // push 0
209 // mov %ebp, %(rsp) 209 // mov %ebp, %(rsp)
210 // .bundle_end 210 // .bundle_end
211 // 211 //
212 // to avoid leaking the upper 32-bits (i.e., the sandbox address.) 212 // to avoid leaking the upper 32-bits (i.e., the sandbox address.)
213 AutoBundle _(this); 213 AutoBundle _(this);
214 _push(_0); 214 _push(_0);
215 Context.insert<typename Traits::Insts::Store>(ebp, TopOfStack); 215 Context.insert<typename Traits::Insts::Store>(ebp, TopOfStack);
216 } 216 }
217 217
218 void TargetX8664::_link_bp() {
219 Variable *esp =
220 getPhysicalRegister(Traits::RegisterSet::Reg_esp, IceType_i32);
221 Variable *rsp =
222 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, Traits::WordType);
223 Variable *ebp =
224 getPhysicalRegister(Traits::RegisterSet::Reg_ebp, IceType_i32);
225 Variable *rbp =
226 getPhysicalRegister(Traits::RegisterSet::Reg_rbp, Traits::WordType);
227 Variable *r15 =
228 getPhysicalRegister(Traits::RegisterSet::Reg_r15, Traits::WordType);
229
230 if (!NeedSandboxing) {
231 _push(rbp);
232 _mov(rbp, rsp);
233 } else {
234 _push_rbp();
235
236 AutoBundle _(this);
237 _redefined(Context.insert<InstFakeDef>(ebp, rbp));
238 _redefined(Context.insert<InstFakeDef>(esp, rsp));
239 _mov(ebp, esp);
240 _redefined(Context.insert<InstFakeDef>(rsp, esp));
241 _add(rbp, r15);
242 }
243 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode).
244 Context.insert<InstFakeUse>(rbp);
245 }
246
247 void TargetX8664::_unlink_bp() {
248 Variable *rsp =
249 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64);
250 Variable *rbp =
251 getPhysicalRegister(Traits::RegisterSet::Reg_rbp, IceType_i64);
252 Variable *ebp =
253 getPhysicalRegister(Traits::RegisterSet::Reg_ebp, IceType_i32);
254 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
255 // use of rsp before the assignment of rsp=rbp keeps previous rsp
256 // adjustments from being dead-code eliminated.
257 Context.insert<InstFakeUse>(rsp);
258 if (!NeedSandboxing) {
259 _mov(rsp, rbp);
260 _pop(rbp);
261 } else {
262 _mov_sp(ebp);
263
264 Variable *r15 =
265 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
266 Variable *rcx =
267 getPhysicalRegister(Traits::RegisterSet::Reg_rcx, IceType_i64);
268 Variable *ecx =
269 getPhysicalRegister(Traits::RegisterSet::Reg_ecx, IceType_i32);
270
271 _pop(rcx);
272 Context.insert<InstFakeDef>(ecx, rcx);
273 AutoBundle _(this);
274 _mov(ebp, ecx);
275
276 _redefined(Context.insert<InstFakeDef>(rbp, ebp));
277 _add(rbp, r15);
278 }
279 }
280
281
282 void TargetX8664::_push_reg(Variable *Reg) {
283 Variable *rbp =
284 getPhysicalRegister(Traits::RegisterSet::Reg_rbp, Traits::WordType);
285 if (Reg != rbp || !NeedSandboxing) {
286 _push(Reg);
287 } else {
288 _push_rbp();
289 }
290 }
291
292 void TargetX8664::emitGetIP(CfgNode *Node) {
293 // No IP base register is needed on X86-64.
294 (void)Node;
295 }
296
218 Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) { 297 Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) {
219 // In x86_64-nacl, all memory references are relative to %r15 (i.e., %rzp.) 298 // In x86_64-nacl, all memory references are relative to %r15 (i.e., %rzp.)
220 // NaCl sandboxing also requires that any registers that are not %rsp and 299 // NaCl sandboxing also requires that any registers that are not %rsp and
221 // %rbp to be 'truncated' to 32-bit before memory access. 300 // %rbp to be 'truncated' to 32-bit before memory access.
222 assert(NeedSandboxing); 301 assert(NeedSandboxing);
223 Variable *Base = Mem->getBase(); 302 Variable *Base = Mem->getBase();
224 Variable *Index = Mem->getIndex(); 303 Variable *Index = Mem->getIndex();
225 uint16_t Shift = 0; 304 uint16_t Shift = 0;
226 Variable *r15 = 305 Variable *r15 =
227 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); 306 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 Offset = nullptr; 397 Offset = nullptr;
319 } 398 }
320 399
321 static constexpr bool IsRebased = true; 400 static constexpr bool IsRebased = true;
322 return Traits::X86OperandMem::create( 401 return Traits::X86OperandMem::create(
323 Func, Mem->getType(), r15, Offset, T, Shift, 402 Func, Mem->getType(), r15, Offset, T, Shift,
324 Traits::X86OperandMem::DefaultSegment, IsRebased); 403 Traits::X86OperandMem::DefaultSegment, IsRebased);
325 } 404 }
326 405
327 void TargetX8664::_sub_sp(Operand *Adjustment) { 406 void TargetX8664::_sub_sp(Operand *Adjustment) {
328 Variable *rsp = 407 Variable *rsp = getPhysicalRegister(getStackReg(), Traits::WordType);
John 2016/01/21 15:04:52 why? just curious...
sehr 2016/01/21 16:02:10 I honestly think semantically referring to this as
329 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64);
330 if (!NeedSandboxing) { 408 if (!NeedSandboxing) {
331 _sub(rsp, Adjustment); 409 _sub(rsp, Adjustment);
332 return; 410 return;
333 } 411 }
334 412
335 Variable *esp = 413 Variable *esp =
336 getPhysicalRegister(Traits::RegisterSet::Reg_esp, IceType_i32); 414 getPhysicalRegister(Traits::RegisterSet::Reg_esp, IceType_i32);
337 Variable *r15 = 415 Variable *r15 =
338 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); 416 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
339 417
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 return legalizeToReg(Value, Traits::RegisterSet::Reg_xmm0); 519 return legalizeToReg(Value, Traits::RegisterSet::Reg_xmm0);
442 } else { 520 } else {
443 assert(ReturnType == IceType_i32 || ReturnType == IceType_i64); 521 assert(ReturnType == IceType_i32 || ReturnType == IceType_i64);
444 Variable *Reg = nullptr; 522 Variable *Reg = nullptr;
445 _mov(Reg, Value, 523 _mov(Reg, Value,
446 Traits::getGprForType(ReturnType, Traits::RegisterSet::Reg_rax)); 524 Traits::getGprForType(ReturnType, Traits::RegisterSet::Reg_rax));
447 return Reg; 525 return Reg;
448 } 526 }
449 } 527 }
450 528
451 void TargetX8664::addProlog(CfgNode *Node) { 529 void TargetX8664::emitSandboxedReturn() {
452 // Stack frame layout:
453 //
454 // +------------------------+
455 // | 1. return address |
456 // +------------------------+
457 // | 2. preserved registers |
458 // +------------------------+
459 // | 3. padding |
460 // +------------------------+
461 // | 4. global spill area |
462 // +------------------------+
463 // | 5. padding |
464 // +------------------------+
465 // | 6. local spill area |
466 // +------------------------+
467 // | 7. padding |
468 // +------------------------+
469 // | 8. allocas |
470 // +------------------------+
471 // | 9. padding |
472 // +------------------------+
473 // | 10. out args |
474 // +------------------------+ <--- StackPointer
475 //
476 // The following variables record the size in bytes of the given areas:
477 // * X86_RET_IP_SIZE_BYTES: area 1
478 // * PreservedRegsSizeBytes: area 2
479 // * SpillAreaPaddingBytes: area 3
480 // * GlobalsSize: area 4
481 // * GlobalsAndSubsequentPaddingSize: areas 4 - 5
482 // * LocalsSpillAreaSize: area 6
483 // * SpillAreaSizeBytes: areas 3 - 10
484 // * maxOutArgsSizeBytes(): area 10
485
486 // Determine stack frame offsets for each Variable without a register
487 // assignment. This can be done as one variable per stack slot. Or, do
488 // coalescing by running the register allocator again with an infinite set of
489 // registers (as a side effect, this gives variables a second chance at
490 // physical register assignment).
491 //
492 // A middle ground approach is to leverage sparsity and allocate one block of
493 // space on the frame for globals (variables with multi-block lifetime), and
494 // one block to share for locals (single-block lifetime).
495
496 Context.init(Node);
497 Context.setInsertPoint(Context.getCur());
498
499 llvm::SmallBitVector CalleeSaves =
500 getRegisterSet(RegSet_CalleeSave, RegSet_None);
501 RegsUsed = llvm::SmallBitVector(CalleeSaves.size());
502 VarList SortedSpilledVariables, VariablesLinkedToSpillSlots;
503 size_t GlobalsSize = 0;
504 // If there is a separate locals area, this represents that area. Otherwise
505 // it counts any variable not counted by GlobalsSize.
506 SpillAreaSizeBytes = 0;
507 // If there is a separate locals area, this specifies the alignment for it.
508 uint32_t LocalsSlotsAlignmentBytes = 0;
509 // The entire spill locations area gets aligned to largest natural alignment
510 // of the variables that have a spill slot.
511 uint32_t SpillAreaAlignmentBytes = 0;
512 // A spill slot linked to a variable with a stack slot should reuse that
513 // stack slot.
514 std::function<bool(Variable *)> TargetVarHook =
515 [&VariablesLinkedToSpillSlots](Variable *Var) {
516 if (auto *SpillVar =
517 llvm::dyn_cast<typename Traits::SpillVariable>(Var)) {
518 assert(Var->mustNotHaveReg());
519 if (SpillVar->getLinkedTo() && !SpillVar->getLinkedTo()->hasReg()) {
520 VariablesLinkedToSpillSlots.push_back(Var);
521 return true;
522 }
523 }
524 return false;
525 };
526
527 // Compute the list of spilled variables and bounds for GlobalsSize, etc.
528 getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize,
529 &SpillAreaSizeBytes, &SpillAreaAlignmentBytes,
530 &LocalsSlotsAlignmentBytes, TargetVarHook);
531 uint32_t LocalsSpillAreaSize = SpillAreaSizeBytes;
532 SpillAreaSizeBytes += GlobalsSize;
533
534 // Add push instructions for preserved registers.
535 uint32_t NumCallee = 0;
536 size_t PreservedRegsSizeBytes = 0;
537 llvm::SmallBitVector Pushed(CalleeSaves.size());
538 for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
539 const int32_t Canonical = Traits::getBaseReg(i);
540 assert(Canonical == Traits::getBaseReg(Canonical));
541 if (CalleeSaves[i] && RegsUsed[i])
542 Pushed[Canonical] = true;
543 }
544
545 Variable *rbp =
546 getPhysicalRegister(Traits::RegisterSet::Reg_rbp, IceType_i64);
547 Variable *ebp =
548 getPhysicalRegister(Traits::RegisterSet::Reg_ebp, IceType_i32);
549 Variable *rsp =
550 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64);
551
552 for (SizeT i = 0; i < Pushed.size(); ++i) {
553 if (!Pushed[i])
554 continue;
555 assert(static_cast<int32_t>(i) == Traits::getBaseReg(i));
556 ++NumCallee;
557 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64);
558 Variable *Src = getPhysicalRegister(i, IceType_i64);
559 if (Src != rbp || !NeedSandboxing) {
560 _push(getPhysicalRegister(i, IceType_i64));
561 } else {
562 _push_rbp();
563 }
564 }
565 Ctx->statsUpdateRegistersSaved(NumCallee);
566
567 // Generate "push ebp; mov ebp, esp"
568 if (IsEbpBasedFrame) {
569 assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None))
570 .count() == 0);
571 PreservedRegsSizeBytes += typeWidthInBytes(IceType_i64);
572 Variable *esp =
573 getPhysicalRegister(Traits::RegisterSet::Reg_esp, IceType_i32);
574 Variable *r15 =
575 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
576
577 if (!NeedSandboxing) {
578 _push(rbp);
579 _mov(rbp, rsp);
580 } else {
581 _push_rbp();
582
583 AutoBundle _(this);
584 _redefined(Context.insert<InstFakeDef>(ebp, rbp));
585 _redefined(Context.insert<InstFakeDef>(esp, rsp));
586 _mov(ebp, esp);
587 _redefined(Context.insert<InstFakeDef>(rsp, esp));
588 _add(rbp, r15);
589 }
590 // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode).
591 Context.insert<InstFakeUse>(rbp);
592 }
593
594 // Align the variables area. SpillAreaPaddingBytes is the size of the region
595 // after the preserved registers and before the spill areas.
596 // LocalsSlotsPaddingBytes is the amount of padding between the globals and
597 // locals area if they are separate.
598 assert(SpillAreaAlignmentBytes <= Traits::X86_STACK_ALIGNMENT_BYTES);
599 assert(LocalsSlotsAlignmentBytes <= SpillAreaAlignmentBytes);
600 uint32_t SpillAreaPaddingBytes = 0;
601 uint32_t LocalsSlotsPaddingBytes = 0;
602 alignStackSpillAreas(Traits::X86_RET_IP_SIZE_BYTES + PreservedRegsSizeBytes,
603 SpillAreaAlignmentBytes, GlobalsSize,
604 LocalsSlotsAlignmentBytes, &SpillAreaPaddingBytes,
605 &LocalsSlotsPaddingBytes);
606 SpillAreaSizeBytes += SpillAreaPaddingBytes + LocalsSlotsPaddingBytes;
607 uint32_t GlobalsAndSubsequentPaddingSize =
608 GlobalsSize + LocalsSlotsPaddingBytes;
609
610 // Align esp if necessary.
611 if (NeedsStackAlignment) {
612 uint32_t StackOffset =
613 Traits::X86_RET_IP_SIZE_BYTES + PreservedRegsSizeBytes;
614 uint32_t StackSize =
615 Traits::applyStackAlignment(StackOffset + SpillAreaSizeBytes);
616 StackSize = Traits::applyStackAlignment(StackSize + maxOutArgsSizeBytes());
617 SpillAreaSizeBytes = StackSize - StackOffset;
618 } else {
619 SpillAreaSizeBytes += maxOutArgsSizeBytes();
620 }
621
622 // Combine fixed allocations into SpillAreaSizeBytes if we are emitting the
623 // fixed allocations in the prolog.
624 if (PrologEmitsFixedAllocas)
625 SpillAreaSizeBytes += FixedAllocaSizeBytes;
626 // Generate "sub esp, SpillAreaSizeBytes"
627 if (SpillAreaSizeBytes) {
628 if (NeedSandboxing) {
629 _sub_sp(Ctx->getConstantInt32(SpillAreaSizeBytes));
630 } else {
631 _sub(getPhysicalRegister(getStackReg(), IceType_i64),
632 Ctx->getConstantInt32(SpillAreaSizeBytes));
633 }
634 // If the fixed allocas are aligned more than the stack frame, align the
635 // stack pointer accordingly.
636 if (PrologEmitsFixedAllocas &&
637 FixedAllocaAlignBytes > Traits::X86_STACK_ALIGNMENT_BYTES) {
638 assert(IsEbpBasedFrame);
639 _and(getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64),
640 Ctx->getConstantInt32(-FixedAllocaAlignBytes));
641 }
642 }
643
644 // Account for alloca instructions with known frame offsets.
645 if (!PrologEmitsFixedAllocas)
646 SpillAreaSizeBytes += FixedAllocaSizeBytes;
647
648 Ctx->statsUpdateFrameBytes(SpillAreaSizeBytes);
649
650 // Fill in stack offsets for stack args, and copy args into registers for
651 // those that were register-allocated. Args are pushed right to left, so
652 // Arg[0] is closest to the stack/frame pointer.
653 Variable *FramePtr =
654 getPhysicalRegister(getFrameOrStackReg(), Traits::WordType);
655 size_t BasicFrameOffset =
656 PreservedRegsSizeBytes + Traits::X86_RET_IP_SIZE_BYTES;
657 if (!IsEbpBasedFrame)
658 BasicFrameOffset += SpillAreaSizeBytes;
659
660 const VarList &Args = Func->getArgs();
661 size_t InArgsSizeBytes = 0;
662 unsigned NumXmmArgs = 0;
663 unsigned NumGPRArgs = 0;
664 for (Variable *Arg : Args) {
665 // Skip arguments passed in registers.
666 if (isVectorType(Arg->getType()) || isScalarFloatingType(Arg->getType())) {
667 if (NumXmmArgs < Traits::X86_MAX_XMM_ARGS) {
668 ++NumXmmArgs;
669 continue;
670 }
671 } else {
672 assert(isScalarIntegerType(Arg->getType()));
673 if (NumGPRArgs < Traits::X86_MAX_GPR_ARGS) {
674 ++NumGPRArgs;
675 continue;
676 }
677 }
678 // For esp-based frames, the esp value may not stabilize to its home value
679 // until after all the fixed-size alloca instructions have executed. In
680 // this case, a stack adjustment is needed when accessing in-args in order
681 // to copy them into registers.
682 size_t StackAdjBytes = 0;
683 if (!IsEbpBasedFrame && !PrologEmitsFixedAllocas)
684 StackAdjBytes -= FixedAllocaSizeBytes;
685 finishArgumentLowering(Arg, FramePtr, BasicFrameOffset, StackAdjBytes,
686 InArgsSizeBytes);
687 }
688
689 // Fill in stack offsets for locals.
690 assignVarStackSlots(SortedSpilledVariables, SpillAreaPaddingBytes,
691 SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize,
692 IsEbpBasedFrame);
693 // Assign stack offsets to variables that have been linked to spilled
694 // variables.
695 for (Variable *Var : VariablesLinkedToSpillSlots) {
696 Variable *Linked =
697 (llvm::cast<typename Traits::SpillVariable>(Var))->getLinkedTo();
698 Var->setStackOffset(Linked->getStackOffset());
699 }
700 this->HasComputedFrame = true;
701
702 if (BuildDefs::dump() && Func->isVerbose(IceV_Frame)) {
703 OstreamLocker L(Func->getContext());
704 Ostream &Str = Func->getContext()->getStrDump();
705
706 Str << "Stack layout:\n";
707 uint32_t EspAdjustmentPaddingSize =
708 SpillAreaSizeBytes - LocalsSpillAreaSize -
709 GlobalsAndSubsequentPaddingSize - SpillAreaPaddingBytes -
710 maxOutArgsSizeBytes();
711 Str << " in-args = " << InArgsSizeBytes << " bytes\n"
712 << " return address = " << Traits::X86_RET_IP_SIZE_BYTES << " bytes\n"
713 << " preserved registers = " << PreservedRegsSizeBytes << " bytes\n"
714 << " spill area padding = " << SpillAreaPaddingBytes << " bytes\n"
715 << " globals spill area = " << GlobalsSize << " bytes\n"
716 << " globals-locals spill areas intermediate padding = "
717 << GlobalsAndSubsequentPaddingSize - GlobalsSize << " bytes\n"
718 << " locals spill area = " << LocalsSpillAreaSize << " bytes\n"
719 << " esp alignment padding = " << EspAdjustmentPaddingSize
720 << " bytes\n";
721
722 Str << "Stack details:\n"
723 << " esp adjustment = " << SpillAreaSizeBytes << " bytes\n"
724 << " spill area alignment = " << SpillAreaAlignmentBytes << " bytes\n"
725 << " outgoing args size = " << maxOutArgsSizeBytes() << " bytes\n"
726 << " locals spill area alignment = " << LocalsSlotsAlignmentBytes
727 << " bytes\n"
728 << " is ebp based = " << IsEbpBasedFrame << "\n";
729 }
730 }
731
732 void TargetX8664::addEpilog(CfgNode *Node) {
733 InstList &Insts = Node->getInsts();
734 InstList::reverse_iterator RI, E;
735 for (RI = Insts.rbegin(), E = Insts.rend(); RI != E; ++RI) {
736 if (llvm::isa<typename Traits::Insts::Ret>(*RI))
737 break;
738 }
739 if (RI == E)
740 return;
741
742 // Convert the reverse_iterator position into its corresponding (forward)
743 // iterator position.
744 InstList::iterator InsertPoint = RI.base();
745 --InsertPoint;
746 Context.init(Node);
747 Context.setInsertPoint(InsertPoint);
748
749 Variable *rsp =
750 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64);
751
752 if (!IsEbpBasedFrame) {
753 // add rsp, SpillAreaSizeBytes
754 if (SpillAreaSizeBytes != 0) {
755 _add_sp(Ctx->getConstantInt32(SpillAreaSizeBytes));
756 }
757 } else {
758 Variable *rbp =
759 getPhysicalRegister(Traits::RegisterSet::Reg_rbp, IceType_i64);
760 Variable *ebp =
761 getPhysicalRegister(Traits::RegisterSet::Reg_ebp, IceType_i32);
762 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
763 // use of rsp before the assignment of rsp=rbp keeps previous rsp
764 // adjustments from being dead-code eliminated.
765 Context.insert<InstFakeUse>(rsp);
766 if (!NeedSandboxing) {
767 _mov(rsp, rbp);
768 _pop(rbp);
769 } else {
770 _mov_sp(ebp);
771
772 Variable *r15 =
773 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
774 Variable *rcx =
775 getPhysicalRegister(Traits::RegisterSet::Reg_rcx, IceType_i64);
776 Variable *ecx =
777 getPhysicalRegister(Traits::RegisterSet::Reg_ecx, IceType_i32);
778
779 _pop(rcx);
780 Context.insert<InstFakeDef>(ecx, rcx);
781 AutoBundle _(this);
782 _mov(ebp, ecx);
783
784 _redefined(Context.insert<InstFakeDef>(rbp, ebp));
785 _add(rbp, r15);
786 }
787 }
788
789 // Add pop instructions for preserved registers.
790 llvm::SmallBitVector CalleeSaves =
791 getRegisterSet(RegSet_CalleeSave, RegSet_None);
792 llvm::SmallBitVector Popped(CalleeSaves.size());
793 for (int32_t i = CalleeSaves.size() - 1; i >= 0; --i) {
794 if (i == Traits::RegisterSet::Reg_rbp && IsEbpBasedFrame)
795 continue;
796 const SizeT Canonical = Traits::getBaseReg(i);
797 if (CalleeSaves[i] && RegsUsed[i])
798 Popped[Canonical] = true;
799 }
800 for (int32_t i = Popped.size() - 1; i >= 0; --i) {
801 if (!Popped[i])
802 continue;
803 assert(i == Traits::getBaseReg(i));
804 _pop(getPhysicalRegister(i, IceType_i64));
805 }
806
807 if (!NeedSandboxing) {
808 return;
809 }
810
811 Variable *T_rcx = makeReg(IceType_i64, Traits::RegisterSet::Reg_rcx); 530 Variable *T_rcx = makeReg(IceType_i64, Traits::RegisterSet::Reg_rcx);
812 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx); 531 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx);
813 _pop(T_rcx); 532 _pop(T_rcx);
814 _mov(T_ecx, T_rcx); 533 _mov(T_ecx, T_rcx);
815
816 // lowerIndirectJump(T_ecx); 534 // lowerIndirectJump(T_ecx);
817 Variable *r15 = 535 Variable *r15 =
818 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); 536 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
819 537
820 /* AutoBundle scoping */ { 538 /* AutoBundle scoping */ {
821 AutoBundle _(this); 539 AutoBundle _(this);
822 const SizeT BundleSize = 540 const SizeT BundleSize =
823 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); 541 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes();
824 _and(T_ecx, Ctx->getConstantInt32(~(BundleSize - 1))); 542 _and(T_ecx, Ctx->getConstantInt32(~(BundleSize - 1)));
825 Context.insert<InstFakeDef>(T_rcx, T_ecx); 543 Context.insert<InstFakeDef>(T_rcx, T_ecx);
826 _add(T_rcx, r15); 544 _add(T_rcx, r15);
827 545
828 _jmp(T_rcx); 546 _jmp(T_rcx);
829 } 547 }
830
831 if (RI->getSrcSize()) {
832 auto *RetValue = llvm::cast<Variable>(RI->getSrc(0));
833 Context.insert<InstFakeUse>(RetValue);
834 }
835 RI->setDeleted();
836 } 548 }
837 549
838 void TargetX8664::emitJumpTable(const Cfg *Func, 550 void TargetX8664::emitJumpTable(const Cfg *Func,
839 const InstJumpTable *JumpTable) const { 551 const InstJumpTable *JumpTable) const {
840 if (!BuildDefs::dump()) 552 if (!BuildDefs::dump())
841 return; 553 return;
842 Ostream &Str = Ctx->getStrEmit(); 554 Ostream &Str = Ctx->getStrEmit();
843 IceString MangledName = Ctx->mangleName(Func->getFunctionName()); 555 IceString MangledName = Ctx->mangleName(Func->getFunctionName());
844 Str << "\t.section\t.rodata." << MangledName 556 Str << "\t.section\t.rodata." << MangledName
845 << "$jumptable,\"a\",@progbits\n"; 557 << "$jumptable,\"a\",@progbits\n";
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 #define X(tag, sizeLog2, align, elts, elty, str) \ 858 #define X(tag, sizeLog2, align, elts, elty, str) \
1147 static_assert(_table1_##tag == _table2_##tag, \ 859 static_assert(_table1_##tag == _table2_##tag, \
1148 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); 860 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE");
1149 ICETYPE_TABLE 861 ICETYPE_TABLE
1150 #undef X 862 #undef X
1151 } // end of namespace dummy3 863 } // end of namespace dummy3
1152 } // end of anonymous namespace 864 } // end of anonymous namespace
1153 865
1154 } // end of namespace X8664 866 } // end of namespace X8664
1155 } // end of namespace Ice 867 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698