| 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 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 JumpTarget = T64; | 591 JumpTarget = T64; |
| 592 } | 592 } |
| 593 | 593 |
| 594 _jmp(JumpTarget); | 594 _jmp(JumpTarget); |
| 595 } | 595 } |
| 596 | 596 |
| 597 Inst *TargetX8664::emitCallToTarget(Operand *CallTarget, Variable *ReturnReg) { | 597 Inst *TargetX8664::emitCallToTarget(Operand *CallTarget, Variable *ReturnReg) { |
| 598 Inst *NewCall = nullptr; | 598 Inst *NewCall = nullptr; |
| 599 auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget); | 599 auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget); |
| 600 if (NeedSandboxing) { | 600 if (NeedSandboxing) { |
| 601 // In NaCl sandbox, calls are replaced by a push/jmp pair: |
| 602 // |
| 603 // push .after_call |
| 604 // jmp CallTarget |
| 605 // .align bundle_size |
| 606 // after_call: |
| 607 // |
| 608 // In order to emit this sequence, we need a temporary label ("after_call", |
| 609 // in this example.) |
| 610 // |
| 611 // The operand to push is a ConstantRelocatable. The easy way to implement |
| 612 // this sequence is to create a ConstantRelocatable(0, "after_call"), but |
| 613 // this ends up creating more relocations for the linker to resolve. |
| 614 // Therefore, we create a ConstantRelocatable from the name of the function |
| 615 // being compiled (i.e., ConstantRelocatable(after_call - Func, Func). |
| 616 // |
| 617 // By default, ConstantRelocatables are emitted (in textual output) as |
| 618 // |
| 619 // ConstantName + Offset |
| 620 // |
| 621 // ReturnReloc has an offset that is only known during binary emission. |
| 622 // Therefore, we set a custom emit string for ReturnReloc that will be |
| 623 // used instead. In this particular case, the code will be emitted as |
| 624 // |
| 625 // push .after_call |
| 601 InstX86Label *ReturnAddress = InstX86Label::create(Func, this); | 626 InstX86Label *ReturnAddress = InstX86Label::create(Func, this); |
| 602 ReturnAddress->setIsReturnLocation(true); | 627 auto *ReturnRelocOffset = RelocOffset::create(Ctx); |
| 628 ReturnAddress->setRelocOffset(ReturnRelocOffset); |
| 603 constexpr bool SuppressMangling = true; | 629 constexpr bool SuppressMangling = true; |
| 630 const IceString EmitString = ReturnAddress->getName(Func); |
| 631 auto *ReturnReloc = llvm::cast<ConstantRelocatable>(Ctx->getConstantSym( |
| 632 {ReturnRelocOffset}, Ctx->mangleName(Func->getFunctionName()), |
| 633 EmitString, SuppressMangling)); |
| 604 /* AutoBundle scoping */ { | 634 /* AutoBundle scoping */ { |
| 605 std::unique_ptr<AutoBundle> Bundler; | 635 std::unique_ptr<AutoBundle> Bundler; |
| 606 if (CallTargetR == nullptr) { | 636 if (CallTargetR == nullptr) { |
| 607 Bundler = makeUnique<AutoBundle>(this, InstBundleLock::Opt_PadToEnd); | 637 Bundler = makeUnique<AutoBundle>(this, InstBundleLock::Opt_PadToEnd); |
| 608 _push(Ctx->getConstantSym(0, ReturnAddress->getName(Func), | 638 _push(ReturnReloc); |
| 609 SuppressMangling)); | |
| 610 } else { | 639 } else { |
| 611 Variable *T = makeReg(IceType_i32); | 640 Variable *T = makeReg(IceType_i32); |
| 612 Variable *T64 = makeReg(IceType_i64); | 641 Variable *T64 = makeReg(IceType_i64); |
| 613 Variable *r15 = | 642 Variable *r15 = |
| 614 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); | 643 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); |
| 615 | 644 |
| 616 _mov(T, CallTargetR); | 645 _mov(T, CallTargetR); |
| 617 Bundler = makeUnique<AutoBundle>(this, InstBundleLock::Opt_PadToEnd); | 646 Bundler = makeUnique<AutoBundle>(this, InstBundleLock::Opt_PadToEnd); |
| 618 _push(Ctx->getConstantSym(0, ReturnAddress->getName(Func), | 647 _push(ReturnReloc); |
| 619 SuppressMangling)); | |
| 620 const SizeT BundleSize = | 648 const SizeT BundleSize = |
| 621 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); | 649 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); |
| 622 _and(T, Ctx->getConstantInt32(~(BundleSize - 1))); | 650 _and(T, Ctx->getConstantInt32(~(BundleSize - 1))); |
| 623 _movzx(T64, T); | 651 _movzx(T64, T); |
| 624 _add(T64, r15); | 652 _add(T64, r15); |
| 625 CallTarget = T64; | 653 CallTarget = T64; |
| 626 } | 654 } |
| 627 | 655 |
| 628 NewCall = Context.insert<Traits::Insts::Jmp>(CallTarget); | 656 NewCall = Context.insert<Traits::Insts::Jmp>(CallTarget); |
| 629 } | 657 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 #define X(tag, sizeLog2, align, elts, elty, str, rcstr) \ | 806 #define X(tag, sizeLog2, align, elts, elty, str, rcstr) \ |
| 779 static_assert(_table1_##tag == _table2_##tag, \ | 807 static_assert(_table1_##tag == _table2_##tag, \ |
| 780 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); | 808 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); |
| 781 ICETYPE_TABLE | 809 ICETYPE_TABLE |
| 782 #undef X | 810 #undef X |
| 783 } // end of namespace dummy3 | 811 } // end of namespace dummy3 |
| 784 } // end of anonymous namespace | 812 } // end of anonymous namespace |
| 785 | 813 |
| 786 } // end of namespace X8664 | 814 } // end of namespace X8664 |
| 787 } // end of namespace Ice | 815 } // end of namespace Ice |
| OLD | NEW |